如何为ggsurvplot生成的生存曲线添加平滑效果?
欢迎来到Stack Overflow!很高兴看到你的第一个问题——给生存曲线加平滑线是个很实用的需求,刚好有几种方法可以实现,下面我一步步给你演示:
首先要明确,ggsurvplot()返回的是一个包含ggplot对象的列表,所以我们可以直接用ggplot2的语法扩展它,或者通过拟合专门的生存模型来生成平滑曲线。
方法1:直接在现有生存曲线上叠加平滑线
先运行你提供的代码生成基础生存曲线:
library(survival) library(survminer) # 创建生存对象 surv_object <- Surv(time = ovarian$futime, event = ovarian$fustat) # 拟合生存模型 fit1 <- survfit(surv_object ~ rx, data = ovarian) # 绘制生存曲线并保存为对象 p <- ggsurvplot(fit1, data = ovarian, pval = TRUE)
接下来,我们用surv_summary()提取生存曲线的详细数据,再用geom_smooth()添加平滑线:
# 获取生存曲线的汇总数据(包含时间、生存概率、分组等信息) surv_data <- surv_summary(fit1, data = ovarian) # 在原生存曲线基础上叠加平滑线 p$plot + geom_smooth( data = surv_data, aes(x = time, y = surv, color = strata), method = "loess", # 这里用loess方法做平滑,也可以尝试"gam"等其他方法 se = FALSE, # 是否显示置信区间可按需调整 linetype = "dashed", linewidth = 0.8 )
方法2:拟合平滑生存模型后绘制
如果你想要更具统计意义的平滑生存曲线,可以用flexsurv包拟合样条生存模型,再把预测的平滑曲线叠加到图上:
library(flexsurv) # 拟合样条生存模型(k=3控制样条的复杂度,可根据数据调整) fit_spline <- flexsurvspline(surv_object ~ rx, data = ovarian, k = 3) # 生成用于预测的时间序列和分组组合 pred_grid <- expand.grid( rx = unique(ovarian$rx), time = seq(min(ovarian$futime), max(ovarian$futime), length.out = 100) ) # 预测平滑的生存概率 pred_surv <- as.data.frame( predict(fit_spline, type = "survival", newdata = pred_grid) ) # 把平滑曲线叠加到原ggsurvplot上 p$plot + geom_line( data = pred_surv, aes(x = time, y = est, color = group), linetype = "dashed", linewidth = 1 )
两种方法各有优劣:方法1简单快速,是对现有阶梯曲线的平滑处理;方法2从模型层面拟合平滑生存曲线,更适合需要统计推断的场景。你可以根据自己的需求选择~
内容的提问来源于stack exchange,提问作者ValZee




