百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

文献解析:生存数据和分类结局列线图的做法,史上最全

bigegpt 2024-10-30 01:48 9 浏览

今天给大家分析一篇文献,作者是浙大邵逸夫医院的章仲恒副主任,论文的主要内容就是教大家怎么画列线图。写的比较详细,拜读之后顺手写个粗浅的解析分享给大家,依然还是建议大家去看原文哦,论文题目见文章最后。

全文包括2分类逻辑斯蒂回归,多分类逻辑斯蒂回归,生存分析的列线图的画法和解析,基本上涵盖了临床上常用的预测方法,所以很值得大家收藏

接下来我一个一个给大家解析

作者先模拟了一个数据集,大概长这样:

这个数据集有1000个个案,6个变量,其中age和lac都是正态分布的连续自变量,sex和shock为因子,y是二分类结局,Y是多分类结局(3分类),所以我们如果用y做结局,就是拟合一个二分类逻辑斯蒂回归,用Y做结局就是多分类逻辑斯蒂回归。接下来我们一个一个看:

二分类结局的列线图画法

画列线图用到的包是rms。

第一步我们需要用datadist()函数来得到预测变量的分布,以此来规定我们的图形的尺度,紧接着拟合我们的逻辑回归模型(用到的函数为lrm),代码如下:

ddist <- datadist(data)
options(datadist='ddist')
mod.bi<-lrm(y~shock+lac*sex+age,data)

模型拟合好了之后,我们把这个模型直接喂给nomogram函数就行,代码如下:

nom.bi <- nomogram(mod.bi,          
											lp.at=seq(-3,4,by=0.5),
                     fun=function(x)1/(1+exp(-x)),
                     fun.at=c(.001,.01,.05,seq(.1,.9,by=.1),.95,.99,.999),
                     funlabel="Risk of Death",
                     conf.int=c(0.1,0.7),
                     abbrev=TRUE,
                     minlength=1,lp=F)

plot(nom.bi,lplabel="Linear Predictor",
     fun.side=c(3,3,1,1,3,1,3,1,1,1,1,1,3),
     col.conf=c('red','green'),
     conf.space=c(0.1,0.5),
     label.every=3,
     col.grid = gray(c(0.8, 0.95)),
     which="shock")

运行上面的代码即可得到下面的列线图:

上面的代码中我们自行设定了部分参数,需要给大家写写都是什么意思,首先是lp.at=seq(-3,4,by=0.5)表示我们的自变量的线性组合只在-3到4的范围内以步长为0.5进行显示,不过奇怪的是作者设置了这个参数,又把lp设置为F(就是不显示预测变量的线性组合值),所以作者在上面的代码中设置这个完全是没有必要的,如果我们将lp参数改为T则可看到预测变量的线性组合结果,效果如下:

然后是fun这个参数,因为我们的结局是二分类的,这个分类是通过连接函数得到的,我们的预测变量的线性组合直接得到的其实是log odds(看不明白的同学请看之前关于逻辑回归机器学习的文章),我们这儿其实想要的是某一类的概率,所以就用了一个反logit转换,目的是为了得到每一类的概率p,具体,代码中我们将参数fun设定为function(x)1/(1+exp(-x)),其实写成fun=plogis也是可以的,这个plogis就是逻辑斯蒂的累计分布函数(Logistic Cumulative Distribution Function (plogis Function))

为了更好地给大家说明,这儿给大家做个演示,运行如下代码大家就可以看到逻辑斯蒂的累计分布函数长啥样:

x_plogis <- seq(- 10, 10, by = 0.1) 
y_plogis <- plogis(x_plogis) 
plot(y_plogis) 

看到没,纵轴就是我们想要的p,这个就是通过反logit转换得到p的原理,好好体会哈。

其实逻辑回归在做的就是把自变量的线性组合通过连接函数映射到上面这个图上(就是得到p)从而达到对2分类结局分类的目的,在做列线图的时候我们也得把这个东西以fun参数的形式给指出来,不然它就不会对自变量进行转换,出来的概率就是错误的,转换就是通过fun这个参数实现的。

