6. 临床预测模型——可视化列线图

基本原理:

根据多因素模型中各自变量的偏回归系数的大小,给每个自变量进行赋分,然后将各个自变量评分相加得到总评分,根据总评分估计出个体结局事件的预测情况。

列线图包括三个部分:

  • 用于预测模型的自变量:线段长短表示对因变量的贡献
  • 自变量相应的得分:列线图最上方的points表示每个自变量取不同值时对应的得分。
  • 总得分

连续型资料

load("prostate.Rdata")
prostate$svi<-factor(prostate$svi,levels = c(0,1),labels = c("No","Yes"))

library(rms)
dd <- datadist(prostate)
options(datadist='dd')

利用rms包中datadist()函数对prostate数据集进行打包,然后options()函数中指定打包完的dd,便于后续调用分析。

1.静态列线图

form.stepwise<-as.formula(lpsa~age+lbph+lweight+svi+lcavol)
fit.lm<-ols(formula=form.stepwise,data=prostate,x=TRUE,y=TRUE)
nom.lm <- nomogram(fit.lm,lp=TRUE)

逐步法后最终纳入age+lbph+lweight+svi+lcavol这几个变量。as.formula()函数生成模型公式,储存到form.stepwise中。ols()函数拟合模型,x,y=TRUE。

nomogram()函数中输入模型的名称fit.lm,lp表示是否显示线性概率。

plot(nom.lm,lplabel = 'Predicted value of lpsa',
     cex=1.3,
     cex.axis=1.3,
     cex.lab=1.3)

lplabel表示线性预测值坐标轴名称。

nom.lm

直接显示各自变量取不同值对应的准备points

lpsa每增加一个单位,points增加33.4,每增加1分,lpsa增加0.0299

如果需要具体的换算函数:

#install.packages("nomogramEx")
library(nomogramEx)
nomogramEx(nom.lm,np=1)

np=1表示预测的因变量只有1个

静态列线图的变种
nom3.lm <- nomogram(fit.lm, 
                 lp=TRUE,
                 conf.int = c(0.1,0.9),
                 maxscale=100) 

plot(nom3.lm,
     lplabel = 'Predicted value of lpsa',
     col.grid = c("blue","yellow"),
     col.conf = c('red','green'),
     conf.space = c(0.1,0.5),
     cex=1.3,
     cex.axis=1.3,
     cex.lab=1.3)

lp表示是否显示线性预测值,conf.int这只points的置信区间,这里设置为10%,90%,选项maxscale设置points最大刻度为100。

col.grid设置垂直参考线的颜色,col.conf设置置信区间的颜色。10%的颜色为红色,90%为green。conf.space设置置信区间条在两条坐标轴之间的位置

2.网页动态列线图

#install.packages("DynNom")
library(DynNom)
fit2.lm <- lm(formula=form.stepwise,data=prostate)
DynNom(model=fit2.lm, 
       DNtitle="Nomogram", 
       DNxlab = "Predicted value of lpsa")

Numerical Summary窗口会显示具体的数值结果

3. 花样列线图

#install.packages("regplot")
library(regplot)
nom2.lm<-regplot(fit2.lm, 
              observation = prostate[1,], 
              interval = "confidence",
              center=TRUE, 
              title="Nomogram",
              points=TRUE, 
              showP=TRUE, 
              rank="sd",
              clickable=FALSE)

observation指定将数据集prostate中的第一个观测对象的具体情况在图形上显示出来。

interval设置为confidence表示在图上显示预测值的可信区间。

Center=TRUE表示将每个变量的Points不从0开始,FALSE表示从0开始。

showP=T表示显示各变量是否存在统计学差异,如果有差异*标记。

rank=“sd”表示对各个变量回归系数的SD数值大小排序。

clickable=F表示不进行图片的后续编辑。

连续型变量中频数分布曲线展现其数值的分布情况,分类变量方块的大小展现其分布情况,方块越大,该水平的人数越多。红色区域为第一个观测对象的情况,总分208,对应的lpsa为0.8458。

二分类资料

1.静态列线图

案例:680名研究对象,研究肺动脉栓塞风险。

library(readxl)
data <- read_excel("data.xlsx")
data<-na.omit(data)
data<-as.data.frame(data)

na.omit()对数据集中data中的缺失值进行删除。

对分类变量进行因子化

data$CDU<-factor(data$CDU,levels = c(0,1),labels = c("Normal","Abnormal"))
data$transfusion<-factor(data$transfusion,levels = c(0,1),labels = c("No","Yes"))
data$stage<-factor(data$stage,levels = c(0,1),labels = c("<IIb",">=IIb"))

