平滑ggsurvplot生成的生存曲线?

1sbrub3j  于 2023-09-27  发布在  其他
关注(0)|答案(3)|浏览(134)

我是stackoverflow的新手,这是我的第一个问题:)我想知道是否有一个类似于“geom_smooth”的函数,但是使用“ggsurvplot”生成的图。下面是我想做的一个例子,使用R“ovarian”数据集:
创建一个“生存对象”:

library(survival)
surv_object <- Surv(time = ovarian$futime, event = ovarian$fustat)

从先前拟合的模型创建“生存曲线”:

fit1 <- survfit(surv_object ~ rx, data = ovarian)

绘制“survfit”对象:

library(survminer)    
ggsurvplot(fit1, data = ovarian, pval = TRUE)

多谢了,瓦莱里安

pbgvytdp

pbgvytdp1#

一种“绘制点之间对角线的简单方法”可以很容易地从我们感兴趣的"survfit"对象中提取出来,timesurv和地层。两个层具有相同的长度,因此我们只需重复每个层的层id length(fit1$surv) / 2

# survfit object
library(survival)
fit1 <- survfit(Surv(time=ovarian$futime, event=ovarian$fustat) ~ rx, data=ovarian)

# extraction
d1 <- with(fit1, data.frame(time, surv, strata=rep(1:2, each=length(surv) / 2)))

然后,我们可以分别绘制每个层的估计值。

cols <- c("red", "blue")
plot(d1$time, d1$surv, type="n", ylim=0:1)
sapply(1:2, function(x) with(d1[d1$strata == x, ], lines(time, surv, type="l", col=cols[x])))
legend("topright", legend=c("rx1", "rx2"), lty=1, col=cols, title="Strata")

或者使用ggplot2,类似这样:

ggplot2::ggplot(d1, aes(x=time, y=surv, group=strata, col=strata)) +
  geom_line() +
  ylim(0:1) + 
  scale_colour_identity()

注意,这只是编程问题的范围,可能需要一些关于平滑假设的讨论,例如在Cross Validated上。

vpfxa7rd

vpfxa7rd2#

你不想平滑你的数据,而是绘制曲线而不是直线。
该方法的全部功劳归于@Z.Lin(https://stackoverflow.com/a/54900769/9406040)。还要感谢@jay.sf从survfit对象中提取数据。

数据

library(tidyverse)
library(survival)

surv_object <- Surv(time = ovarian$futime, event = ovarian$fustat)
fit1 <- survfit(surv_object ~ rx, data = ovarian)

d1 <- with(fit1, data.frame(time, surv,
                            strata = as.factor(rep(1:2, each=length(fit1$surv) / 2))))

d2 <- d1 %>%
  group_by(strata) %>%
  summarise(x = list(spline(time, surv, n = 200, method = "natural")[["x"]]),
            y = list(spline(time, surv, n = 200, method = "natural")[["y"]])) %>%
  tidyr::unnest(cols = c("x", "y"))

Plot

ggplot() + 
  geom_point(data = d1,
             aes(time, surv, color = strata)) +
  geom_line(data = d2,
            aes(x, y, color = strata))

与平滑的对比

ggplot() + 
  geom_point(data = d1,
             aes(time, surv, color = strata)) +
  geom_smooth(data = d1,
              aes(time, surv, color = strata),
              se = FALSE)

vsnjm48y

vsnjm48y3#

**更新:**好的答案可能是here,用ggplot here绘图。
原件:我知道这个帖子有点老了,但我刚刚遇到了同样的问题,因为我正在处理基于注册表的公共卫生数据,不允许公布敏感数据。逐步生存图被认为是这样的,所以我不得不想办法绘制一条平滑的生存曲线。

下面是我对优秀的ggsurvfit包的建议。
作为平滑函数,我使用来自ggplot2::geom_smooth()函数的标准平滑函数来处理大型数据集,因为这可以提供更好的外观(这也是我使用ggsurvfit::df_colon数据集的原因)。
我本来很想分享由此产生的情节,但我的名声不允许我分享图片。想办法

library(tidyverse)
library(survival)
library(purrr)
library(ggsurvfit)

## Data
df <- survfit(Surv(time, status) ~ surg, data = ggsurvfit::df_colon) |> ggsurvfit::tidy_survfit(type = "survival")

df_split <- split(df,df$strata)

df_smoothed <- purrr::reduce(lapply(c("estimate","conf.low", "conf.high"), function(j) {
  do.call(rbind,
          lapply(seq_along(df_split), function(i) {
            nms <- names(df_split)[i]
            y <-
              predict(mgcv::gam(as.formula(paste0(
                j[[1]], " ~ s(time, bs = 'cs')"
              )), data = df_split[[i]]))
            df <- data.frame(df_split[[i]]$time, y, nms)
            names(df) <- c("time", paste0(j[[1]], ".smooth"), "strata")
            df
          }))
}),dplyr::full_join) |> full_join(df)
#> Joining with `by = join_by(time, strata)`
#> Joining with `by = join_by(time, strata)`
#> Joining with `by = join_by(time, strata)`

## Plotting
ggplot(data=df_smoothed) + 
  geom_line(aes(x=time, y=estimate.smooth, color = strata))+
  geom_ribbon(aes(x=time, ymin = conf.low.smooth, ymax = conf.high.smooth, fill = strata), alpha = 0.50)

创建于2023-09-15使用reprex v2.0.2

相关问题