imd 统计教程 · 预测模型与机器学习
← 教程首页 返回本模块

临床预测模型DCA决策曲线,顶刊全套路,美图美代码

聂志强实战医学统计2025-01-06 07:50:00广东

2024匆匆一年就这样过去了也没做过总结,就把此文献给和我一同奋斗的同学们和小伙伴们吧。

今天更新2025年第一篇推文,作为好的开端,我们就来聊一聊预测模型中的性能指标体系中的DCA曲线。之前我们写过许多预测模型系列文章,大家可以移步点此观看,还有未归纳的内容也可以搜索公众号“预测模型”。

预测模型性能指标包括许多维度,层级1整体性能、区分度、校准度、临床效度/效用/影响力指标,内容都包络万象不限于我下图的总结。DCA曲线是临床效用指标一个酷炫的展示形式。本文为DCA套路总结。

一、DCA

ROC追求的是区分度和高灵敏度特异度,而临床决策下一步是否采取干预,并不完全取决于预测准确度高!例如,干预后患者就一定受益吗?模型预测再准确,无论界值cutoff如何选取,都可能面对假阳性(误诊)和/或假阴性(漏诊)的问题。根据模型的预测结果去干预病人,这里面就有一个干预划不划得来的问题,对于不同的疾病,需要的阈值就不同,有时需要更高的假阳性,有时需要更高的假阴性。如果疾病危害小、尚无治愈办法,需要适当增加假阴性、避免假阳性;如果疾病危害大且晚发现、预后差,则需要适当增加假阳性、避免假阴性。

因此,这就是一个实际临床效用问题,到底怎么办,才能使患者获益最大?决策曲线分析(Decision Curve Analysis,DCA)就是为了解决这一问题。

二、DCA顶刊款式

我收集了pubmed顶刊全部的DCA的套路,汇总如下,A款课程,点我上课,当然也都提供了解决方案。主要是常规非time、time DCA两大类,图形可以单曲线、多曲线、DCA + 色带 + CIC自由组

三、常规6款图形R实战

常规模型如logistic等glm、ML系列非time相关预测模型,总体结果图形如下。推荐dca.r标准款、dcurve包。ggDCA存在R包兼容错误,ggscidca形态与标准图阈值接近0或者1处有异常,有待验证。

R代码如下

#----二、DCA 决策曲线----
#--① logistic DCA--------------
#---- 方法1  rmda包,不能画生存资料的DCA
# install.packages("rmda")
library(rmda)
set.seed(2025)
fit1 <- decision_curve(status ~ birth + lowph + pltct + bwt + vent + black + white,
                       data = train,
                       study.design = "cohort"# 选择研究类型
                       bootstraps = 100 )
                       # 重抽样次数1000+
##---款式1 rmda----
rmda::plot_decision_curve(fit1,
                    curve.names = "fit1",
                    cost.benefit.axis = F, # 是否需要损失:获益比轴
                    confidence.intervals = "none" )
# 数据很大,没有展示,大家可以自己运行看看
summary(fit1)

#----多条DCA 
fit2 <- decision_curve(status ~ birth + lowph + pltct,
                       data = train,
                       study.design = "cohort"# 选择研究类型
                       bootstraps = 100)
#画图只要把多个模型放在1 个列表中即可,还可以进行很多自定义调整
plot_decision_curve(list(fit1, fit2),
                    curve.names = c("fit1""fit2"),
                    xlim = c(0, 1), # 可以设置x 轴范围
                    legend.position = "topright"# 图例位置,
                    col = c("red""blue"), # 自定义颜色
                    confidence.intervals = "none",
                    lty = c(1, 2), # 线型,注意顺序
                    lwd = c(3, 2, 2, 1))
                    # 注意顺序,先是自己的模型,然后All, 然后None)
                
                    
## ----款式2  dca.r---- 
source("./dca.R")
df <- as.data.frame(train)
##--1??单指标----
dca(
  data = df, # 指定数据集, 必须是data.frame 类型
  outcome = "status"# 指定结果变量
  predictors = "black"# 分类预测x,则F
  probability = F )

#连续型只适合pre值0-1概率
dca(
  data = df, # 指定数据集, 必须是data.frame 类型
  outcome = "status"# 指定结果变量
  predictors = "birth",  # 如果predictors连续型则F
  probability = T )
#birth must be between 0 and 1 OR sepcified as a non-probability in the probability option

#--------预测变量不是0,1 或者有多个的话, 需要你先把预测概率算出来
#??建立包含多个自变量的logistic 模型,单指标也适用!
model <- glm(status ~ birth + lowph + pltct + bwt + vent + black + white,
             data = train,
             family = binomial())
df$prob <- predict(model, type = "response")
#---2??多指标计算prob!
dca(
  data = df, outcome = "status", predictors = "prob",
  probability = T,
  xstop = 0.35)
  # 控制x 轴范围

##---2??多曲线+多指标----
# prob 是概率所以是T,"black", "white"是01分类所以是F。
dca(
  data = df, outcome = "status",
  predictors = c("prob""black""white"), # 这是3 个模型哦!
  probability = c(T, F, F) # 和上面是对应的!
)
#-----款式4 ggDCA----
#install.packages("base.rms")
#install.packages("ggDCA")
##remotes::install_github('yikeshu0611/ggDCA')
library(ggDCA)
library(rmda)
# 构建模型
fit1 <- glm(status ~ birth + lowph + pltct + bwt + vent + black + white,
            data = train, family = binomial())
fit2 <- glm(status ~ birth + lowph  ,
            data = train, family = binomial())
