3
votes

I would like to fit a weibull curve to some event data and then include the fitted weibull curve in a survival plot plotted by survminer::ggsurvplot. Any ideas of how? Here is an example to work on:

A function for simulating weibull data:

# N = sample size    
# lambda = scale parameter in h0()
# rho = shape parameter in h0()
# beta = fixed effect parameter
# rateC = rate parameter of the exponential distribution of C

simulWeib <- function(N, lambda, rho, beta, rateC)
{
  # covariate --> N Bernoulli trials
  x <- sample(x=c(0, 1), size=N, replace=TRUE, prob=c(0.5, 0.5))

  # Weibull latent event times
  v <- runif(n=N)
  Tlat <- (- log(v) / (lambda * exp(x * beta)))^(1 / rho)

  # censoring times
  C <- rexp(n=N, rate=rateC)

  # follow-up times and event indicators
  time <- pmin(Tlat, C)
  status <- as.numeric(Tlat <= C)

  # data set
  data.frame(id=1:N,
             time=time,
             status=status,
             x=x)
}

generate data

set.seed(1234)
betaHat <- rep(NA, 1e3)
for(k in 1:1e3)
{
  dat <- simulWeib(N=100, lambda=0.01, rho=1, beta=-0.6, rateC=0.001)
  fit <- coxph(Surv(time, status) ~ x, data=dat)
  betaHat[k] <- fit$coef
}

#Estimate a survival function
survfit(Surv(as.numeric(time), x)~1, data=dat) -> out0

#plot    

library(survminer)
ggsurvplot(out0, data = dat, risk.table = TRUE)

gg1 <- ggsurvplot(
  out0,                     # survfit object with calculated statistics.
  data = dat,  # data used to fit survival curves. 
  risk.table = TRUE,       # show risk table.
  pval = TRUE,             # show p-value of log-rank test.
  conf.int = TRUE,         # show confidence intervals for 
  # point estimaes of survival curves.
  xlim = c(0,2000),        # present narrower X axis, but not affect
  # survival estimates.
  break.time.by = 500,     # break X axis in time intervals by 500.
  ggtheme = theme_minimal(), # customize plot and risk table with a theme.
  risk.table.y.text.col = T, # colour risk table text annotations.
  risk.table.y.text = FALSE,
  surv.median.line = "hv",
  color = "darkgreen",
  conf.int.fill = "lightblue",
  title = "Survival probability",# show bars instead of names in text annotations
  # in legend of risk table
)
gg1

enter image description here

2

2 Answers

3
votes

As far as I see this, it is not possible do it with ggsurvplot at this moment.

I created an issue requesting this feature: https://github.com/kassambara/survminer/issues/276

You can plot survivor curves of a weibull model with ggplot2 like this:

library("survival")
wbmod <- survreg(Surv(time, status) ~ x, data = dat)
s <- seq(.01, .99, by = .01)
t_0 <- predict(wbmod, newdata = data.frame(x = 0), 
                 type = "quantile", p = s)
t_1 <- predict(wbmod, newdata = data.frame(x = 1), 
                type = "quantile", p = s)

smod <- data.frame(time = c(t_0, t_1), 
                   surv = rep(1 - s, times = 2), 
                   strata = rep(c(0, 1), each = length(s)),
                   upper = NA, lower = NA)

head(surv_summary(cm))

library("ggplot2")
ggplot() + 
  geom_line(data = smod, aes(x = time, y = surv, color = factor(strata))) +
  theme_classic()

enter image description here However to my knowledge you cannot use survminer (yet):

library("survminer")

# wrong:
ggsurvplot(smod) 

# does not work:
gg1$plot + geom_line(data = smod, aes(x = time, y = surv, color = factor(strata)))
0
votes

The following works for me. Probably the credit goes to Heidi filling a feature request. Hope, someone finds this useful.

library(survminer)
library(tidyr)

s <- with(lung,Surv(time,status))
sWei <- survreg(s ~ as.factor(sex),dist='weibull',data=lung)
fKM <- survfit(s ~ sex,data=lung)

pred.sex1 = predict(sWei, newdata=list(sex=1),type="quantile",p=seq(.01,.99,by=.01))
pred.sex2 = predict(sWei, newdata=list(sex=2),type="quantile",p=seq(.01,.99,by=.01))

df = data.frame(y=seq(.99,.01,by=-.01), sex1=pred.sex1, sex2=pred.sex2)
df_long = gather(df, key= "sex", value="time", -y)

p = ggsurvplot(fKM, data = lung, risk.table = T)
p$plot = p$plot + geom_line(data=df_long, aes(x=time, y=y, group=sex))

enter image description here