绘制列线图

library(rms)
dd=datadist(data) #对数据集data进行打包
options(datadist="dd") #指定打包完的dd

group表示结局,是否有动脉栓塞?

form.bestglm<-as.formula(group~age+BMI+ToS+CA153+CDU+transfusion+stage)
fit.glm<- lrm(formula=form.bestglm,data=data)  
nom.glm <- nomogram(fit.glm,
                 fun=function(x)1/(1+exp(-x)),  
                 lp=TRUE, 
                 fun.at=c(0.1,0.3,0.5,0.7,0.9),
                 funlabel="Risk")

plot(nom.glm,cex=1.3,
     cex.axis=1.3,
     cex.lab=1.3)
nom.glm 

fun指定线性概率值究竟是如何转换,由于是logstic模型,应该进行Logit转换,即function(x)1/(1+exp(-x))。

lp表示是否显示线性概率值;

fun.at设置坐标轴刻度;

funlabel设置坐标轴名称。

详细的换算公式:

library(nomogramEx)
nomogramEx(nom.glm,np=1)

2. 网页动态列线图

library(DynNom)
dat=data
fit2.glm <- glm(formula=form.bestglm,data = dat, family = binomial())
DynNom(fit2.glm, DNtitle="Nomogram", DNxlab = "Probability")

family指定因变量为二分类,注意区别于连续型变量,连续型变量使用的是lm()函数,二分类变量资料用的是glm()函数,其他格式相同。

3. 花样列线图

form.bestglm<-as.formula(group~age+BMI+ToS+CA153+CDU+transfusion+stage)
fit.glm<- lrm(formula=form.bestglm,data=data) 
library(regplot)
nom2.glm <- regplot(fit.glm, 
                observation=data[1,], 
                center=TRUE, 
                title="Nomogram",
                points=TRUE, 
                odds=FALSE, 
                showP=TRUE, 
                rank="sd",
                clickable=FALSE) 
nom2.glm

使用lrm()函数拟合的模型fit.glm。center=TRUE表示将每个变量的points设置为不从0开始。

生存资料

案例:原发性胆汁性肝硬化的生存分析研究

1.静态列线图

