kassambara / survminer

Survival Analysis and Visualization
https://rpkgs.datanovia.com/survminer/
504 stars 162 forks source link

Survminer & ggsurvplot with multiple surv objects #98

Closed kassambara closed 7 years ago

kassambara commented 7 years ago

(email from a survminer user)

Hi there,

I had a question about using ggsurvplot, but wasn't sure to list it as an issue on Github, as the "issue" here probably is on my end...

Basically, I want to try to put two survfit objects in one ggsurvplot that divide strata in different ways. E.g. a plot with survival by sex (2 curves, F vs. M) and a single combined curve of the two.

I can get the plots independently, like so:

library(ggplot2) library(survival) library(survminer)

mini test dataframe

death=c(1,1,1,1,0,1) day=c(1,5,6,2,2,7) sex=c(rep("f",3), rep("m", 3))

df<-data.frame(sex, day, death) #

fit_sex=survfit(Surv(day, death) ~ sex, df) # 2 curves, one per sex fit_all=survfit(Surv(day, death) ~ 1, df) # 1 curve, everybody together

plot_sex=ggsurvplot(fit_sex) plot_all=ggsurvplot(fit_all)

How to put all three curves on one graph? Using "lines()" as I would after "plot()" doesn't work. I've also tried something like this after making the plot: plot_sex$plot <- plot_sex$plot + line(summary(fit_all)$time, summary(fit_all)$surv) #an attempt to pull the x and y from summary(fit_all) and just stick it on plot_sex as a line

Preferably, I would like to avoid adding a "new sex" into my data frame with duplicate data from both f/m. I will be gradually adding to this data set overtime, and would generally like to keep it simple and clean in there. And, I might want to compare and combine various things with my real data (sex/treatment type/treatment time/experiment date etc.), making up a new addition to my dataframe each time doesn't seem optimal.

[I also have a problem with my risk table others have reported also where day 0 has the same (and incorrect) value for all strata - I didn't see a resolution to the problem, just questions. Know about how to solve this one to?]

Thanks for reading this email from a stumped stranger, and let me know if you need any clarification!

Best, Ian

kassambara commented 7 years ago

Hi,

The survminer package uses ggplot2 plotting system. So, you should ggplot2 functions - geom_line() or geom_step() - to add line instead of the R base function line()

To put the 3 curves together, try this:

# Fit survival curves
#%%%%%%%%%%%%%%%%%%%%%%%
library(survival)
fit_sex <- survfit(Surv(time, status) ~ sex, data = lung)
fit_all <- survfit(Surv(time, status) ~ 1, data = lung)

# Visualize
#%%%%%%%%%%%%%%%%%%%%%%
library(survminer)
plot_sex <- ggsurvplot(fit_sex)

sum_all <- surv_summary(fit_all)
plot_sex$plot+geom_step(data = sum_all,
                        mapping = aes(x = time, y = surv),
                        color = "black")

rplot

Concerning the risk.table, make sure that you have the lattest version of survival and survminer packages.

Let us know if it works, so that we can close this issue.

Best, A. Kassambara

igwill commented 7 years ago

Thanks for the fast reply, after updating R and my packages, this worked like a charm.

I wanted also to add the 95%CI for the curve plotted by geom_step(sum_all...), I tried to use geom_ribbon() but it is a spiky mess. For the sex=1/2 curves, simply using conf.int=T in ggsurvplot() works fine, but how to best put the CI on the added "all" line?

kassambara commented 7 years ago

I'm happy that it works..

For the confidence band, you can use the hidden function .geom_confint() availble in survminer. As this function is hidden, you should always use it as follow: survminer:::.geom_confint().

The final R script looks like this:

# Fit survival curves
#%%%%%%%%%%%%%%%%%%%%%%%
library(survival)
fit_sex <- survfit(Surv(time, status) ~ sex, data = lung)
fit_all <- survfit(Surv(time, status) ~ 1, data = lung)

# Visualize
#%%%%%%%%%%%%%%%%%%%%%%
library(survminer)
plot_sex <- ggsurvplot(fit_sex)

sum_all <- surv_summary(fit_all)
plot_sex$plot+geom_step(data = sum_all,
                        mapping = aes(x = time, y = surv),
                        color = "black")+
  survminer:::.geom_confint(data = sum_all,
                            mapping = aes(ymin = lower, ymax = upper),
                            fill = "black", alpha = 0.3)

rplot

Best, /A

igwill commented 7 years ago

Perfect, thanks again. I will be happily plotting from here.

kassambara commented 7 years ago

so we can close this issue. Have a great day!!

kassambara commented 7 years ago

A simple solution is now available at https://github.com/kassambara/survminer/issues/194

igwill commented 7 years ago

Very cool, thanks for thinking to update me after all this time!

On Fri, Apr 28, 2017 at 11:18 AM, Alboukadel KASSAMBARA < notifications@github.com> wrote:

A simple solution is now available at #194 https://github.com/kassambara/survminer/issues/194

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kassambara/survminer/issues/98#issuecomment-297950581, or mute the thread https://github.com/notifications/unsubscribe-auth/AXc_HkWJztX9vdac_JtUJ-KDHicjThDTks5r0a7ogaJpZM4LOd8B .

thirupathipattipaka commented 7 years ago

@kassambara: is it possible to add risk table for all lines

thirupathipattipaka commented 7 years ago

@kassambara, I have four different survival curves which came from four different fits, I wanted overlay all and add risk tables.

kassambara commented 7 years ago

Hi @thirupathipattipaka ,

A solution is provided at https://github.com/kassambara/survminer/issues/195