生存分析

目录

一、生存分析
  基本术语
二、R语言实现
  0.加载包
  1.示例数据,R包自带数据集"lung"
  2.创建生存对象并拟合函数
  3.可视化
    3.1 默认设置作图
    3.2 我的偏好作图
    3.3 我的作图函数
三、其他
  1.p值如何计算

一、生存分析

一些医学事件所经历的时间,从开始观察到事件发生的时间,不是短期内可以明确判断的。
e.g.乳腺癌病人术后生存时间
针对这类生存资料的分析方法:生存分析

基本术语

event 事件

例如,患者死亡,患者复发……取决于研究要观察的事件

time 时间

一般指,从开始观察到事件发生的时间。

xx期 定义
OS(Overall survival) 总体生存期:从初次治疗到患者死亡的时间。
RFS(Recurrence free survival) 无复发生存期:从初次治疗到出现复发或者随访截止的时间。
PFS(Progression-free survival) 从初次治疗到疾病进展或因任何原因死亡的时间。一般PFS越长,意味着患者有质量的生存时间越长,活得越好。

status 状态

status     含义
1 观察对象出现了终点事件,e.g.观察对象在手术后5年死亡
0 观察对象没有出现终点事件,e.g.观察对象在手术后第3年,与该患者失去联络,该患者的生存情况未知;或者该患者仍存活;或者……

二、R语言实现

0.加载包(如果没有,就安装)

library(survival)
library(survminer)

1. 示例数据,R包自带数据集"lung"

head(lung)
  inst time status age sex ph.ecog ph.karno pat.karno meal.cal wt.loss
1    3  306      2  74   1       1       90       100     1175      NA
2    3  455      2  68   1       0       90        90     1225      15
3    3 1010      1  56   1       0       90        90       NA      15
4    5  210      2  57   1       1       90        60     1150      11
5    1  883      2  60   1       0      100        90       NA       0
6   12 1022      1  74   1       1       50        80      513       0
变量 含义
inst Institution code
time Survival time in days
status   censoring status 1=censored, 2=dead
age Age in years
sex Male=1 Female=2
ph.ecog     ECOG performance score as rated by the physician. 0=asymptomatic, 1= symptomatic but completely ambulatorph.karno: Karnofsky performance score (bad=0-good=100) rated by physician
pat.karno     Karnofsky performance score as rated by patient
meal.cal     Calories consumed at meals
wt.loss     Weight loss in last six months (pounds)

2.创建生存对象并拟合函数

创建生存对象需要三个变量

变量
时间,即time 例如生存的时间
状态 ,即status 例如这个样本是否出现终点事件(0或1)
分组标签 本例中分为男女两组

本文按照性别分组,男性是1,女性是2

table(lung$sex)
  1   2 
138  90 

接下来是创建生存对象

fit <- survfit(Surv(time, status) ~ sex, data = lung)             

3.可视化

3.1 默认设置作图

使用函数ggsurvplot()按照默认设置作图

ggsurvplot(fit)
Survival analysis

图中曲线下降说明某些观察对象出现了了终点事件;
图中的"+"表示是删失数据(Cencor),即未出现终点事件的观察对象,可能由于失去联络而未知该观察对象的生存情况。

3.2 我的作图偏好

其中HR(95%CI)和C-index是用函数annotate()添加,这部分要先计算cox模型。

注意点

  1. R语言运行的HR的含义。男性是1,女性是2。按顺序排序,男性是第一组,女性是第二组,HR=0.59 < 1的含义是第二组(女性)相对于第一组(男性)是一个保护因素。为了提前标记好分组的顺序,我的习惯是提前将分组标记为0,1……。

拟合cox模型,及一些必要的准备。

cox <- coxph(Surv(time, status) ~ sex, data = lung)
res <- summary(cox)
x <- lung$time

作图代码如下:

p<-ggsurvplot(fit,
           pval = TRUE, pval.coord = c(0.7*max(x), 1),
           pval.method = TRUE, pval.method.coord=c(0.4*max(x),1),
           risk.table = TRUE, risk.table.col = "strata",
           ggtheme = theme_linedraw(), 
           palette = c("darkblue", "red"), 
           legend.title = "Gender",
           legend.labs = c("Male", "Female"),
           xlab = "Time(days)", xlim = c(0,1000), break.x.by = 200, 
           ylab = "Survival probability"
           )
