Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: Extend confidence bands added via add_confidence_interval() #214

Closed
slobaugh opened this issue May 21, 2024 · 4 comments
Closed

Comments

@slobaugh
Copy link

Is your feature request related to a problem? Please describe.
Confidence bands drawn in a KM curve created using ggsurvfit + add_confidence_interval() do not necessarily appear for all of the times for which they are defined.

Describe the solution you'd like
Sometimes I provide KM survival estimates for a time-point past where the confidence bands end in the associated plot created using ggsurvfit, and it would be nice if the plot aligned with the estimates for consistency. I would like for the confidence bands to appear in the plot for all of the times for which they are defined.

Describe alternatives you've considered
I could use survminer::ggsurvplot instead. My reprex below compares the behavior of this function with ggsurvfit.

Additional context
Reprex:

# load packages
library(reprex)
library(tidyverse)
library(ggsurvfit)
library(survival)
library(survminer)
#> Loading required package: ggpubr
#> 
#> Attaching package: 'survminer'
#> The following object is masked from 'package:survival':
#> 
#>     myeloma
library(gridExtra)
#> 
#> Attaching package: 'gridExtra'
#> The following object is masked from 'package:dplyr':
#> 
#>     combine
# create data
df_fake <- tibble::tribble(
                ~time, ~status,
     24.0164271047228,       1,
     24.1478439425051,       1,
     24.3121149897331,       0,
     25.1334702258727,       1,
     25.9876796714579,       1,
     26.4804928131417,       0,
     26.7433264887064,       1,
     26.9733059548255,       0,
     27.5975359342916,       0,
     29.0102669404517,       1,
     31.7043121149897,       0,
     33.1827515400411,       0,
     33.5770020533881,       0,
     58.5770020533881,       0,
     63.5770020533881,       1
     ) 

# create kaplan-meier curve using ggsurvfit
# expect this code to create a plot with a CI band that extends up until just before the final event
# reality: the CI band ends at the final censored patient.
x <- survfit2(Surv(time, status) ~ 1, data = df_fake) %>%
  ggsurvfit() +
  add_confidence_interval() +
  add_censor_mark() +
  labs(title = "ggsurvfit plot: \n CI band ends way before \n final event") +
  coord_cartesian(xlim = c(0, 72))

# create kaplan-meier curve using survminer::ggsurvplot
# expect this code to create a plot with a CI band that extends up until just before the final event
# reality: matches expectation
km <- survfit2(Surv(time, status) ~ 1, data = df_fake)
y <- ggsurvplot(
  fit = km,
  data = df_fake, 
  conf.int = TRUE,
  palette = "black",
  xlim = c(0, 72),
  break.x.by = 20,
  legend = "none",
  title = "survminer::ggsurvplot plot: \n CI band goes up to just \n before final event"
)

# display side-by-side to visualize the difference in CI bands between the two plots
gridExtra::grid.arrange(ggsurvfit_build(x),
                        y$plot,
                        ncol = 2)

Created on 2024-05-21 with reprex v2.1.0

@ddsjoberg
Copy link
Collaborator

Hi @slobaugh !

I think we spoke about this request a few years ago, right? The ggsurvfit behavior mimics what is done in the survival package. That said, I am not against the change. But I probably wouldn't put the effort into making the change myself.

I think this would require an update to the geom_step_ribbon() function. Let me know if it's something you'd like to pursue.

library(ggsurvfit)
#> Loading required package: ggplot2
# create data
df_fake <- tibble::tribble(
  ~time, ~status,
  24.0164271047228,       1,
  24.1478439425051,       1,
  24.3121149897331,       0,
  25.1334702258727,       1,
  25.9876796714579,       1,
  26.4804928131417,       0,
  26.7433264887064,       1,
  26.9733059548255,       0,
  27.5975359342916,       0,
  29.0102669404517,       1,
  31.7043121149897,       0,
  33.1827515400411,       0,
  33.5770020533881,       0,
  58.5770020533881,       0,
  63.5770020533881,       1
) 

survfit(Surv(time, status) ~ 1, data = df_fake) |> plot()

Created on 2024-05-21 with reprex v2.1.0

@ddsjoberg
Copy link
Collaborator

@slobaugh is this something you're interested in doing? 💯

@slobaugh
Copy link
Author

slobaugh commented Jun 3, 2024

Thanks @ddsjoberg, we did chat briefly about this in person a while ago! I feel similarly to you in that I probably won't put the effort into making the change myself 🙈 but I really appreciate the reminder that ggsurvfit is mimicking the survival package's behavior here. Please close this issue as you see fit!

@ddsjoberg
Copy link
Collaborator

OK, I'll go ahead and close. If you ever feel the motivation to make it happen, re-open the issue :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants