前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >生存分析有必要把连续值依据中位值进行高低分组变成分类变量吗

生存分析有必要把连续值依据中位值进行高低分组变成分类变量吗

作者头像
生信技能树
发布2021-10-12 12:11:19
1.4K0
发布2021-10-12 12:11:19
举报
文章被收录于专栏:生信技能树生信技能树

前面的教程:estimate或者CIBERSORT结果真的是很好的临床预后指标吗,我们针对 estimate 的StromalSignature 和 ImmuneSignature 这样的打分值进行了生存分析。

但是呢,我们其实是根据每个癌症内部自己的 estimate 的StromalSignature 和 ImmuneSignature的打分的中位值,首先分成为了高低两个组,然后进行生存分析看是否有统计学显著。estimate 的打分本身是超级简单, 如果你还不懂就去看前面的教程:不同癌症内部按照estimate的两个打分值高低分组看蛋白编码基因表达量差异

全部的癌症批量就可以跑完生存分析,然后我们查看了BRCA这个癌症的结果, estimate 算法得到的StromalSignature 和 ImmuneSignature都是可以区分生存,因为p值都是0.05附近,结合生存分析的图表,可以看到:

  • 其中StromalSignature 高死得快,是风险因子。
  • 而ImmuneSignature高死的慢,是保护因子。

然后有小伙伴就留言了,为什么要把连续值依据中位值进行高低分组变成分类变量,然后使用survdiff来做两个组的统计检验呢,既然是连续值,可以直接cox方法啊!

ox方法的操作代码如下所示:

代码语言:javascript
复制
rm(list = ls()) 
load('../expression/estimate_results/ssgseaScore-for-ssGSEA_for_seurat.Rdata')
head(ssgseaScore)
ssgseaScore$pid=substring(rownames(ssgseaScore),1,12)
head(ssgseaScore)

library(survminer) 
library(survival)
load(file = 'phe_stage.Rdata')
phe[1:4,1:4] 
phe$OS.time =  phe$OS.time/365
tp=unique(phe$type)
tp
options(digits = 2)

cox_results <- do.call(rbind,
                      lapply(tp, function(x){
                        # x=tp[1]
                        this_phe=phe[phe$type==x,]
                        # 这里先看 os 
                        survival_dat=as.data.frame(this_phe[,c('bcr_patient_barcode','OS','OS.time')])
                        head(survival_dat) 
                        colnames(survival_dat)=c('pid','event','time')
                        survival_dat=merge(survival_dat,ssgseaScore,by='pid')  
                        colnames(survival_dat)
                        attach(survival_dat)
                        s=Surv(time, event) ~    StromalSignature+ImmuneSignature 
                        model <- coxph(s, data = survival_dat )
                        sm=summary(model,data=survival_dat) 
                        return( c(sm$coefficients[1,c(5,2)],
                                  sm$coefficients[2,c(5,2)]))
                      }))
rownames(cox_results)=tp
round(cox_results,2)
save(cox_results,file = 'cox_results_for_estimate.Rdata')

load(file = 'km_results_for_estimate.Rdata')
tmp=cbind(cox_results,km_results)
colnames(tmp)=NULL
round(tmp,2)

可以看到两次生存分析结果还是有比较好的一致性,为了节省空间,下面的表格结合了cox和km的两种生存分析结果,都是 stromal_p.val,stromal_HR, immune_p.val,immune_HR的顺序。

前面的4列是cox结果,后面的4列是km的结果。可以看到cox的生存分析把打分当做是连续变量,计算得到的HR值非常的大,但是km方法把打分根据中位值进行了高低分组,得到的HR整体低很多!

代码语言:javascript
复制
> round(tmp,2)
     [,1]     [,2] [,3]    [,4] [,5] [,6] [,7] [,8]
