reReg icon indicating copy to clipboard operation
reReg copied to clipboard

How to add IDs into the bars of the `plotEvents()`

Open mafed opened this issue 9 months ago • 2 comments

First of all, thanks for the {reReg} and the {reda} packages, very helpful in my case.

My request is: how could I annotate the bars of the plotEvents() with the IDs from the data?
I know this would be sensible only when there are a few subjects but having this feature would open up individual bar annotation which might be useful per se.

Cheers

mafed avatar Jul 22 '25 09:07 mafed

This is what I mean:

data(readmission, package = "frailtypack")
readmission <- subset(readmission, !(id %in% c(60, 109, 280)))

## selecting a small subset
readmission_subset <- subset(readmission, id %in% 1L:20)
p <- plotEvents(Recur(t.stop, id, event, death) ~ chemo, 
                data = readmission_subset)

## better labelling strips
labels <- c("chemo = Treated" = "Yes",
            "chemo = NonTreated" = "No")
p <-
  p + 
  facet_grid(chemo ~., scales = "free", space = "free", switch = "both",
               labeller = labeller(chemo = labels)) +
  xlab("Received chemo?")

## now how to add 'id's within the bars? 
## Even with a single string the placing is wrong as it adds 'phantom rows'
p +
  annotate("text", x = p$data$id, y = 0,
           label = "ID", size = 3, color = "black")
## trying this gives the following error
p +
  annotate("text", x = p$data$id, y = 0,
           label = p$data$id, size = 3, color = "black")

Error in `annotate()`:
! Problem while setting up geom aesthetics.
ℹ Error occurred in the 4th layer.
Caused by error in `check_aesthetics()` at ggplot2/R/geom-.R:178:5:
! Aesthetics must be either length 1 or the same as the data (40).
✖ Fix the following mappings: `label`.
Run `rlang::last_trace()` to see where the error occurred.

mafed avatar Jul 22 '25 09:07 mafed

Thank you for the interesting question. Is the following what you are looking for?

## selecting a small subset
readmission_subset <- subset(readmission, id %in% 1L:20)
p <- plotEvents(Recur(t.stop, id, event, death) ~ chemo, 
                data = readmission_subset)
## better labelling strips
labels <- c("chemo = Treated" = "Yes",
            "chemo = NonTreated" = "No")
p <- p + 
  facet_grid(chemo ~., scales = "free", space = "free", switch = "both",
             labeller = labeller(chemo = labels)) +
  xlab("Received chemo?")

## Adding id and adjusting space
p + geom_text(aes(y = 0, label = paste0("id ", 1:20)), hjust = 1.2) +
  scale_y_continuous(expand = expansion(mult = c(0.12, 0)))

Rplot.pdf

After applying facet_grid() to change the label layout, I used geom_text() to add the ID labels and scale_y_continuous() to create extra space for displaying them properly. Here are a few considerations I took into account:

  • geom_text() seems to work better when using facet_grid()
  • For the label in geom_text(), I set the ID values from 1 to 20 to match the IDs in the readmission_subset. Internally, p$data$id changes depending on the result argument when plotEvents() is called. In this case, it reflects the rank (or order) of individuals based on the length of their terminal event time within each group. I think this also explains why there was one extra row in the annotate() version of the code?
  • The expand in scale_y_continous() pushes the facet strip to the left.

I hope this is what you need. Let me know if you have more questions!

stc04003 avatar Jul 23 '25 23:07 stc04003