p$plot <- p$plot+
  theme(panel.grid.major=element_blank(),panel.grid.minor=element_blank())+
  ggtitle("My Survival Plot")+
  theme(plot.title = element_text(hjust = 0.5))+
  annotate("text",x=0.7*max(x),y=0.91, label=paste0("HR(95%CI) = ", round(res$conf.int[1],2), "(",round(res$conf.int[3],2),"-", round(res$conf.int[4],2), ")" ))+
  annotate("text",x=0.7*max(x),y=0.83, label=paste0("C-index = ", round(res$concordance[1],2)))
p$table <- p$table+
  theme(panel.grid.major=element_blank(),panel.grid.minor=element_blank())

png("My Survival analysis.png", width = 4290, height = 4930, res = 1000)
p
dev.off()
参数 含义
pval 是否显示p-value
pval.coord p-value的位置
pval.method 是否显示计算p-value的方法
pval.method.coord pval.method的位置,此处的代码意思是
risk.table 是否显示风险表
risk.table.col 设置风险表的颜色,此处设置为与分组(palette)颜色一致
ggtheme 设置主题,见ggplot2的主题设置
palette 设置分组颜色
legend.title 图例标题
legend.labs 两组的名称,此处设为"Male"和"Female"
xlab 设置x轴名称
xlim 设置x轴的取值范围
break.x.by 设置x轴的刻度
ylab 设置y轴名称
My Survival analysis

3.3 我的作图函数

输入数据object0是如下格式的数据框:

time status groups
xx 1 1
xx 0 0
…… …… ……

file_name 是保存的文件名,我要输出的图片格式是tiff,所以此处应该是"file_name.tiff"这样形式,如果要保存为其他图片格式,需要修改函数中的代码。
其余的参数是我要修改的地方,也就是按我的偏好设置图的地方。
要注意的是这些值都需要设置,可以根据自己的偏好去修改函数,不要的删去,要的留下。

ylab0 xlab0 break_x0 xlim0 legend_title0 legend_labs0
y轴名称 x轴名称 x轴刻度 x轴显示范围 图例标题 分组标签
loop_survival_analysis <- function(object0, file_name, ylab0, xlab0, break_x0,
                                   xlim0, legend_title0, legend_labs0){
  library(survival)
  library(survminer)
  
  # survfit()-------------------------------------------------------------------
  fit <- surv_fit(Surv(time, status) ~ groups, data = object0) 
  
  # cox-------------------------------------------------------------------------
  cox <- coxph(Surv(time, status) ~ groups, data = object0)
  res <- summary(cox)
  x <- object0$time
  
  # fig-------------------------------------------------------------------------
  p<-ggsurvplot(fit,
                pval = TRUE, pval.coord = c(0.7*max(x), 1),
                pval.method = TRUE, pval.method.coord=c(0.4*max(x),1),
                risk.table = TRUE, risk.table.col = "strata",
                ggtheme = theme_linedraw(), 
                palette = c("darkblue", "red"), 
                legend.title = legend_title0,
                legend.labs = legend_labs0,
                xlab = xlab0, xlim = xlim0, break.x.by = break_x0, 
                ylab = ylab0
                )
  
  p$plot <- p$plot+
    theme(panel.grid.major=element_blank(),panel.grid.minor=element_blank())+
    # ggtitle("My Survival Plot")+
    theme(plot.title = element_text(hjust = 0.5))+
    annotate("text",x=0.7*max(x),y=0.91, label=paste0("HR(95%CI) = ", round(res$conf.int[1],2), "(",round(res$conf.int[3],2),"-", round(res$conf.int[4],2), ")" ))+
    annotate("text",x=0.7*max(x),y=0.83, label=paste0("C-index = ", round(res$concordance[1],2)))
  p$table <- p$table+
    theme(panel.grid.major=element_blank(),panel.grid.minor=element_blank())
  
  tiff(file_name, width = 4290, height = 4930, res = 1000)
  print(p)
  dev.off()
}

三、其他

1. p值如何计算

Log-Rank test是无参数检验,近似于卡方检验
H0:两组生存过程相同,H1:两组生存过程不同

取出p值

surv_diff <- survdiff(Surv(time, status) ~ sex, data = lung)
p.value <- 1 - pchisq(surv_diff$chisq, length(surv_diff$n) -1)

surv_diffs 如下所示

surv_diff

Call:
survdiff(formula = Surv(time, status) ~ sex, data = lung)

        N Observed Expected (O-E)^2/E (O-E)^2/V
sex=1 138      112     91.6      4.55      10.3
sex=2  90       53     73.4      5.68      10.3

 Chisq= 10.3  on 1 degrees of freedom, p= 0.001 
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,402评论 6 499
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,377评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,483评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,165评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,176评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,146评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,032评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,896评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,311评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,536评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,696评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,413评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,008评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,815评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,698评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,592评论 2 353

推荐阅读更多精彩内容