You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用ggsurvfit包创建分面生存图?报错问题求助

如何在ggsurvfit中创建分面生存曲线?

你尝试用ggsurvfit结合ggplot2的分面功能,按Treatment分组展示不同Timepoint的Kaplan-Meier曲线,但代码报错,核心原因是生存分析模型未纳入分面变量Treatment,导致后续ggplot图层中没有该变量,无法完成分面。

原代码报错信息

Error in `combine_vars()`:
! At least one layer must contain all faceting variables: `Treatment`
✖ Plot is missing `Treatment`
✖ Layer 1 is missing `Treatment`
✖ Layer 2 is missing `Treatment`
✖ Layer 3 is missing `Treatment`
Run `rlang::last_error()` to see where the error occurred.

正确实现方法

要让分面生效,必须在survfit2()的公式中同时包含分面变量和分组变量(即Treatment和Timepoint),这样生成的生存对象会携带分面分组信息,后续ggsurvfit处理后的数据才能被ggplot识别用于分面。

完整代码如下:

library(survival)
library(ggsurvfit)

dat <- structure(list(Rabbit = c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 
10L, 11L, 12L, 13L, 14L, 15L, 16L, 17L, 18L, 19L, 20L, 21L, 22L, 
23L, 24L, 25L, 27L, 26L, 34L, 35L, 28L, 29L, 32L, 36L, 30L, 31L, 
33L, 37L, 38L, 39L, 40L, 41L, 42L), Treatment = structure(c(3L, 
3L, 4L, 4L, 2L, 2L, 1L, 1L, 5L, 3L, 3L, 4L, 4L, 2L, 2L, 1L, 1L, 
5L, 3L, 3L, 4L, 4L, 2L, 2L, 1L, 1L, 5L, 3L, 3L, 4L, 4L, 2L, 2L, 
1L, 1L, 5L, 4L, 4L, 5L, 4L, 4L, 5L), levels = c("Meat bait", 
"Soil spray", "Carrot bait", "Oat bait", "Control"), class = "factor"), 
    Survival.Time.Rabbit = c(68.5, 75, 51, 51, 99, 120, 240, 
    219, 336, 53, 29, 77, 77, 96, 149, 91.5, 77, 336, 336, 336, 
    77.67, 92.67, 336, 336, 336, 336, 336, 336, 336, 53.5, 73, 
    336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336), Status.Rabbit = c(1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 0L, 0L, 0L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), Timepoint = structure(c(1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 
    4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 6L, 6L, 6L), levels = c("1 Day post exposure", 
    "5 Days post exposure", "10 Days post exposure", "20 Days post exposure", 
    "40 Days post exposure", "60 Days post exposure"), class = "factor"), 
    Survival.Time.Bait1 = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, NA, 
    5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, NA, NA, NA, 10L, 10L, NA, 
    NA, NA, NA, NA, NA, NA, 20L, 20L, NA, NA, NA, NA, NA, NA, 
    NA, NA, NA, NA, NA), Survival.Time.Bait2 = c(NA, NA, NA, 
    NA, NA, NA, NA, NA, 1L, NA, NA, NA, NA, NA, NA, NA, NA, 5L, 
    10L, 10L, NA, NA, 10L, 10L, 10L, 10L, 10L, 20L, 20L, NA, 
    NA, 20L, 20L, 20L, 20L, 20L, 40L, 40L, 40L, 60L, 60L, 60L
    )), row.names = c(NA, -42L), class = "data.frame")

# 关键修改:在survfit2公式中加入Treatment变量
survfit2(Surv(Survival.Time.Rabbit, Status.Rabbit) ~ Treatment + Timepoint, data = dat) %>% 
  ggsurvfit(linewidth = 1.5) + 
  labs(x = "Time to death (hours)", 
       y = "Survival probability") + 
  add_confidence_interval() + 
  add_pvalue("annotation", caption = "Log-rank {p.value}", size = 4) +
  theme(axis.title.x = element_text(face = "bold", size = 12), 
        axis.title.y = element_text(face = "bold", size = 12), 
        axis.text.x = element_text(size = 10), 
        axis.text.y = element_text(size = 10)) + 
  facet_wrap(~Treatment, nrow = 2)

原理说明

ggsurvfit虽然与ggplot2深度集成,但生存曲线的生成依赖于survfit2输出的对象。如果模型中未包含分面变量,ggsurvfit生成的图层数据里就没有该变量,ggplot在执行分面时无法找到对应的分组信息,因此抛出错误。通过在模型公式中加入Treatment,让生存分析按Treatment和Timepoint的组合分组,后续分面就能正确识别每个子图对应的Treatment组,展示该组内不同Timepoint的生存曲线。

内容的提问来源于stack exchange,提问作者Pat Taggart

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 20:52:22