再看fun.at参数,这个参数是设定函数轴的标签的,我们将其设定为fun.at=c(.001,.01,.05,seq(.1,.9,by=.1),.95,.99,.999)就是希望如果自变量的组合会导致这些值的话,就会在相应的地方打上标签,因为我们自变量的线性组合最小为-3其对应的p为0.0474,所以在途中标签是从0.05开始的;funlabel参数是用来规定轴的名字的。conf.int参数用来设定变量的confidence levels,默认不显示。

接下来看看plot函数中的几个参数:lplabel用来设定预测变量线性组合的标签,fun.side用来设定fun刻度值标签的上下位置,防止重叠;col.conf给置信水平上颜色;conf.space规定置信轴的垂直位置;label.every=3意思是轴的每3个值打一个标签;方便我们对齐的垂直轴的颜色可以通过col.grid调节。

有序结局变量的列线图画法

有序逻辑斯蒂回归也是用lrm()函数进行拟合的,代码如下:

mod.ord <- lrm(Y ~ age+rcs(lac,4)*sex)

上面的代码中拟合了加了限制性样条的sex和lac的交互项(之后会给大家写什么是样条,本篇文章略过)。

为了更好地给大家解释有序逻辑回归,我们先看看有序逻辑回归的模型表达:

我们在做有序逻辑回归的时候,比如我们的结局变量有4个水平,这个时候我们会同时拟合3个二分逻辑模型(下图中的1,2,3),我们始终是有一个参考水平的,解释的时候依然和二分逻辑回归一样的解释:

比如我们的例子中,我们就会同时拟合如下3个模型,第1个模型回答了个案是不是大于第1类,第二个模型回答了是不是大于第二类,第3个模型回答了是不是大于第3类,这样就穷尽了所有的可能性。

相应地,我们的概率p也得有三个:

fun2 <- function(x) plogis(x-mod.ord$coef[1]+mod.ord$coef[2])
fun3 <- function(x) plogis(x-mod.ord$coef[1]+mod.ord$coef[3])

以上就规定好了出图时的自变量线性组合的转换方法,接着就可以出图了,代码为:

nom.ord <- nomogram(f, fun=list('Prob Y>=1'=plogis,
                                'Prob Y>=2'=fun2,
                                'Prob Y=3'=fun3),
                    lp=F,
                    fun.at=c(.01,.05,seq(.1,.9,by=.1),.95,.99))
plot(nom.ord, lmgp=.2, cex.axis=.6)

因为我们的模型中是有交互的,是lac和sex交互,其中sex是有两个水平,那么我们出来的列线图就会在sex的两个水平分别画出lac,于是我们做出来的列线图就是下面这个样子的:

我们有看到,在列线图中结局Y不同顺序的概率都有出现,通过这个列线图就可以很方便地得到某个个案到底处于结局变量的哪个水平的概率最大了。

生存分析的列线图

对于生存数据我们可以用半参数模型和参数模型进行建模(见我之前的文章),在生存分析中我们一般会感兴趣特定时点的生存概率和中位生存期,当然啦,这些模型都是可以通过列线图进行可视化的。

首先我们需要拟合生存模型,用到的是psm函数,本例中我们用到的数据长这样:

需要用到的变量是(time,status,ph.ecog,sex和age,其中ph.ecog是病人日常活动功能的一个指标。我们现在就拟合一个模型来研究ph.ecog对病人生存的影响,将sex和age当作协变量,代码如下:

 mod.sur <- psm(Surv(time,status) ~ ph.ecog+sex+age,
 data, dist='weibull')

然后我们可以用下面的代码得到病人的中位生存期和生存概率:

med <- Quantile(mod.sur)
surv <- Survival(mod.sur)
ddist <- datadist(lung)

到这儿,我们画图需要的东西就全部准备好了,接下来进行出图,首先是以生存期为结局的图:

nom.sur1<-nomogram(mod.sur,
                   fun=list(function(x) med(lp=x, q=0.5),
                            function(x) med(lp=x,q=0.25)),
                   funlabel=c("Median Survival Time",
                              "1Q Survival Time"),
                   lp=F)
plot(nom.sur1,
     fun.side=list(c(rep(1,7),3,1,3,1,3),rep(1,7)),
     col.grid = c("red","green"))

运行代码就可以得到下面的图啦:

可以看到我们的结局变量有两,分别是中位生存期和第一四分位生存期,因为我们定义fun的时候是定义了两嘛。

接下来是以生存概率为结局进行出图,代码如下:

nom.sur2 <- nomogram(mod.sur, fun=list(function(x)surv(200, x),
  function(x) surv(400, x)),
  funlabel=c("200-Day Survival Probability",
             "400-Day Survival Probability"),
  lp=F)

上面的代码分别定义了随访200天和400天时病人的生存概率,也就是我们的结局,接下来就用plot函数出图了,代码如下:

plot(nom.sur2,
     fun.side=list(c(rep(c(1,3),5),1,1,1,1),
                   c(1,1,1,rep(c(3,1),6))),
     xfrac=.7,
     col.grid = c("red","green"))

代码中的xfrac参数是用来规定轴标签和图距离的哈,运行代码就可以得到下面的列线图:

半参生存分析

半参生存分析其实就是比例风险模型,为什么叫半参呢,这儿再给大家补习一下:

A parametric survival model is one in which survival time (the outcome) is assumed to follow a known distribution. Examples of distributions that are commonly used for survival time are: the Weibull, the exponential (a special case of the Weibull), the log-logistic, the log-normal, etc.

The Cox proportional hazards model, by contrast, is not a fully parametric model. Rather it is a semi-parametric model because even if the regression parameters (the betas) are known, the distribution of the outcome remains unknown. The baseline survival (or hazard) function is not specified in a Cox model (we do not assume any shape or form).

我们依然是先拟合模型,以ph.ecog为i变量并控制sex和age,比例风险模型的拟合用的是cph()函数,本例中代码如下:

mod.cox <- cph(Surv(time,status) ~ ph.ecog+sex+age,
               lung, surv=TRUE)

接下来是出图前的准备(注意看fun参数):

ddist <- datadist(lung)
options(datadist='ddist')
surv.cox <- Survival(mod.cox)
nom.cox <- nomogram(mod.cox, fun=list(function(x)
  surv.cox(200, x),
  function(x) surv.cox(400, x)),
  funlabel=c("200-Day Sur. Prob.",
             "400-Day Sur. Prob."),
  lp=F)

然后出图:

plot(nom.cox,
fun.side=list(c(rep(c(1,3),5),1,1,1,1),
c(1,1,1,rep(c(3,1),6))))

运行代码即可做出如下的列线图:


通过上图就可以很方便地得到某个病人200天和400天时的生存概率了,好了,以上就是论文的所有内容,就给大家解析到这儿,希望对做列线图的同学有用。

论文原文:Zhang, Z., & Kattan, M. W. (2017). Drawing Nomograms with R: applications to categorical outcome and survival data. Annals of translational medicine, 5(10).

小结

今天给大家写了临床常见预测模型的列线图的做法,感谢大家耐心看完,自己的文章都写的很细,代码都在原文中,希望大家都可以自己做一做,请关注后私信回复“数据链接”获取所有数据和本人收集的学习资料。如果对您有用请先收藏,再点赞转发。

也欢迎大家的意见和建议,大家想了解什么统计方法都可以在文章下留言,说不定我看见了就会给你写教程哦,另,咨询代做请私信。

如果你是一个大学本科生或研究生,如果你正在因为你的统计作业、数据分析、论文、报告、考试等发愁,如果你在使用SPSS,R,Python,Mplus, Excel中遇到任何问题,都可以联系我。因为我可以给您提供好的,详细和耐心的数据分析服务。

如果你对Z检验,t检验,方差分析,多元方差分析,回归,卡方检验,相关,多水平模型,结构方程模型,中介调节,量表信效度等等统计技巧有任何问题,请私信我,获取详细和耐心的指导。

If you are a student and you are worried about you statistical #Assignments, #Data #Analysis, #Thesis, #reports, #composing, #Quizzes, Exams.. And if you are facing problem in #SPSS, #R-Programming, #Excel, Mplus, then contact me. Because I could provide you the best services for your Data Analysis.

Are you confused with statistical Techniques like z-test, t-test, ANOVA, MANOVA, Regression, Logistic Regression, Chi-Square, Correlation, Association, SEM, multilevel model, mediation and moderation etc. for your Data Analysis...??

Then Contact Me. I will solve your Problem...

猜你喜欢

R数据分析:列线图的做法及解释

R数据分析:手把手教你画列线图(Nomogram)及解读结果

R数据分析:Lasso回归筛选变量构建Cox模型并绘制列线图

相关推荐

悠悠万事,吃饭为大(悠悠万事吃饭为大,什么意思)

新媒体编辑:杜岷赵蕾初审:程秀娟审核:汤小俊审签:周星...

高铁扒门事件升级版!婚宴上‘冲喜’老人团:我们抢的是社会资源

凌晨两点改方案时,突然收到婚庆团队发来的视频——胶东某酒店宴会厅,三个穿大红棉袄的中年妇女跟敢死队似的往前冲,眼瞅着就要扑到新娘的高额钻石项链上。要不是门口小伙及时阻拦,这婚礼造型团队熬了三个月的方案...

微服务架构实战:商家管理后台与sso设计,SSO客户端设计

SSO客户端设计下面通过模块merchant-security对SSO客户端安全认证部分的实现进行封装,以便各个接入SSO的客户端应用进行引用。安全认证的项目管理配置SSO客户端安全认证的项目管理使...

还在为 Spring Boot 配置类加载机制困惑?一文为你彻底解惑

在当今微服务架构盛行、项目复杂度不断攀升的开发环境下,SpringBoot作为Java后端开发的主流框架,无疑是我们手中的得力武器。然而,当我们在享受其自动配置带来的便捷时,是否曾被配置类加载...

Seata源码—6.Seata AT模式的数据源代理二

大纲1.Seata的Resource资源接口源码2.Seata数据源连接池代理的实现源码3.Client向Server发起注册RM的源码4.Client向Server注册RM时的交互源码5.数据源连接...

30分钟了解K8S(30分钟了解微积分)

微服务演进方向o面向分布式设计(Distribution):容器、微服务、API驱动的开发;o面向配置设计(Configuration):一个镜像,多个环境配置;o面向韧性设计(Resista...

SpringBoot条件化配置(@Conditional)全面解析与实战指南

一、条件化配置基础概念1.1什么是条件化配置条件化配置是Spring框架提供的一种基于特定条件来决定是否注册Bean或加载配置的机制。在SpringBoot中,这一机制通过@Conditional...

一招解决所有依赖冲突(克服依赖)

背景介绍最近遇到了这样一个问题,我们有一个jar包common-tool,作为基础工具包,被各个项目在引用。突然某一天发现日志很多报错。一看是NoSuchMethodError,意思是Dis...

你读过Mybatis的源码?说说它用到了几种设计模式

学习设计模式时,很多人都有类似的困扰——明明概念背得滚瓜烂熟,一到写代码就完全想不起来怎么用。就像学了一堆游泳技巧,却从没下过水实践,很难真正掌握。其实理解一个知识点,就像看立体模型,单角度观察总...

golang对接阿里云私有Bucket上传图片、授权访问图片

1、为什么要设置私有bucket公共读写:互联网上任何用户都可以对该Bucket内的文件进行访问,并且向该Bucket写入数据。这有可能造成您数据的外泄以及费用激增,若被人恶意写入违法信息还可...

spring中的资源的加载(spring加载原理)

最近在网上看到有人问@ContextConfiguration("classpath:/bean.xml")中除了classpath这种还有其他的写法么,看他的意思是想从本地文件...

Android资源使用(android资源文件)

Android资源管理机制在Android的开发中,需要使用到各式各样的资源,这些资源往往是一些静态资源,比如位图,颜色,布局定义,用户界面使用到的字符串,动画等。这些资源统统放在项目的res/独立子...

如何深度理解mybatis?(如何深度理解康乐服务质量管理的5个维度)

深度自定义mybatis回顾mybatis的操作的核心步骤编写核心类SqlSessionFacotryBuild进行解析配置文件深度分析解析SqlSessionFacotryBuild干的核心工作编写...

@Autowired与@Resource原理知识点详解

springIOCAOP的不多做赘述了,说下IOC:SpringIOC解决的是对象管理和对象依赖的问题,IOC容器可以理解为一个对象工厂,我们都把该对象交给工厂,工厂管理这些对象的创建以及依赖关系...

java的redis连接工具篇(java redis client)

在Java里,有不少用于连接Redis的工具,下面为你介绍一些主流的工具及其特点:JedisJedis是Redis官方推荐的Java连接工具,它提供了全面的Redis命令支持,且...