4

I would like to have the shading of the confidence intervals for the survival estimates. Now I have black lines.

library(survival)
library(ggplot2)
library(GGally)
data(lung) 
sf.sex <- survfit(Surv(time, status) ~ sex, data = lung) 
pl.sex <- ggsurv(sf.sex, CI = TRUE) 
pl.sex

enter image description here

FTF
  • 181
  • 3
  • 11

2 Answers2

8

Here is an easy, almost-right solution:

pl.sex <- ggsurv(sf.sex, CI = FALSE) +
  geom_ribbon(aes(ymin=low,ymax=up,fill=group),alpha=0.3)

Set CI = FALSE to get rid of the dashed-line CI bands then add geom_ribbon() to get the confidence bands you want.

enter image description here

This is only mostly right, though, since we want the confidence bands to use the step function as well. To get exactly what we want, we can use some code from this link to create a new stat for geom_ribbon called "stepribbon" as follows:

library(proto)

stairstepn <- function( data, direction="hv", yvars="y" ) {
  direction <- match.arg( direction, c( "hv", "vh" ) )
  data <- as.data.frame( data )[ order( data$x ), ]
  n <- nrow( data )

  if ( direction == "vh" ) {
    xs <- rep( 1:n, each = 2 )[ -2 * n ]
    ys <- c( 1, rep( 2:n, each = 2 ) )
  } else {
    ys <- rep( 1:n, each = 2 )[ -2 * n ]
    xs <- c( 1, rep( 2:n, each = 2))
  }

  data.frame(
    x = data$x[ xs ]
    , data[ ys, yvars, drop=FALSE ]
    , data[ xs, setdiff( names( data ), c( "x", yvars ) ), drop=FALSE ]
  )
}

stat_stepribbon <- function( mapping=NULL, data=NULL, geom="ribbon", position="identity" ) {
  StatStepribbon$new( mapping=mapping, data=data, geom=geom, position=position )
}

StatStepribbon <- proto(ggplot2:::Stat, {
  objname <- "stepribbon"
  desc <- "Stepwise area plot"
  desc_outputs <- list(
    x = "stepped independent variable",
    ymin = "stepped minimum dependent variable",
    ymax = "stepped maximum dependent variable"
  )
  required_aes <- c( "x", "ymin", "ymax" )

  default_geom <- function(.) GeomRibbon
  default_aes <- function(.) aes( x=..x.., ymin = ..y.., ymax=Inf )

  calculate <- function( ., data, scales, direction = "hv", yvars = c( "ymin", "ymax" ), ...) {
    stairstepn( data = data, direction = direction, yvars = yvars )
  }

  examples <- function(.) {
    DF <- data.frame( x = 1:3, ymin = runif( 3 ), ymax=rep( Inf, 3 ) )
    ggplot( DF, aes( x=x, ymin=ymin, ymax=ymax ) ) + stat_stepribbon()
  }

})

With that new stat you can get the solution I think you were really looking for:

pl.sex <- ggsurv(sf.sex, CI = FALSE) +
  geom_ribbon(aes(ymin=low,ymax=up,fill=group),stat="stepribbon",alpha=0.3) +
  guides(fill=guide_legend("sex"))

enter image description here

Sam Dickson
  • 5,082
  • 1
  • 27
  • 45
  • Thanks @SamDickson, but now there are two legends -- one for the line and one for the ribbon. How can I correct that? – FTF Nov 23 '15 at 17:23
  • Combining the legends is as simple as making sure they have the same name. The answer has been updated to show you one way to do this. A slightly shorter is to use `+labs(fill="sex")`. – Sam Dickson Nov 23 '15 at 17:24
3

I found a better solution. You just use the Rcmdrplugin KMggplot2 which also has the optional features of adding the median line and number at risk table.

enter image description here

FTF
  • 181
  • 3
  • 11