生存分析(Survival analysis)实战演练! 内附全部R代码!

生存分析(Survival analysis)是研究生存时间和危险因素之间关系的一种统计方法,被广泛应用于多种研究类型中,如临床试验,前瞻性与回顾性的观察性研究,以及动物研究等。


通常来说,生存分析可以回答以下问题: 

1. 不同组别之间的生存时间是否有差异?(比如:药物组vs安慰剂组)
2. 病人的五年生存率是多少?
3. 哪些因素会影响病人的生存时间?
等等...

因为生存分析内涵太深,理论部分实在是要花大把时间并参考其他书籍以深入了解,不是单独一篇文章可以讲清楚的。

所以,这篇教程目的在于实战,小推荐两款R包{survival}{survminer},速速带各位把代码先跑起来!

马上进入实战部分!

1. 如何准备符合生存分析要求的数据形式

想要做生存分析,第一个让人头疼问题很可能就是:数据乱糟糟,不知道如何清理数据以符合生存分析的要求。小编可以拍着胸脯保证,只要数据清理的好,分析和作图都是分分钟的事!


生存分析中的模范数据应该长这样(小编亲手制作 



上述表格应该说是简易版本,但也足够用来说明一些重要的概念。表格中的每行代表一个病例,每列代表一个变量,表格中共有五个变量(本表数值为虚构)。其中: 


ID:指病人的编号。


survtime: 生存时间,指从进入研究到事件发生(如死亡)或者失访或者一直存活到研究结束的这一段时间。


status: “1”指的是发生了某个事件(如死亡);“0”指的是删失(censored)。这里插一句,censored是生存分析中非常重要的一个概念。比如说,一个病人在整个研究期间没有死亡,或者在研究的过程中失访了,这样的情况就称作为“censored”,研究者这时候会在数据库中记录此病人的状态为“0”。


age: 年龄。


gender: 性别,比如“1”代表男,“2”代表女。你也可以反过来,但我们的“潜规则”是1男2女。

2. R包的安装

安装和载入两个在生存分析领域中非常热门的R包: 


# 安装R
install.packages(
"survminer")

# 载入
library(survival)  # R自带,无需安   
library(survminer)


其中,{survival}主要用于分析,{survminer}主要用于作图。

3. lung数据集简介

为了让每个人可以重复出结果,之后的分析与作图将会用到{survival}中的lung数据集。首先查看一下这个数据: 


str(lung)



可以使用R自带的帮助系统进一步了解这个数据集:


?lung


点击右侧帮助系统弹出的NCCTG Lung Cancer Data , 出现下图: 


按照上图可以一一对应的找到每个变量的意思,值得注意的是,time指的是生存时间,单位为天。status中的“1”指的是删失,“2”为死亡。其它为潜在的可以预测生存时间的临床变量。

4. 制作生存曲线

万事俱备,马上可以作图了(Kaplan-Meier曲线)!

现在假设我们想要研究性别是否会影响病人的生存时间,代码如下: 


# 拟合模型
surv_model <- survfit(Surv(time, status) ~ sex, data = lung)
# 制作生存曲线
ggsurvplot(surv_model, data = lung)



将y轴改成百分比的形式: 


ggsurvplot(surv_model, fun = "pct" ,data = lung)   # “pct” 即百分比



除此之外,ggsurvplot()函数可以通过参数多方位修饰,让图片变得更漂亮:


ggsurvplot(surv_model, data = lung, 
           conf.int = TRUE,                            # 添加置信区间
           pval = TRUE,                                # 添加p值
           fun =
"pct",                                # 将y轴转变为百分比的格式
           size =
1,                                   # 修饰线条的粗细
           linetype =
"strata",                        # 改变两条线条的类型
           palette = c(
"lightseagreen", "goldenrod1"), # 改变两条曲线的颜色
           legend = c(
0.8, 0.85),                      # 改变legend的位置
           legend.title =
"Gender",                    # 改变legend的题目
           legend.labs = c(
"Male", "Female"),          # 改变legend的标签
           surv.median.line =
"hv")                    # 添加中位生存时间




图片就搞定了!

因为{survminer}{ggplot2}的一个延伸,所以可以使用{ggplot2}的相关函数

举个例子,可以在上图中添加相应的文本“Chisq = 10.3  on 1 degrees of freedom”,会使用到{ggplot2}中的annotate()函数:

p1 <- ggsurvplot(surv_model, data = lung, 
           conf.int =
TRUE, # 添加置信区间
           pval =
TRUE, # 添加p值
           fun =
"pct", # 将y轴转变为百分比的格式
           size =
1, # 修饰线条的粗细
           linetype =
"strata", # 改变两条线条的类型
           palette = c(
"lightseagreen", "goldenrod1"), # 改变两条曲线的颜色
           legend = c(
0.80.85), # 改变legend的位置
           legend.title =
"Gender", # 改变legend的题目
           legend.labs = c(
"Male", "Female"), # 改变legend的标签
           surv.median.line =
"hv")

p1$plot +
  annotate(
"text", x = 750, y = 70, # 注明x和y轴的位置
           label =
"Chisq = 10.3 on 1 degrees of freedom") # 添加文本信息


文本就成功添加上去了!

5. Cox回归以及森林图

现在建立一个Cox回归,以研究sex对生存时间的影响,并且校正ph.ecog,那么可以这么做: 


cox_model <- coxph(Surv(time, status) ~ sex + ph.ecog, data = lung)
cox_model



为了更加美观地展示上述结果,森林图是一个不错的选择: 


ggforest(cox_model)



从上图可知,sex(女性相比较于男性)的风险比(hazard ratio)为0.58,95%置信区间为0.41-0.8,区间的两头都在1(虚线)的左侧,提示女性的风险更低(可能是保护因素),并且具有统计学意义(p < 0.001)。同理,ph.ecog的风险比为1.63, 提示是一个危险因素。


好啦,今天的内容就到这里。如果有帮助,记得分享给需要的人!



参考文献:

[1] https://github.com/kassambara/survminer
[2] https://cran.r-project.org/web/packages/survival/index.html
[3]《Applied Survival Analysis Using R》by Dirk F. Moore


▌本文由R语言和统计首发,如需转载请联系我们
▌课程相关咨询可添加R师妹微信: kefu_rstats
▌编辑:June
▌邮箱:contact@rstats.cn
▌网站:www.rstats.cn
我们致力于让R语言和统计变得简单!



2023-02-13 11:01
首页    公众号    生存分析(Survival analysis)实战演练! 内附全部R代码!