load("pbc.Rdata")
#对分类变量进行因子化
pbc$edema<-factor(pbc$edema,levels = c(0,1),labels = c("No","Yes"))
pbc$stage<-factor(pbc$stage,levels = c(1,2,3,4),labels = c("Ⅰ","Ⅱ","Ⅲ","Ⅳ"))
#对数据集进行打包
library(rms)
dd<-datadist(pbc)
options(datadist='dd'

根据最优子集法筛选出自变量

form.bestcox<-as.formula(Surv(days,status)~age+edema+bili+albumin+copper+sgot+
                                 trig+platelet+prothrombin+stage)
fit.cox<-cph(formula = form.bestcox, data = pbc,surv = T,x=TRUE,y=TRUE)

surv=T,为了方便后面生成生存函数。根据模型fit.cox设置生存函数,利用Survival()构造生存函数。

surv <- Survival(fit.cox)

设置不同时间点的生存函数

surv1 <- function(x)surv(1*365,lp=x)  
surv3 <- function(x)surv(3*365,lp=x)  
surv5 <- function(x)surv(5*365,lp=x) 
surv10 <- function(x)surv(10*365,lp=x) 

这里设置了1年,3年,5年和10年的生存函数

nom.cox<-nomogram(fit.cox,  
              fun=list(surv1,surv3,surv5,surv10),  
              lp= TRUE,  
              funlabel=c('1-Year Survival prob.',
                         '3-Year survival prob.',
                         '5-Year survival prob.',
                         '10-Year survival prob.'), 
              maxscale=100, 
              fun.at=c('0.99','0.9','0.7','0.5','0.3','0.1','0.01')) 

plot(nom.cox,cex.axis=1.2,
     cex.lab=1.2)

fun指定线性概率函数如何转化,这里设置为4个时间点的生存函数,将其用list()连接起来。IP表示是否显示线性概率值,funlabel表示4个时间点的坐标轴名称。

具体换算关系:

library(nomogramEx)
nomogramEx(nom.cox,np=4)

np=4表示预测的因变量有4个,1年,3年,5年,10年。

 预测生存概率列线图

1.中位生存时间

med <- Quantile(fit.cox)
med.surv <- function(x)med(lp=x,q=0.5)
nom5.cox <- nomogram(fit.cox,
                     fun=med.surv, 
                     lp=TRUE,
                     funlabel=c('中位生存时间')) 
plot(nom5.cox,cex.axis=0.8,
     cex.lab=0.8)
nom5.cox

 此处表示有中位人数生存的时间,即在55-60区间内,有一半的人存活。

2. 90%的生存时间

Quan_tile<-Quantile(fit.cox)
Quantile.surv<-function(x)Quan_tile(lp=x,q=0.9)
nom5.cox <- nomogram(fit.cox,
                 fun=Quantile.surv, 
                 lp=TRUE,
                 funlabel=c('90% Survival Time'),
                 maxscale=100) 

plot(nom5.cox,cex.axis=1.3,
     cex.lab=1.3)
nom5.cox

 

2.网页动态列线图

library(DynNom)
DynNom(fit.cox, DNtitle="Nomogram", DNxlab = "Probability")

3. 花样列线图

生存概率
library(regplot)
nom2.cox <- regplot(fit.cox, 
                observation=pbc[2,], 
                failtime=c(1832,2832),
                center=TRUE, 
                title="Nomogram",
                points=TRUE, 
                odds=FALSE, 
                showP=TRUE, 
                rank="sd",
                clickable=FALSE) 
nom2.cox

observation表示将第二个观测值显示出来;

failtime设置观察第1832天的生存概率,第2832天的生存概率。

center=T表示将每个变量的points设置为不从0开始,Odds=F表示不显示Odds;

rank=“sd” 表示按照sd大小排序

图中红色的点为第二个观测值的情况。总评分为311, 生存小于2832天的概率为0.189,生存小于1832天的概率为0.0906。

注意:

对于Total points与生存概率的关系,输出结果只显示了regplot()函数中选项failtime设置的第一个时间点,未显示其他时间点的结果。如果需要了解其他时间点的情况,可以在regplot()函数拟合模型时,选项failtime每次只设置1个时间点。由于Points涉及四舍五入,Total points对应的生存概率轻微偏离真实值。

生存时间
nom3.cox <- regplot(fit.cox, 
                    observation=pbc[2,], 
                    failtime=c("10%"),
                    center=TRUE, 
                    title="Nomogram",
                    points=TRUE, 
                    odds=FALSE, 
                    showP=TRUE, 
                    rank="sd",
                    clickable=FALSE)

估计何时研究对象的生存概率未10%。

补充:不同lm()函数的意义

glm 函数适用于广义线性模型,可以处理多种类型的响应变量,如二项式、泊松分布等,非常适合于多样化的数据集。相反,lrm 函数专门用于逻辑回归模型,主要处理二元响应变量,例如在二分类问题中表现得更为出色。

如果数据集涉及非二元响应变量或需要广义线性模型的灵活性,应选择 glm。对于明确的二分类问题,lrm 更为合适。

lm()函数:

用拟合普通最小二乘(OLS)线性回归模型的主要函数。OLS回归用于估计因变量和自变量之间的线性关系。适用于连续型变量和线性回归的条件。lrm()本质是lm()用于绘制列线图

glm()函数:

用于拟合广义线性模型(GLM)函数。GLM是对线性模型的拓展,适用于因变量不满足正态分布或具有非连续型的情况。

### 回答1: Java中有八种基本数据类型,分别是byte、short、int、long、float、double、char、boolean。String不是基本类型数据,它是一个类。String类不能被继承,因为它被声明为final类。 ### 回答2: Java中的基本数据类型包括:byte、short、int、long、float、double、boolean和char这八种类型。这些数据类型是用来存储基本数据的,每种类型都有固定的取值范围和默认值。 String不是基本数据类型,它是Java中的引用数据类型。String表示字符串,用于存储文本类型的数据。在Java中,String类提供了许多方法来操作字符串,例如连接、截取、查找等,这些方法使得处理字符串变得更加方便。 String类是Java中的最终类,这意味着它不能被其他类继承。最终类是不能被其他类所继承的类,它的设计初衷是为了防止被修改或影响。因此,String类不能被继承,不能有子类。但是,我们可以使用String类创建对象并调用它的方法来进行字符串的操作。 ### 回答3: Java中的基本数据类型包括:整型(int)、浮点型(float和double)、字符型(char)、布尔型(boolean)。 String不是基本数据类型,它是引用类型。在Java中,String是一个类,用于表示字符串类型的数据。它可以用来存储任意长度的字符序列。 在Java中,String类是不可继承的,它被设计成了final类,即无法被其他类继承。这是因为String类在Java中用途非常广泛,涉及到字符串的不可变性和安全性等方面考虑。通过将String类设置为final类,可以避免由于继承导致的不可控制的数据访问和修改,确保字符串对象的一致性和稳定性。即使不能继承String类,我们仍然可以通过创建String类的新实例来使用它的方法和属性。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值