I'm working on a survival analysis project where it would be useful to visualize everyone's followup time and event times. The data is made up of an ID, which of two possible events they had (A or B), and the time at which they had the event as well as whether or not they are interval censored. Non-censored individuals have two identical event times, t1 and t2, while censored individuals have t1 =/= t2, giving the lower and upper bound of their censored time.
This looks like so (all made up):
ID, eventA, eventB, t1, t2, censored
1, 0, 1, 7, 7, 0
2, 1, 0, 5, 5, 0
3, 1, 0, 10, 10, 0
4, 0, 1, 4.5, 4.5, 0
5, 1, 0, 2, 8, 1
Where ID 5 is censored.
I'd like to produce a plot like this:
Essentially, make the X-axis ID, the Y axis time. Draw a line segment from 0 to t1. Then if they're censored, draw another line segment from t1 to t2. Presumably if they're uncensored they'll just overlap, which is fine. Then drop a marker at t2 for each type of event, say an X if they're eventA and O if they're eventB.
I presume there's a way to do this in R, but I haven't yet really wrapped my mind around graphing in R, and most of the examples for graphs in survival analysis I'm finding are KM curves. Anyone have an idea?
Best Answer
There must be many ways to make follow-up time plots with interval censored data, although a quick Google search only found this image in an overview of censoring, which looks a bit busy to my eye.
Just to give another perspective, here's an approach using the ggplot2 package.
And the result:
When making graphs with line-type, color, size, etc. conditional on data, I find ggplot2 more intuitive than base graphics and even trellis, although trellis is much faster when plotting bigger data.
I'm not sure if it is preferred to place the event marker in the middle of the censored interval or at the end. I chose the middle here, to emphasize that the event did not necessarily occur near the end of follow-up.
Addendum
Once you decide on a standard plot, and if you find yourself making these plots often, it can be convenient to wrap it up in a function and use R's S3 object system to dispatch the plotting method with a call to the
plot()
generic. The following does not relate directly to the original question, but for the sake of other readers interested in adding methods to theplot()
generic I'll include it here. First, wrap up the ggplot call into a plot method function:Then, add
internal.censored
to the class of your data object:Now, the plot can be produced simply by calling:
You can either put
plot.interval.censored()
into a package, or add it to your .Rprofile, in which case it will always be available to you when you start R on your machine. Publishing a package might be preferred, as it is easier to share with others or install when you are not on your own machine. However, editing .Rprofile might be simpler. Hadley has a great overview of the S3 object system.