2

I'm trying to plot an adjusted survival curve, but struggling with changing the line types by group. I'm able to customise other aspects of the plot using typical ggplot2 language, but I've hit a wall with changing line type.

Example:

library(survival)
library(survminer)

fit2 <- coxph( Surv(stop, event) ~ size + strata(rx), data = bladder )

ggadjustedcurves(fit2,
                 variable = "rx", 
                 data = bladder,
                 method = "average",
                 palette = c("#E69F00", "#56B4E9"),
                 size = 1.3,
                 legend = "right",
                 legend.title = expression(bold("Legend title")),
                 xlab = "Time",
                 font.legend = 12) +
  theme(legend.text.align = 0.5)

I've tried adding in:

geom_line( aes( linetype = c(1, 2) )
add.params = list(linetype = c(1, 2))

and just

linetype = c(1, 2)

but nothing seems to work.

IRTFM
  • 258,963
  • 21
  • 364
  • 487
T.P.
  • 87
  • 1
  • 6

1 Answers1

1

First you need to look at the code.

ggadjustedcurves

It appears that ggadjustedcurves passes all it arguments on to helper functions that depend on the "method" argument, in this case "average", so now look at that (hidden) function:

 getAnywhere( ggadjustedcurves.average )

And note that there is no provision to accept additional arguments beyond the few that are defined in the "master function", i.e. no use of R's ellipsis mechanism or specifications of other possible aes-arguments besides size. (It's also not using geom_line.) So you need to change both the master function and the helper function to accept a "linetype" argument. Here I show how to modify the helper function (although this needs to be done to the ggadjustedcurves function as well and maybe the rest of the helper functions if you want this to be completely general):

assignInNamespace('ggadjustedcurves.average',  

  function (data, fit, variable, size = 1, ..., linetype=linetype) 
    {
    time <- surv <- NULL
    lev <- sort(unique(data[, variable]))
    pred <- survexp(as.formula(paste("~", variable)), data = data, 
                    ratetable = fit)
    curve <- data.frame(time = rep(c(0, pred$time), length(lev)), 
                        variable = factor(rep(lev, each = 1 + length(pred$time))), 
                        surv = c(rbind(1, pred$surv)))
    ggplot(curve, aes(x = time, y = surv, color = variable)) + 
        geom_step(size = size, ..., linetype=linetype)  # not geom_line
    }, 
   pos="package:survminer")

enter image description here

If you do an SO search on "geom_segment linetype" you find that geom_segment (which is what geon_step uses) is not constructed in a manner that makes it easy to give it short vectors to modify "contiguous" lengths of step function results. See ggplot error using linetype and group aesthetics . This means you would need to use a for-loop or lapply to build separate "step-curves" if you need different line types.

IRTFM
  • 258,963
  • 21
  • 364
  • 487
  • Is there any way to add patients at risk below the plots? [link](https://stackoverflow.com/questions/65158418/add-patients-at-risk-to-adjusted-survival-curves-in-ggplot2-in-r) – Mohamed Rahouma Dec 05 '20 at 19:39
  • This doesn't appear to be related to the primary question. If you've done a search on the topic, then why not try composing reproducible example and then also review the nominated prior questions. If none of them answer your question then hit "Submit". – IRTFM Dec 06 '20 at 02:31
  • thanks for your answer. I composed 2 separate questions in 2 different coding manners [link](https://stackoverflow.com/questions/65153421/add-at-risk-table-and-95-confidence-intervals-to-adjusted-survival-curves-using) and here [link](https://stackoverflow.com/questions/65158418/add-patients-at-risk-to-adjusted-survival-curves-in-ggplot2-in-r) but I did not get an answer so I added a comment here if you could help. Upvoted your current answer. Appreciate any advice – Mohamed Rahouma Dec 06 '20 at 12:53
  • Searching on "survminer risk table" which I suggested. brings up 20 hits. – IRTFM Dec 06 '20 at 21:44