使用ggsurvplot分面时add.all=TRUE无法显示合并生存曲线
问题:survminer分面生存曲线添加全局汇总曲线失败
我想用R的survminer包绘制生存曲线,按基因突变(mut)分组分面,同时添加代表所有个体的全局汇总曲线。未使用add.all参数时,按性别和突变类型分组的生存分析与绘图都正常,但设置add.all=TRUE后,并没有按预期添加跨分面的汇总曲线。
可复现代码
library(survival) ; library(survminer) library(dplyr) set.seed(102030) lung <- lung %>% mutate( mut = sample(c("mutA","mutB"), nrow(lung), replace = T, prob = c(0.5,0.5))) # 创建演示分组 # 基础全局生存曲线 fit1 <- survfit(Surv(time, status) ~ 1 , data = lung) ggsurvplot(fit1 , data = lung) # 按性别分组的生存曲线 fit2 <- survfit(Surv(time, status) ~ sex , data = lung) ggsurvplot(fit2 , data = lung) # 按性别+突变分组的生存曲线(问题部分) fit3 <- survfit(Surv(time, status) ~ sex + mut, data = lung) ggsurvplot(fit3 , data = lung, facet.by = "mut") # 分面正常 ggsurvplot(fit3 , data = lung, facet.by = "mut", add.all = T) # 未按预期添加全局汇总曲线 # 尝试ggsurvplot_combine也无效 ggsurvplot_combine( list(fit1, fit3), list(lung, lung), facet.by = "mut", pval = TRUE, risk.table = TRUE, conf.int = F, palette = "jco" )
原因说明
survminer的add.all参数设计上不支持在facet.by分面场景下自动添加全局汇总曲线。当使用facet.by时,add.all只会尝试在整个绘图区域添加一条汇总曲线,而非为每个分面匹配对应的全局数据,因此无法达到预期效果。
解决方案
方法一:用ggsurvplot_facet手动添加全局曲线
先分别拟合全局模型和分面内的分组模型,再通过ggplot2的图层叠加为每个分面添加全局曲线:
library(survival) library(survminer) library(dplyr) library(broom) set.seed(102030) lung <- lung %>% mutate(mut = sample(c("mutA","mutB"), nrow(lung), replace = T, prob = c(0.5,0.5))) # 拟合全局生存曲线 fit_all <- survfit(Surv(time, status) ~ 1, data = lung) # 按mut分面,拟合每个分面内的sex分组模型 fit_group <- survfit(Surv(time, status) ~ sex, data = lung, strata = "mut") # 绘制分面生存曲线 p <- ggsurvplot_facet(fit_group, data = lung, facet.by = "mut", palette = "jco") # 将全局曲线转换为数据框,添加到每个分面 p$plot <- p$plot + geom_step(data = tidy(fit_all), aes(x = time, y = estimate), color = "black", linetype = "dashed", size = 1) print(p)
方法二:用ggplot2原生绘图(更灵活)
直接处理生存曲线数据,用ggplot2实现分面和全局曲线的叠加,自由度更高:
library(survival) library(ggplot2) library(dplyr) library(broom) set.seed(102030) lung <- lung %>% mutate(mut = sample(c("mutA","mutB"), nrow(lung), replace = T, prob = c(0.5,0.5))) # 获取性别+突变分组的生存数据 df_group <- tidy(survfit(Surv(time, status) ~ sex + mut, data = lung)) %>% separate(strata, into = c("sex", "mut"), sep = ", ") %>% mutate(sex = gsub("sex=", "", sex), mut = gsub("mut=", "", mut)) # 获取全局生存数据,并复制适配两个分面 df_all <- tidy(survfit(Surv(time, status) ~ 1, data = lung)) %>% mutate(mut = rep(c("mutA", "mutB"), each = nrow(.))) # 绘制生存曲线 ggplot() + geom_step(data = df_group, aes(x = time, y = estimate, color = sex), size = 0.8) + geom_step(data = df_all, aes(x = time, y = estimate), color = "black", linetype = "dashed", size = 1) + facet_wrap(~mut) + labs(x = "生存时间", y = "生存概率") + scale_color_jco() + theme_bw()
内容的提问来源于stack exchange,提问作者Seymoo
相关产品推荐
相关产品推荐

