列线图什么鬼?听说它能把logistic结果变得更易看懂?!

经验

  作者:麦子

  转载请注明:解螺旋·临床医生科研成长平台

  诺莫图(Nomogram)又称列线图(Alignment Chart),是把数学公式画成图的表达方法,我好像只能解释到这了……

  不管了,先看个例子,来自Lancet Neurol. 2017 Jul;16(7):532-540.

  这是收集了900多例轻度外伤性脑损伤(mTBI)患者的几个临床信息,如图第二行开始,包括教育程度、精神健康状况、饮酒史等等,一直到Total Points以上。结局指标为6个月后是否完全康复(GOSE评分≤7为不完全,GOSE=8为完全)。

  然后做个logistic回归,建立模型,通过这几个指标预测不完全康复的风险。一般我们做logistic也就是想看看哪几个指标对结局影响比较大,但具体到患者个人来说,我有个高风险指标,但我怎么知道发生结局事件的风险是多少呢?

  这时就可以通过这种图来计算,取得那几个指定的临床信息(自变量)后,从该自变量的坐标轴向顶部的points轴作一条垂直线,得到对应的point,第个自变量的point相加得到总分,在下方的total points上找到对应的值,向下边的linear predictor(线性预测值)再作一条垂直线,即得到发生结局事件的风险,更有临床应用的价值。

  这个线性预测跟我们熟悉的风险概率不太一样,但其实可以转换的。

  纪念斯隆凯特琳癌症研究所好像特别推崇这种方法,建立了好几种癌症的预测模型,而这种表达方式也渐渐在各大期刊流行起来。想学不?正好这里有一篇新鲜教程,由浙大医学院和克利夫兰医学基金会的老师们合作发表(Ann Transl Med. 2017 May; 5(10): 211.),一起来研习一下吧。

  载入所需要的包

  library(rms)

  这个包还需预先载入Hmisc、survival、Formula、ggplot2,如果系统没有自动载入,还请自行手动安装并载入。

  构建示例数据

  这段大概看一下知道数据是怎么来的就行了,反正你的实验数据是不需要构建的。

  

  接下来看看生成的表格,数据结构是这个样子(显示部分):

  年龄和乳酸水平为连续变量,性别为二元变量,卒中为分类变量,有四个level,分别为No、Mild、Moderate(未展示)、Severe。结局指标y为二元变量,1表示死亡。接下来用logistic回归,通过三个自变量预测死亡风险。

  打包数据

  ddist <- datadist(data)

  options(datadist = 'ddist')

  因为我们不仅是要做logistic回归,还要做列线图,这一步是专为列线图而设的。用datadist()定义各变量的分布,再把它们包到options()中。运行ddist可以看到输出结果:

  包含各变量的描述信息,范围。一会作图就会默默地使用这些值。

  Logistic回归

  mod <- lrm(y~shock+lac*sex+age,data)

  “~”前面是结局,后面是自变量,各自变量用+相连。乳酸一项需要根据性别分层,所以乳酸和性别用*号,后面的data是用到的数据集。

  设置列线图参数

  nom <- nomogram(mod,

  lp=T,

  lp.at = seq(-3,4,by=0.5),

  fun=function(x) 1/(1+exp(-x)),

  funlabel = 'Risk of Death',

  fun.at = c(0.05,seq(0.1,0.9,by=0.1),0.95),

  conf.int = c(0.1,0.7))

  第一行mod就是刚才logistic回归的模型名称。Lp选择True或False,是否显示线性预测坐标(linear predictor),lp.at则是设置其坐标轴的范围,此处就是从-3到4,每个刻度为0.5。

  fun是要自己设一个函数,对lp进行转换,并建立一个新坐标轴。此处就用logit变换的反函数,将lp转换为我们熟悉的风险概率-。function(x) 1/(1+exp(-x))这一串,即使用function()构建一个自定义函数,括号中的x从lp的范围中取值,代入1/(1+exp(-x))中运算。

  fun.at则是给新的坐标轴设置范围。本例中,lp的最小值是-3,对应的死亡风险是0.0474,所以起始值要大于这个值才能显示,不落在其范围内的都是不会显示的。

  funlabel则是给上面转换好的新坐标轴起个名字,Risk of Death。其实有了这条坐标轴,上面lp那里也可以设为F,不显示了。但即使不显示,lp.at还是要设置,否则光设后面的fun.at似乎是无效的。

  conf.int展示每个自变量坐标轴上各刻度的置信区间,这里显示两层置信区间,即0.1和0.7。默认是F,即不显示。其实好多文章都不显示,你可以多学一招。

  出图

  plot(nom,

  lplabel = 'Linear Predictor',

  fun.side = c(1,1,1,1,3,1,3,1,1,1,1),

  label.every = 3,

  col.conf = c('red','green'),

  conf.space = c(0.1,0.5),

  col.grid = gray(c(0.8,0.95)),

  which='shock')

  用plot()作图。nom是刚才定义的所有参数对象的名字,lplabel是lp坐标轴的名称,如果刚才lp选了F,这行也可以不要了。

  fun.side是设置新坐标轴“Risk of Death”的坐标刻度显示在哪一边,1表示下方,3为上方。不写则默认下方,但当空间比较窄,刻度密集时,可以把几个刻度放到上面。刚才fun.at设了几个刻度,这里的fun.side就要设几个值。数不清的话,可以把fun.at那一行单独选中运行一次,然后运行length(fun.at)查看。

  label.every也是这个意思,刻度每3个显示1个,拒绝密恐。

  col.conf设置置信区间的颜色。传说“红配绿赛狗屁”不是没有道理,忘了是Nat Commum.还是哪个杂志来着,建议作者们不要使用红绿配色,照顾色盲同学。。。

  conf.space是设置刚才那些置信区间条在两条坐标轴之间的位置,两轴之间的距离为1,现在设成0.1~0.5之间,虽然设了看起来不精确,但不设会压成一团。

  col.grid设置垂直参考线的颜色,从自变量轴指向point轴。一般设2个,表示主要和次要刻度。此处表示灰色的0.8透明度和0.95透明度,你也可以设成其他颜色,格式同上面的红配绿。

  终于看到图了!

  是不是比那个Lancet Neurology的例子还丰富一些^_^

  列线图不仅能画出logistic模型,我们常用的cox模型、生存模型等等都可绘制,有兴趣的同学可参考原教程,应该能触类旁通了~

  参考文献:

  1.Early predictors of outcome after mild traumatic brain injury (UPFRONT): an observational cohort study

  2.Drawing Nomograms with R: applications to categorical outcome and survival data

声明:本文由入驻搜狐公众平台的作者撰写,除搜狐官方账号外,观点仅代表作者本人,不代表搜狐立场。
推荐阅读