Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I add shading and color to the confidence intervals in ggplot 2 generated Kaplan-Meier plot? [duplicate]

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

like image 605
FTF Avatar asked Dec 19 '22 22:12

FTF


1 Answers

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

like image 158
Sam Dickson Avatar answered Apr 30 '23 19:04

Sam Dickson