R笔记:生存分析之竞争风险模型[概念与实操]
转自个人微信公众号【Memo_Cleon】的统计学习笔记:R笔记:生存分析之竞争风险模型[概念与实操]。
在《生存分析之Kaplan-Meier曲线绘制与比较》文末,我们提到了竞争风险。由于出现了其他结局事件而阻碍或者改变了感兴趣的目标结局事件的发生(概率),相对目标结局事件而言,这里的其他结局事件就是竞争风险事件。实际上除了以全因死亡为研究结局,以死因、复发等为结局的研究都广泛存在着竞争风险。比如以心血管死亡为研究结局,其他原因的死亡(如车祸意外、非心血管疾病死亡)发生时,心血管死亡就不会再出现了,但如果将其他原因的死亡按删失(censoring)处理,就意味着只要随访时间足够长,这些其他原因导致的死亡对象仍会再发生心血管疾病死亡,这显然与事实不符。同样以疾病复发为结局事件的研究中,研究对象的死亡同样导致该对象不会再发生疾病的复发。也就是说当失效时间与删失时间不独立时。将竞争风险作为删失处理是不恰当的。进一步你可能会问,删失是不是目标结局事件的竞争事件呢?当受试者失去随访时(发生删失),这些受试者仍然有发生目标结局事件的风险,只是研究者无法记录发生的准确时间而已,而竞争风险的发生是阻碍了目标结局事件的发生(如死亡发生后,疾病不会再出现复发)。换句话说,删失只是阻止了你观察到目标结局事件,而竞争事件则是阻止了目标结局事件的发生,所以删失并不是竞争事件,竞争事件的分析需要用一些新的方法。
本次笔记内容:(1)竞争风险模型理论基础;(2)R操作示例:累积发生率单因素比较;(3)R操作示例:特定原因风险回归;(4)R操作示例:子分布风险回归/累积发生率回归。
不存在竞争风险时,累积发生率函数与生存函数、风险函数、累积风险函数可以通过简单的函数直接转换,对累积发生率的研究可以转变成结局事件生存函数、风险函数/累积风险函数的分析,expβ可以作为考察协变量对累积发生率的相对影响的度量。当存在竞争风险时,累积发生率不仅取决于目标结局事件的风险函数,而且与竞争事件的风险函数也有关系,此时累积发生率不能简单地转变为对风险函数和生存函数的研究; 特定原因风险集排除了发生竞争事件的观察人群,特定原因的HR可以反应暴露对目标结局事件的影响的关系,而竞争事件可以从风险集中移除观察人群来从侧面影响这种关系。子分布风险集的构建包含了没发生任何事件的观察人群和那些已经发生竞争事件的人群; 特定原因的风险比可以表示暴露的出现使得结局发生的风险是原来的expβ倍(或者比原来增加100(expβ-1)%),但其值>1并不意味着暴露组的累积发生率大于非暴露组;子分布风险比表示暴露的出现使得结局的累积发生率增加(HRsd>1)或者减少(HRsd<1)。
由于此时CIF可以直接和生存函数或者累计风险函数直接关联,对CIF的研究可以转变为对目标结局事件生存函数或者累积风险函数的分析,只是我们往往关注的是生存函数S(t)=Pr(T>t and event type 1) 。
这里的不同原因的结局事件的风险函数hk(t),cause-specifific hazard function,在众多学习材料上不知为何翻译为原因别风险函数,刚看见这个概念的时候一脸的懵逼,我一度还以为是笔误。其实个人觉得翻译为特定原因的风险函数或者特定结局的风险函数更贴合实际意义一些。
当t趋于无穷大时,CIFk=P(D=k)。
注:Ik(t)即CIFk,λk(tj)即时刻j的hk(t)。
表示t时刻未发生第k类结局事件的观察人群中,k结局事件的瞬时发生率(瞬时概率强度)。与特定原因的风险函数不同,子分布风险函数将发生了其他结局事件的观察人群仍然在风险集中。此公式中的Fk(t)=CIFk=P(T≤t,D=k)、Sk(t)=P(T>t,D=k)、fk(t)=dFk(t)/dt分别是子分布累积发生率、子生存函数和子密度函数,注意P(D=k)=Sk(t)+Fk(t)。
特定原因的风险回归模型:
其中hk(t)即我们前面讲过的特定原因的风险函数(cause-specific hazard function):
hk0(t)表示k结局的基线风险,而β表示协变量对k结局的影响。
其中hsdk(t)即前面讲过的子分布风险函数(subdistribution hazard function):
参考文献:
H. Putter,et al.Tutorial in biostatistics: Competing risks and multi-state models.Statist. Med. 2007; 26:2389–2430.
Bryan L,et al.Competing Risk Regression Models for Epidemiologic Data.Am J Epidemiol. 2009 Jul 15;170(2):244-56.
Peter CA,et al.Introduction to the Analysis of Survival Data in the Presence of Competing Risks.Circulation. 2016;133:601–609.
【2】R操作示例:累积发生率单因素比较
cuminc{cmprsk}:Cumulative Incidence Analysis,Estimate cumulative incidence functions from competing risks data and test equality across groups.程序包cmprsk用于Subdistribution Analysis of Competing Risks,其通过函数cuminc获得的CIF也是子分布风险函数来获得的。
cuminc(ftime, fstatus, group, strata, rho=0, cencode=0,subset, na.action=na.omit)
命令清单如下:
library(haven)
surv <- read_dta("D:/Temp/survivalm.dta") #从stata文件中导入数据
library(cmprsk)
attach(surv) #将sury附加到搜索路径,这样后面直接使用sury中的变量名称即可,而不用采用surv$变量名的形式
CIF<-cuminc(time,cause,stage,0) #CIF<-cuminc(ftime=time,fstatus=cause,group=stage,cencode=0)
CIF #print(CIF)
legend<-c("stage I_CancerRelated", "stage II_CancerRelated", "stage III_CancerRelated", "stage I_notCancerRelated", "stage II_notCancerRelated", "stage III_notCancerRelated") #图例命名
plot(CIF, curvlab=legend,ylim=c(0,0.5),xlab="time_days", ylab="cumulative incidence function", lty=1:length(CIF), color=1:6)
detach(surv)
Gray检验结果显示不同病理学分期的多发性骨髓瘤死于癌症的累积发生率不同(Z=27.701,P<0.001),死于非癌症的累积发生率不同(Z=24.552,P<0.001)。
能进行经典的Cox风险比例回归分析的软件都可以进行特定原因的风险回归,只需要对不同原因的结局事件分别拟合即可,拟合的时候把对应的发生竞争结局的观察个体在发生竞争事件时视作删失来处理。R中可采用比较经典的coxph {survival}来处理。
Surv{survival}:Create a Survival Object.
Surv(time, time2, event,type=c('right', 'left', 'interval', 'counting', 'interval2', 'mstate'), origin=0)
该函数的难点在于定义失效事件,event: The status indicator, normally 0=alive, 1=dead. Other choices are TRUE/FALSE (TRUE = death) or 1/2 (2=death). For interval censored data, the status indicator is 0=right censored, 1=event at time, 2=left censored, 3=interval censored. For multiple endpoint data the event variable will be a factor, whose fifirst level is treated as censoring. Although unusual, the event indicator can be omitted, in which case all subjects are assumed to have an event.
coxph(formula, data=, weights, subset,na.action, init, control,ties=c("efron","breslow","exact"),
singular.ok=TRUE, robust,model=FALSE, x=FALSE, y=TRUE, tt, method=ties,id, cluster, istate, statedata, nocenter=c(-1, 0, 1), ...)
library(haven)
surv <- read_dta("D:/Temp/survivalm.dta") #从stata文件中导入数据
surv$stage<-factor(surv$stage) #gender、age、relative_with_cancer_history都是采用0/1赋值的二分类变量,不设为因子不影响结果
library(survival)
coxph(Surv(time,cause==1)~gender+age+relative_with_cancer_history+stage,data=surv) #癌症死亡结局
coxph(Surv(time,cause==2)~gender+age+relative_with_cancer_history+stage,data=surv) #非癌症死亡结局
结果显示,在校正其他变量的作用后,相对于stage1,stage2的死于癌症估计系数是1.09,是一个风险因子(HR=2.976,P=0.003);stage3也是死于癌症的一个风险因子(HR=5.367,P<0.001)。而对于非癌症死亡,stage3相对stage1是一个风险因子(HR=3.503,P<0.001),stage2却不是(HR=1.165,P=0.702)。值得注意的是,年龄是非癌症死亡的危险因子(HR=1.053,P<0.001),但不是癌症死亡的危险因子(HR=1.00,P=0.922)。
累积发生率回归可以使用crr{cmprsk}:
crr(ftime, fstatus, cov1, cov2, tf, cengroup, failcode=1, cencode=0,subset, na.action=na.omit, gtol=1e-06, maxiter=10, init, variance=TRUE)
该函数比较令人讨厌的地方是没有提供公式模型。如果要进行多因素分析,需要构建协变量矩阵,因子变量还需要设置哑变量。可借助函数model.matrix() 来完成,model.matrix() 可将对象中的因子变量转换成0/1哑变量,而连续变量保持不变,该函数可参见《哑变量》一文。
library(haven)
surv <- read_dta("D:/Temp/survivalm.dta") #从stata文件中导入数据
surv$stage<-factor(surv$stage) #gender、age、relative_with_cancer_history都是采用0/1赋值的二分类变量,不设为因子不影响结果
library(cmprsk)
multvar<-surv[2:6]
#multvar<-surv[c("age","gender","race","relative_with_cancer_history","stage")]
attach(multvar) #将multvar附加到搜索路径
cov<-model.matrix(~age+gender+race+relative_with_cancer_history+stage)[,-1] #构建多因素矩阵,model.matrix(~A+B+…)[,-1] 将为因子编码生成变量0/1哑变量,并保持连续变量不变。最后的[,-1]从 model.matrix 的输出中删除常数项
detach(multvar)
sdr1<-crr(surv$time,surv$cause,cov, failcode=1, cencode=0)
summary(sdr1, conf.int = 0.95) #结局1
sdr2<-crr(surv$time,surv$cause,cov, failcode=2, cencode=0)
summary(sdr2, conf.int = 0.95) #结局2
结果显示,在校正其他变量的作用后,相对于stage1,stage2和stage3的死于癌症的发生率更高(子分布风险比HR2=2.927,P=0.0033;HR3=4.470,P<0.001);相对于stage1,stage2的死于非癌症的发生率变化不大(子分布风险比HR2=1.124,P=0.77),stage3的死于非癌症的发生率更高(子分布风险比HR3=3.157,P<0.001)。
转自个人微信公众号【Memo_Cleon】的统计学习笔记:R笔记:生存分析之竞争风险模型[概念与实操]。
END