| name | survival-analysis |
| description | Survival analysis in R, including Kaplan-Meier, Cox models, competing risks, RMST, and multi-state models. |
Survival Analysis Patterns
Overview
Comprehensive survival analysis methods in R covering Kaplan-Meier estimation, Cox proportional hazards models, parametric survival models, and advanced techniques for time-to-event data.
Basic Survival Objects
Creating Survival Data
library(survival)
surv_obj <- Surv(time = df$time, event = df$status)
surv_obj <- Surv(time = df$entry_time, time2 = df$event_time, event = df$status)
surv_obj <- Surv(time = df$left, time2 = df$right, type = "interval2")
head(surv_obj)
Kaplan-Meier Estimation
Basic KM Analysis
km_fit <- survfit(Surv(time, status) ~ 1, data = df)
summary(km_fit)
km_fit
summary(km_fit, times = c(12, 24, 36, 48, 60))
KM by Groups
km_fit <- survfit(Surv(time, status) ~ treatment, data = df)
survdiff(Surv(time, status) ~ treatment, data = df)
survdiff(Surv(time, status) ~ treatment + strata(site), data = df)
pairwise_survdiff(Surv(time, status) ~ treatment, data = df)
Publication-Quality KM Plots (survminer)
library(survminer)
ggsurvplot(km_fit, data = df)
ggsurvplot(
km_fit,
data = df,
pval = TRUE,
conf.int = TRUE,
risk.table = TRUE,
risk.table.col = "strata",
surv.median.line = "hv",
ggtheme = theme_bw(),
palette = c("#E7B800", "#2E9FDF"),
xlab = "Time (months)",
ylab = "Survival probability",
legend.title = "Treatment",
legend.labs = c("Control", "Treatment")
)
Risk Tables and Annotations
ggsurvplot(
km_fit,
data = df,
risk.table = TRUE,
risk.table.height = 0.25,
risk.table.y.text = FALSE,
cumevents = TRUE,
cumcensor = TRUE,
tables.height = 0.2,
break.time.by = 12,
xlim = c(0, 60),
surv.scale = "percent"
)
Cox Proportional Hazards
Basic Cox Model
cox_fit <- coxph(Surv(time, status) ~ treatment + age + sex, data = df)
summary(cox_fit)
exp(coef(cox_fit))
exp(confint(cox_fit))
library(broom)
tidy(cox_fit, exponentiate = TRUE, conf.int = TRUE)
Proportional Hazards Assumption
ph_test <- cox.zph(cox_fit)
print(ph_test)
ggcoxzph(ph_test)
ph_test$table
If proportional hazards is not credible, do not rely only on a single Cox hazard ratio or log-rank p-value. Consider prespecified alternatives such as time-varying treatment effects, weighted log-rank tests, milestone survival, or RMST.
Stratified Cox Model
cox_strat <- coxph(
Surv(time, status) ~ treatment + age + strata(center),
data = df
)
Time-Varying Covariates
cox_tv <- coxph(
Surv(tstart, tstop, status) ~ treatment + biomarker,
data = df_long
)
cox_tv <- coxph(
Surv(time, status) ~ treatment + tt(age),
data = df,
tt = function(x, t, ...) x * log(t)
)
Forest Plots
library(survminer)
ggforest(cox_fit, data = df)
library(forestplot)
forest_data |>
forestplot(
mean = hr,
lower = hr_lower,
upper = hr_upper,
labeltext = c(variable, n, hr_text),
is.summary = is_summary
)
Parametric Survival Models
With survreg
weibull_fit <- survreg(
Surv(time, status) ~ treatment + age,
data = df,
dist = "weibull"
)
exponential_fit <- survreg(..., dist = "exponential")
lognormal_fit <- survreg(..., dist = "lognormal")
loglogistic_fit <- survreg(..., dist = "loglogistic")
summary(weibull_fit)
With flexsurv (more distributions)
library(flexsurv)
ggamma_fit <- flexsurvreg(
Surv(time, status) ~ treatment + age,
data = df,
dist = "gengamma"
)
compare_distributions <- list(
exponential = flexsurvreg(Surv(time, status) ~ treatment, data = df, dist = "exp"),
weibull = flexsurvreg(Surv(time, status) ~ treatment, data = df, dist = "weibull"),
lognormal = flexsurvreg(Surv(time, status) ~ treatment, data = df, dist = "lognormal"),
gamma = flexsurvreg(Surv(time, status) ~ treatment, data = df, dist = "gamma"),
gengamma = flexsurvreg(Surv(time, status) ~ treatment, data = df, dist = "gengamma")
)
sapply(compare_distributions, AIC)
Flexible Parametric Models (rstpm2)
library(rstpm2)
stpm_fit <- stpm2(
Surv(time, status) ~ treatment + age,
data = df,
df = 4
)
stpm_tv <- stpm2(
Surv(time, status) ~ treatment + age,
data = df,
df = 4,
tvc = list(treatment = 2)
)
Competing Risks
Cause-Specific Hazards
cs_cause1 <- coxph(
Surv(time, status == 1) ~ treatment + age,
data = df
)
cs_cause2 <- coxph(
Surv(time, status == 2) ~ treatment + age,
data = df
)
Fine-Gray Subdistribution Hazards
library(cmprsk)
cif <- cuminc(
ftime = df$time,
fstatus = df$status,
group = df$treatment
)
ggcompetingrisks(cif)
fg_fit <- crr(
ftime = df$time,
fstatus = df$status,
cov1 = model.matrix(~ treatment + age, df)[, -1],
failcode = 1
)
summary(fg_fit)
With tidycmprsk
library(tidycmprsk)
cuminc(Surv(time, status) ~ treatment, data = df) |>
ggcuminc()
crr(Surv(time, status) ~ treatment + age, data = df, failcode = 1)
Restricted Mean Survival Time
library(survRM2)
rmst_result <- rmst2(
time = df$time,
status = df$status,
arm = df$treatment,
tau = 60
)
print(rmst_result)
library(survRM2)
rmst_reg <- rmst2(
time = df$time,
status = df$status,
arm = df$treatment,
covariates = df[, c("age", "sex")],
tau = 60
)
Multi-State Models
library(mstate)
tmat <- transMat(
x = list(
c(2, 3),
c(3),
c()
),
names = c("Healthy", "Illness", "Death")
)
msdata <- msprep(
time = c(NA, "illness_time", "death_time"),
status = c(NA, "illness_status", "death_status"),
data = df,
trans = tmat
)
ms_cox <- coxph(
Surv(Tstart, Tstop, status) ~ treatment + strata(trans),
data = msdata
)
pt <- probtrans(msfit(ms_cox, newdata = new_patient), predt = 0)
Survival with tidymodels (censored)
library(censored)
cox_spec <- proportional_hazards() |>
set_engine("survival") |>
set_mode("censored regression")
surv_wf <- workflow() |>
add_formula(Surv(time, status) ~ treatment + age + sex) |>
add_model(cox_spec)
surv_fit <- fit(surv_wf, data = train_data)
predict(surv_fit, new_data, type = "survival", eval_time = c(12, 24, 36))
predict(surv_fit, new_data, type = "hazard", eval_time = c(12, 24, 36))
Key Packages Summary
| Package | Purpose |
|---|
| survival | Core survival functions |
| survminer | KM plots and Cox visualization |
| flexsurv | Parametric models |
| rstpm2 | Flexible parametric (Royston-Parmar) |
| cmprsk | Competing risks |
| tidycmprsk | Tidy competing risks |
| survRM2 | RMST analysis |
| mstate | Multi-state models |
| censored | tidymodels integration |