ACC  0.68     5.45 0.28    0.03 0.70 0.86 0.03 0.43
BLCA 0.00    20.16 0.00    0.07 0.03 1.38 0.85 0.97
BRCA 0.00    18.18 0.00    0.09 0.06 1.31 0.04 0.75
CESC 0.13     5.88 0.01    0.07 0.47 0.84 0.06 0.64
CHOL 0.91     1.48 0.45    0.11 0.15 0.54 0.04 0.39
COAD 0.14     5.51 0.28    0.22 0.41 1.17 0.81 1.05
DLBC 0.70     0.07 0.94    0.62 0.87 0.90 0.63 1.35
ESCA 0.95     1.08 0.84    0.72 0.66 1.11 0.68 1.10
GBM  0.26     9.45 0.74    0.62 0.20 1.24 0.21 1.24
HNSC 0.59     1.41 0.01    0.17 0.23 0.86 0.04 0.77
KICH 0.16   217.22 0.49    0.06 0.76 1.19 0.64 0.76
KIRC 0.06     0.15 0.01    5.62 0.78 0.96 0.13 1.24
KIRP 0.00   135.75 0.12    0.14 0.06 1.70 0.83 0.94
LAML 0.01     0.00 0.00 7617.42 0.80 1.05 0.01 1.70
LGG  0.03    81.55 0.75    1.60 0.00 1.77 0.01 1.58
LIHC 0.71     0.64 0.91    1.12 0.65 1.07 0.75 1.05
LUAD 0.71     1.38 0.17    0.33 0.16 0.82 0.07 0.78
LUSC 0.26     2.30 0.84    1.15 0.03 1.32 0.18 1.19
MESO 0.01    46.32 0.08    0.10 0.01 1.83 0.45 0.84
OV   0.04     4.64 0.12    0.35 0.63 1.06 0.36 0.89
PAAD 0.40     3.12 0.92    0.87 0.54 1.13 0.80 0.95
PCPG 0.98     0.87 0.46    0.00 0.17 0.34 0.64 0.72
PRAD 0.36     0.01 0.91    0.50 0.22 0.45 0.59 0.71
READ 0.44     7.13 0.74    0.35 0.16 1.65 0.80 0.91
SARC 0.85     0.79 0.24    0.34 0.06 0.68 0.01 0.59
SKCM 0.06     4.66 0.00    0.07 0.04 0.76 0.00 0.57
STAD 0.00    10.25 0.16    0.34 0.10 1.30 0.33 1.17
TGCT 0.04 46133.57 0.12  137.01 0.04  Inf 0.19 3.95
THCA 0.01 11888.26 0.01    0.00 1.00 1.00 0.75 0.86
THYM 0.84     1.96 0.51   12.86 0.92 1.07 0.73 0.79
UCEC 0.84     1.28 0.02    0.08 0.48 0.87 0.01 0.60
UCS  0.79     0.60 0.79    1.61 0.68 1.15 0.73 0.89
UVM  0.82     3.06 0.01  164.61 0.01 2.86 0.00 4.38

对上面的表格进行简单的统计:

代码语言:javascript
复制
> table(tmp[,1] > 0.05 ,tmp[,5] > 0.05)
# cox和km对 StromalSignature 指标判断为显著,重合的癌症就3个,各自有自己的特殊性       
        FALSE TRUE
  FALSE     4    6
  TRUE      3   20
> table(tmp[,3] > 0.05 ,tmp[,7] > 0.05)
       
        FALSE TRUE
  FALSE     6    4
  TRUE      4   19
> table(tmp[,2] > 1 ,tmp[,6] > 1)
# 可以看到   StromalSignature 在绝大部分癌症都是风险因子,因为HR值大于1     
        FALSE TRUE
  FALSE     5    3
  TRUE      7   18
> table(tmp[,4] > 1 ,tmp[,8] > 1)
# 可以看到   ImmuneSignature 在绝大部分癌症都是风险因子,因为HR值小于1          
# 而且两个方法异一致性还行
        FALSE TRUE
  FALSE    19    5
  TRUE      2    7

可以看到,无论是从p值0.05这个阈值的角度来看,cox和km的生存分析是否有统计学意义的一致性都还行吧!

另外,从HR值角度看 cox和km对该因素的风险因子和保护因子的判断也是勉强可以的!

主要是可以看看卡方检验的p值,如下所示:

代码语言:javascript
复制
> chisq.test(table(tmp[,1] > 0.05 ,tmp[,5] > 0.05)) 
X-squared = 2, df = 1, p-value = 0.2 
> chisq.test(table(tmp[,3] > 0.05 ,tmp[,7] > 0.05))  
X-squared = 4, df = 1, p-value = 0.04 
> chisq.test(table(tmp[,2] > 1 ,tmp[,6] > 1)) 
X-squared = 2, df = 1, p-value = 0.2 
> chisq.test(table(tmp[,4] > 1 ,tmp[,8] > 1)) 
X-squared = 7, df = 1, p-value = 0.009

这就有点麻烦,在0.05附近蹦跶,很难下结论。

最后你会发现其实上面的数值不直观

所以,需要一个很好的可视化!我随便写了一点:

代码语言:javascript
复制
library(ggpubr) 
library(ggplot2)
library(patchwork)

check <- function(df){
  colnames(df)=c('p.val','HR')
  df$v=log(df$HR)
  df$sig = ifelse(df$p.val < 0.05,'sig','no')
  table(df$sig)
  df$cancer=rownames(df)
  ggdotchart(df, y = "v", x = "cancer",
             color = "sig",       
             sorting = 'none',
             add = "segments", 
             rotate = TRUE,
             xlab=""
  ) 
}
df=as.data.frame(tmp[,1:2])
p1=check(df)
df=as.data.frame(tmp[,5:6])
p2=check(df)

p1+p2

出图如下:

可以看到ACC这个癌症就是cox和km算出来的的HR值反过来了,对stromal来说。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-10-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 生信技能树 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 最后你会发现其实上面的数值不直观
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档