Survival Analysis in R: survminer, Cox PH, and Competing Risks
A practical guide to survival analysis in R — from Surv objects to Cox PH to competing risks — for public health and biostatistics researchers.
R’s survival analysis ecosystem is arguably the best in any language. The survival package (maintained by Terry Therneau, one of the original Cox model implementers) is the gold standard. survminer adds publication-ready visualizations. Together, they handle everything from Kaplan-Meier curves to competing risks.
Setting Up Survival Data
The Surv() object encodes both the time and censoring information. Once created, it plugs into all survival functions as the response variable.
Kaplan-Meier Curves
ggsurvplot() from survminer produces journal-quality KM curves with risk tables, confidence intervals, and log-rank p-values in a single call. This would take ~30 lines of manual ggplot2 code.
Stop fighting with syntax.
Sytra is an AI research assistant built specifically for statistical computing. No more copy-pasting code into ChatGPT.
Get Early AccessCox Proportional Hazards
The cox.zph() function tests the proportional hazards assumption for each covariate and globally. ggcoxzph() visualizes the Schoenfeld residuals. ggforest() produces a forest plot of hazard ratios — the standard visualization for Cox model results in medical journals.
Competing Risks
Comparison with Stata
R’s survival analysis has two clear advantages: (1) survminer’s visualization tools are significantly better than Stata’s sts graph, and (2) the competing risks ecosystem (cmprsk, tidycmprsk) is more mature and better documented. Stata’s advantage is the unified st prefix: stset, stcox, sts, streg — a consistent interface. R requires learning multiple packages with different APIs.