library(ggplot2)
dca1 <- ggDCA::dca(fit1)
ggplot(dca1)
# 自动算出了TPR 和FPR
str(dca1)
ggplot(dca1, linetype = 1, color = c("firebrick""steelblue""green4")) +
  theme(legend.position = c(0.8, 0.75))

# 2 个模型画在一起
dca12 <- ggDCA::dca(fit1, fit2)
ggplot(dca12, linetype = 1, color = c("firebrick""steelblue""green4""tomato")) +
  theme(legend.position = c(0.8, 0.75))
##---- 款式5 ??dcurves包,推荐!----
#install.packages("dcurves")
# install.packages("devtools")
# devtools::install_github("ddsjoberg/dcurves")
library(dcurves)
library(rmda) 
# 构建模型
fit1 <- glm(status ~ birth + lowph + pltct + bwt + vent + black + white,
            data = train, family = binomial())
fit2 <- glm(status ~ birth + lowph  ,
            data = train, family = binomial())
library(ggplot2)
# 建立2 个模型,算出概率 
train$model1 <- predict(fit1, type = "response"
train$model2 <- predict(fit2, type = "response")
dcurves::dca( status ~ model1 + model2, data = train) %>%
  plot(
    smooth = T,
    show_ggplot_code = T # 显示ggplot2 代码,方便大家自己调整
  )
##----款式6 ??ggscidca包,推荐!----
##install.packages("ggscidca")
pacman::p_load(survival, reshape2, ggplot2, do, foreign, cmprsk, ggscidca)

#-----logistic要用tcdca!
#----1???? 单DCA带色带
scidca(fit1, newdata= train)

#----2?? 多DCA
#对每个模型的数据定义,生成列表
newdat<-list(train,train)
tcdca(fit1,fit2, newdata=newdat)

四、cox模型4款图形R实战

dcurve包虽然可以很好的制作logistic的DCA,但是在cox单曲线与多曲线都存在bug。下面推导过程中也发现ggDCA、stdca.R原始代码等包存在bug。ggDCA存在R包兼容错误,ggscidca形态与标准图阈值接近0或者1处有异常,有待验证




##---?? 款式2 ggDCA 错误---- 
##devtools::install_github('yikeshu0611/ggDCA')
pacman::p_load(ggDCA,rms)
# 同一个模型多个时间点、同一个时间点多个模型,ggdca可以非常简单的画出来
#cph和coxph都会报错!
dd <- datadist(df_surv)  # 创建数据分布对象
options(datadist = "dd"# 设置全局数据分布选项
cox_fit1 <- rms::cph(Surv(ttcancer, cancer) ~ marker + famhistory,data = df_surv)
cox_fit2 <- rms::cph(Surv(ttcancer, cancer) ~ cancerpredmarker, data = df_surv) 
#多个模型同一时间点的DCA:
summary(df_surv$ttcancer# 查看时间范围
df1 <- ggDCA::dca(cox_fit1, cox_fit2 , extend = TRUE,
                  # 默认值是中位数
                  times = 1)
#--Error in findrow(fit, times, extend) :  有bug!
library(ggsci)
ggplot(df1, linetype = F) +
  scale_color_jama(name = "Model Type", labels = c("Cox 1""Cox 2",
                                                   "All""None")) +
  theme_bw(base_size = 14) +
  theme(
    legend.position = c(0.8, 0.75),
    legend.background = element_blank()
  )
##----款式4 ??ggscidca包 ----
##install.packages("ggscidca")
pacman::p_load(survival, reshape2, ggplot2, do, foreign, cmprsk, ggscidca)
#----1???? 单DCA带色带
cox_fit1 <- coxph(Surv(ttcancer, cancer) ~ marker + famhistory, data = df_surv)
cox_fit2 <- coxph(Surv(ttcancer, cancer) ~ cancerpredmarker, data = df_surv)
scidca(cox_fit1, newdata= df_surv,timepoint=1)

#----2?? 多DCA
#对每个模型的数据定义,生成列表
newdat<-list(df_surv,df_surv)
#默认不加timepoint,中位数0.584479
summary(df_surv$ttcancer)
##cox.tcdca(cox_fit1,cox_fit2, newdata=newdat) 
#=timepoint=0.584479
cox.tcdca(cox_fit1,cox_fit2,newdata=newdat,timepoint=1)

五、pt阈值

ggscidca包会自动生成pt阈值和色带。其他R包没有提供。pt阈值是否一定要由dca过程自动计算值得商榷,且计算中要考虑拖尾噪音问题,文献中着重强调的是临床经验获取


六、A款课程智荟款式

我提供了修复代码与案例复原代码完全讲解版都在,A款课程,点我上课

小狐狸也有爱的提供了智荟款dca+CIC+色带图心得。智荟顶刊复现特色款美图如下。

小结

Dca曲线分时间关联,以及联合pt阈值和CIC影响曲线。R包推荐stdca.r、dcurves包,ggdca与ggscidca需要修复bug与形态问题。 

正确且最美的还是智荟款式dca

拓展

A款课程,点我上课,已经不知不觉走过了将近10个月,目前讲解预测模型系列。目前讲解的课程极度丰富,细节拉满,课件精美,口碑爆炸!

课程适合任意科研数据设计、公共数据库后期分析套路。感兴趣的小伙伴可以进群或课程深入学习。例如临床预测模型思维导图如下。

课程总结顶刊套路roc、pr曲线、校准曲线等款式新颖全面如下。


另外,我们的C款SCI写作课, 跟着大佬从0开始到顶刊,正式开启了!

这周上了第一堂课。AC老师极度认真负责的手把手传授经验,感兴趣的小伙伴也可以关注一波。



本公众号建立了学术交流群(群6),仅供SCI统计分析交流,人数有限需要实名制。入群请加笔者微信 popnie请备注说明:姓名-学校(单位)-专业