QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3173|回复: 0
打印 上一主题 下一主题

[其他资源] 净重新分类指数NRI的计算

[复制链接]
字体大小: 正常 放大
杨利霞        

5273

主题

82

听众

17万

积分

  • TA的每日心情
    开心
    2021-8-11 17:59
  • 签到天数: 17 天

    [LV.4]偶尔看看III

    网络挑战赛参赛者

    网络挑战赛参赛者

    自我介绍
    本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。

    群组: 2018美赛大象算法课程

    群组: 2018美赛护航培训课程

    群组: 2019年 数学中国站长建

    群组: 2019年数据分析师课程

    群组: 2018年大象老师国赛优

    跳转到指定楼层
    1#
    发表于 2022-9-12 18:43 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta
    " `! s: N6 ^( [6 @- Z9 v. z5 w
    净重新分类指数NRI的计算
    / P) F/ w4 ]. P( `“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。
    , z( o' f: z* @& E( NNRI,net reclassification index,净重新分类指数,是用来比较模型准确度的,这个概念有点难理解,但是非常重要,在临床研究中非常常见,是评价模型的一大利器!
    - r% j: C% G0 @2 T0 ]* v  F5 a% s0 k$ [" C7 n2 D" m
    在R语言中有很多包可以计算NRI,但是能同时计算logistic回归和cox回归的只有nricens包,PredictABEL可以计算logistic模型的净重分类指数,survNRI可以计算cox模型的净重分类指数。
    3 |! ^( D; r1 ~. _' p0 E, a
    6 r/ c( O) D* c! r) Ologistic的NRI, l# O; a8 }6 ^9 g, w# q; N
    nricens包
    ) h8 Y7 w: W$ v$ Q! v: i1 yPredictABEL包8 y) T3 z; X& {6 H
    生存分析的NRI' ~. t5 w$ _% W- z" h. ]# F
    nricens包  [8 n# v' k; o0 e, u
    survNRI包3 [1 w7 a8 z  {2 p
    logistic的NRI
    7 Y* _9 C; \, C+ R; U, g+ {; enricens包* M& h4 v, _) s8 V( [) P# |
    #install.packages("nricens") # 安装R包* a$ {0 D( F1 ]* o
    library(nricens)
    4 y5 `" _3 H/ Z; P6 X0 n4 \1 x; g11 ?3 A4 e8 N) u8 X; d2 m
    ## Loading required package: survival$ e7 O: l. R9 y
    1$ F4 l. N$ N2 t3 d& r8 c* B
    使用survival包中的pbc数据集用于演示,这是一份关于原发性硬化性胆管炎的数据,其实是一份用于生存分析的数据,是有时间变量的,但是这里我们用于演示logistic回归,只要不使用time这一列就可以了。
    " k2 i- y* E, f: z6 y6 j! X; e5 x+ U8 [6 ]. r1 d, P2 R1 e
    library(survival)2 i* z4 z5 P' p. f
    3 A+ F4 `5 {/ D
    # 只使用部分数据
    6 ~0 `3 Z% H* k, b5 y/ T8 Z% cdat = pbc[1:312,] 9 o6 N0 A# M& M& v- u5 t
    dat = dat[ dat$time > 2000 | (dat$time < 2000 & dat$status == 2), ]
    ( S" N1 z% A4 ~; h3 ?3 b5 V' B  F0 K1 L
    str(dat) # 数据长这样6 S2 c: L3 P7 j
    1* Y: E3 |9 @2 `* n1 c( W
    ## 'data.frame': 232 obs. of  20 variables:
    $ M- o* }0 r9 W0 [$ l9 i" h##  $ id      : int  1 2 3 4 6 8 9 10 11 12 ...
    * V/ r# @$ d8 c( N5 @##  $ time    : int  400 4500 1012 1925 2503 2466 2400 51 3762 304 ...
    % }! N# Y" ~6 E; N7 P##  $ status  : int  2 0 2 2 2 2 2 2 2 2 .... }% s* |  N+ E- _; o
    ##  $ trt     : int  1 1 1 1 2 2 1 2 2 2 ...
    ; w8 H- p0 T2 Q2 D# {##  $ age     : num  58.8 56.4 70.1 54.7 66.3 ...9 h2 W) K( J5 \5 ]7 C- X2 {
    ##  $ sex     : Factor w/ 2 levels "m","f": 2 2 1 2 2 2 2 2 2 2 ...# R* }* N* q* {' T9 P% g5 s
    ##  $ ascites : int  1 0 0 0 0 0 0 1 0 0 ...
    : l$ S8 @  z1 D! {1 Z4 t##  $ hepato  : int  1 1 0 1 1 0 0 0 1 0 ...
    $ g9 d# V( L* S+ V, n##  $ spiders : int  1 1 0 1 0 0 1 1 1 1 ...8 p% w: Z6 \. S9 Y& I1 z4 A
    ##  $ edema   : num  1 0 0.5 0.5 0 0 0 1 0 0 ...
    0 G7 d5 E" I$ b0 B6 e- C& y##  $ bili    : num  14.5 1.1 1.4 1.8 0.8 0.3 3.2 12.6 1.4 3.6 ...
    1 }6 }  V8 B# h, o9 R% p##  $ chol    : int  261 302 176 244 248 280 562 200 259 236 ...
    . S1 t* D9 ]# R+ @##  $ albumin : num  2.6 4.14 3.48 2.54 3.98 4 3.08 2.74 4.16 3.52 ...! z8 N( A! _+ y9 u* Q. }4 p/ m6 {
    ##  $ copper  : int  156 54 210 64 50 52 79 140 46 94 ...
    5 t5 v! w% A& \  {7 F9 R7 t! ~##  $ alk.phos: num  1718 7395 516 6122 944 ...; Q% A/ t! D- T! e% T5 ~$ c- w
    ##  $ ast     : num  137.9 113.5 96.1 60.6 93 ...
    2 f! G1 `) ]+ w8 N% q##  $ trig    : int  172 88 55 92 63 189 88 143 79 95 ...
    0 f1 T& r# S9 |5 p##  $ platelet: int  190 221 151 183 NA 373 251 302 258 71 ...  X! \8 {( m  j+ \& s
    ##  $ protime : num  12.2 10.6 12 10.3 11 11 11 11.5 12 13.6 ...& J% m2 S' W/ b! H
    ##  $ stage   : int  4 3 4 4 3 3 2 4 4 4 ...
    * w9 J# h1 {2 _# W: K' j* Z, |, x
    1
    5 O2 X6 O) S4 A( J- g/ pdim(dat) # 232 20& H# ?' z8 B: L' j
    1
    ) P9 ?" X" f+ M! D## [1] 232  20* ?: t6 H& q' a$ v- H' C+ o& |
    18 Z& v0 e* J( `! N
    然后就是准备计算NRI所需要的各个参数。
    9 \' b0 V) w8 T) B$ X2 c8 b
    / I4 i8 h% ^, Y5 h1 R# 定义结局事件,0是存活,1是死亡( I. ]" v. k8 {) ~3 o4 C( H- L
    event = ifelse(dat$time < 2000 & dat$status == 2, 1, 0)
    ) h+ a5 M" K, E1 o5 @
    3 W9 U! w5 `. w* t8 E2 X# 两个只由预测变量组成的矩阵
    9 c& ^. m) ^& n4 ez.std = as.matrix(subset(dat, select = c(age, bili, albumin)))
    0 B/ L8 u4 r5 [  i! wz.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))1 h5 ^3 f7 ]; w, [5 H; r$ [

    6 e3 N# ]. X( h9 u0 q% S" ]! k# 建立2个模型: U4 N3 Q' i. C* q) C! g& u# d) ~
    mstd = glm(event ~ age + bili + albumin, family = binomial(), data = dat, x=TRUE)
    # W8 `" F; [  v6 Z, `+ Fmnew = glm(event ~ age + bili + albumin + protime, family = binomial(), data = dat, x=TRUE)& w& C* n. f# _" ~' ~3 U

    / m& s( ~' N/ J5 g8 A# 取出模型预测概率
    ' i; B) ^- m4 {5 V1 jp.std = mstd$fitted.values: g. P8 ]+ T  l% r2 q5 Z
    p.new = mnew$fitted.values
    5 p" H& G% K4 h8 I/ n& p. ?6 T4 U+ V& }& `% [5 d# C9 U  Q1 C) f
    1" ^4 A$ W) W$ @& m( a
    然后就是计算NRI,对于二分类变量,使用nribin()函数,这个函数提供了3种参数使用组合,任选一种都可以计算出来(结果一样),以下3组参数任选1组即可。 mdl.std, mdl.new 或者 event, z.std, z.new 或者 event, p.std, p.new。
    3 h; k6 X' p+ \8 }+ i+ B
    5 s4 B) b9 J9 z( n* |& @& A# 这3种方法算出来都是一样的结果
    + \! c% y4 B0 v3 |% C8 R% m; _/ b/ @
    # 两个模型
    % h( x" S. s- i4 i% f7 e7 [6 ?nribin(mdl.std = mstd, mdl.new = mnew,
    : P$ M& d3 K$ s( I       cut = c(0.3,0.7), 0 ^* G7 f7 n3 `& i6 f) ^; P/ a% }
           niter = 500, 2 ?0 q$ k& ^8 C0 u1 _
           updown = 'category')8 s; {  g2 A2 [% R2 |1 a4 v& E

    8 y- ]: w5 q  R9 @  E4 R. I& E/ ]# 结果变量 + 两个只有预测变量的矩阵
    9 x5 b% ]  l; E: U2 inribin(event = event, z.std = z.std, z.new = z.new, - {+ R) y4 S: r) Y- I* C
           cut = c(0.3,0.7), 4 J( u' {+ I9 ?3 ~  e% m
           niter = 500,
    . b( V5 b) b2 |4 P  P       updown = 'category')
      F+ X& {1 Q/ r! n# A
    - s/ B2 M$ C7 X7 l- s! D6 U## 结果变量 + 两个模型得到的预测概率: `' w  f6 x8 a' u
    nribin(event = event, p.std = p.std, p.new = p.new, . [  O1 W% N- s3 ]
           cut = c(0.3,0.7), # y; [& m. \" m8 r' r
           niter = 500,
    ; e- L8 o% e9 v       updown = 'category')/ V! F0 E5 V  W  a

    8 m- d- W) C  d1- m5 ~$ B, ^9 p0 T
    其中,cut是判断风险高低的阈值,我们使用了0.3,0.7,代表0-0.3是低风险,0.3-0.7是中风险,0.7-1是高风险,这个阈值是自己设置的,大家根据经验或者文献设置即可。
      q% [* R9 B- ~" _, Y
    * d/ Q' N, s9 ?3 y- j' A4 ]niter是使用bootstrap法进行重抽样的次数,默认是1000,大家可以自己设置。3 p% _% C4 q* I& e; U3 e0 x

    + [! E6 `" i% v% G! Qupdown参数,当设置为category时,表示低、中、高风险这种方式;当设置为diff时,此时cut的取值只能设置1个,比如设置0.2,即表示当新模型预测的风险和旧模型相差20%时,认为是重新分类。. z+ D( q5 z, q7 d' N

    1 r# I! j* F+ F/ [% _上面的代码运行后结果是这样的:% r: P- g$ Q' J$ K7 Y

    & t# O; B3 N3 HUP and DOWN calculation:
    : i# H* o; T7 A1 B% V& U! r, f  #of total, case, and control subjects at t0:  232 88 144
    , `2 w5 c4 R1 N! b" X" H# [1 k2 ]' c' [
      Reclassification Table for all subjects:) v6 [9 V' E& r# F1 h7 a! l
            New5 ~( Y3 a& ~6 S5 r7 ~7 w1 ^  `6 B3 P
    Standard < 0.3 < 0.7 >= 0.7
    , J" K/ R4 [# L; W1 Y+ S  < 0.3    135     4      03 I( k" S5 I- G& T8 b/ j6 E. b
      < 0.7      1    31      4
    ! @; h, Z8 m' X  >= 0.7     0     2     559 L9 E* V" i1 O( f" ~

    ' j. p4 `1 E* ~7 U( m  Reclassification Table for case:
    4 d$ Y% l5 [& b9 f5 X        New
    ! }3 n2 w* h) F0 w8 y' _Standard < 0.3 < 0.7 >= 0.75 G3 V' d. s, p5 e- K
      < 0.3     14     0      0
    - V9 M2 _+ I% s( c7 T7 r  < 0.7      0    18      3) o9 i0 @0 x$ D, U  K
      >= 0.7     0     1     527 @! _# h+ r' z! g

    - i7 u' Q+ e* c- N+ J/ L* q8 N- G  Reclassification Table for control:
    8 i/ b) W6 ~# ^1 ^% F1 g2 V$ \5 |        New
    + [& N- }+ h$ Y* K6 fStandard < 0.3 < 0.7 >= 0.7: m8 e* n5 E) C) X* j/ _
      < 0.3    121     4      0' }4 g; w4 M7 J* h+ P
      < 0.7      1    13      1
    # Z7 {! e# S4 [+ d" Y- q  >= 0.7     0     1      3
    8 k' }; q( K# \8 T' I4 ^/ ^4 T8 U) l8 @, A$ L5 m+ k" @
    NRI estimation:8 s8 C4 r: M7 U. }5 ]
    Point estimates:, ?) R. ^5 J+ i" Q( H
                      Estimate, [* a  H: e- `7 H
    NRI            0.001893939
    5 O0 Q& @+ j" B, E. L: wNRI+           0.022727273  m% _* A: d8 x6 }: U+ j
    NRI-          -0.020833333
    * u8 p7 C4 H9 X0 Q# r8 D, XPr(Up|Case)    0.034090909
    " c/ @* m. I3 a* DPr(Down|Case)  0.011363636
    % S  J9 x8 A- ^: {: x" e) vPr(Down|Ctrl)  0.013888889) e1 L6 u& V' f4 A
    Pr(Up|Ctrl)    0.034722222
    1 m9 j/ F$ r9 ]1 k& ~, Y( w
    " E/ ]$ ^2 K  g' ?" [. [. T7 JNow in bootstrap..
    5 u8 K) k( B( R% g3 H% o
      d" q  H! A( d3 yPoint & Interval estimates:) l8 c7 R( Q2 ^4 t" u2 I
                      Estimate   Std.Error        Lower       Upper5 n* Z. ]& {( r
    NRI            0.001893939 0.027816095 -0.053995513 0.0553544497 O3 U# A- y+ n' {$ {7 o
    NRI+           0.022727273 0.021564394 -0.019801980 0.065789474
    1 ^' k1 E2 h* F/ G2 ]6 b& D- @" @NRI-          -0.020833333 0.017312438 -0.058823529 0.007518797( n* [6 G& u* H
    Pr(Up|Case)    0.034090909 0.019007629  0.000000000 0.072164948, m9 a7 k  M7 l
    Pr(Down|Case)  0.011363636 0.010924271  0.000000000 0.039603960) u8 Y6 }- B* W3 @' c4 u4 p2 @
    Pr(Down|Ctrl)  0.013888889 0.009334685  0.000000000 0.035211268
    ( l$ L& Y$ e1 x4 zPr(Up|Ctrl)    0.034722222 0.014716046  0.006993007 0.066176471# q; W! g' ]$ j# P6 I
      `4 W! K7 ~( |+ T
    1
    1 I6 N0 ~& g% o& v( Q; d. g首先是3个混淆矩阵,第一个是全体的,第2个是case(结局为1)组的,第3个是control(结局为2)组的,有了这3个矩阵,我们可以自己计算净重分类指数。4 x6 h- ?% K$ D3 ?$ E3 D* _# d8 ~

    / D* g' W3 |; Z) `看case组:; f7 l: {% m+ ?
    ( p( n' S1 f7 ~  P! l0 o2 v
    净重分类指数 = ((0+3)-(0+1)) / 88 ≈ 0.022727273
    6 \- f8 M1 i0 J' Z/ @+ d  `0 J6 `3 d& C
    再看control组:9 E9 H# |- P' T: \# v9 E0 y
    6 A6 Q1 G& Y, ~4 N" a
    净重分类指数 = ((1+1)-(4+1)) / 144 ≈ -0.0208333336 {3 D+ K) z$ B* C
    ! M3 H; b5 e- {: l3 r
    相加净重分类指数 = case组净重分类指数 + control组净重分类指数 = 2/88 - 3/144 ≈ 0.000315657
    7 }) A3 h8 K: |2 R: W9 R# a9 H' ~! D: c/ j3 L' F
    再往下是不做bootstrap时得到的估计值,其中NRI就是绝对净重分类指数,NRI+是case组的净重分类指数,NRI-是control组的净重分类指数(和我们计算的一样哦),最后是做了500次bootstrap后得到的估计值,并且有标准误和可信区间。1 K3 |0 ]. E4 I; b4 A0 l
    8 V7 \! v* V' K0 s/ S
    最后还会得到一张图:* b# o8 ?; _: m9 C8 R

    5 c- S2 R+ s7 p$ t9 t这张图中的虚线对应的坐标,就是我们在cut中设置的阈值,这张图对应的是上面结果中的第一个混淆矩阵,反应的是总体的情况,case是结果为1的组,也就是发生结局的组,control是结果为0的组,也就是未发生结局的组。6 l. G% @$ ]7 Q8 Q9 s9 S0 R
    , \3 v0 }; P, q: f! `& T9 S, _
    P值没有直接给出,但是可以自己计算。
    8 r8 e5 h% g1 h, F. G; o
    4 o& Z+ ~% n% t' E% i+ \7 Y, r# 计算P值3 M& V; c6 i% y' V; J1 P
    z <- abs(0.001893939/0.027816095)
      O0 ^- D) _5 A/ Pp <- (1 - pnorm(z))*2- x. C) |1 B# Q7 K# u
    p
    ; K. q) J. _- y  |% {$ h$ u1
    % n7 B& X% J/ {5 `## [1] 0.94571574 @" t- P. x, R
    1
    + |% u5 d& I- Y7 ]; L. PPredictABEL包
    - G  k( b' H: }" Z4 C#install.packages("PredictABEL") #安装R包
    " F* Q4 K- f' a3 J/ p6 tlibrary(PredictABEL)  
    7 Y/ U3 }/ t- O& f. \/ |2 `
    $ [+ O$ D. k4 e- y: s& s# 取出模型预测概率,这个包只能用预测概率计算5 ~( T. ?  @8 ]! f# ~3 n
    p.std = mstd$fitted.values
    / t' ^* [, J( _+ U- x2 Yp.new = mnew$fitted.values ( K6 A8 V  S4 ^4 s: m% f
    1
    # m0 h' M7 F) J# |! s然后就是计算NRI:1 l: K- ^0 S) \) e) Z/ Z, d
    . v0 u9 U- K5 Z, m( C7 k3 r
    dat$event <- event$ q6 `4 G) z# E: o4 X. q+ q$ Q

    / [3 U5 Q" U9 h& Sreclassification(data = dat,! ^0 ~4 f6 l) V9 J
                     cOutcome = 21, # 结果变量在哪一列# v" `% ^5 y, U- z: H; {; M7 w) ]
                     predrisk1 = p.std,
    . v7 G- r( A5 V. b! R                 predrisk2 = p.new,. g$ n6 B* `1 ?( T* D
                     cutoff = c(0,0.3,0.7,1)
    / }  A: t& d9 ]1 O: n' r( C. z0 r                 )  u+ r. b7 w4 Y1 r# Y0 Y4 [
    1
    * z, u/ [8 D5 B9 T##  _________________________________________6 ~6 o5 y! q7 l
    ##  3 d& w% m! y; Q" o* |& I( v
    ##      Reclassification table    1 [: ^5 X+ _1 f/ @9 y& {
    ##  _________________________________________, Z( ?8 ~  Z" I5 u: P" x
    ##
    , o- u* Y/ x3 X. D  W  F( ]. V2 R6 X##  Outcome: absent
    ; }" v, @! T; \, f) E##   ) V5 _- c9 G6 m
    ##              Updated Model
    + D  @5 ]/ {7 H## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
    ) a: v3 m$ c# U' {' D  N; p##     [0,0.3)       121         4       0               3
    6 o$ U1 {% z1 ?0 V##     [0.3,0.7)       1        13       1              13* M0 h9 m" `$ P% u0 Z% a
    ##     [0.7,1]         0         1       3              25
    " o0 w, g3 v4 Q5 }, k## / N$ o- O  [+ u5 S) F
    ##  , E% R2 a4 G' ~+ J  Q: P
    ##  Outcome: present
      I* i2 h/ t) v; W( f3 a##   ! [4 F1 \4 [& F# r0 j. b
    ##              Updated Model
      a& Z' t* m8 g6 ]6 N$ M## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified+ u- n7 X2 N0 q/ [& |# l- M- w' J
    ##     [0,0.3)        14         0       0               0, ^" u( x; z* d7 K4 q8 `
    ##     [0.3,0.7)       0        18       3              14
    9 |' K/ l$ `( p7 S4 y##     [0.7,1]         0         1      52               2
      C6 c: a) Z3 a( ~( U0 e* k" a##
    9 w- w# W: S: K: |1 c##  " Z- o: z+ I. |& E: Q
    ##  Combined Data # I& o9 v  o& g- ~( H# {6 w
    ##   
    . o7 v* @+ B) J5 L  i1 ]* ?##              Updated Model' i4 I2 m# {2 y5 E
    ## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified' ]1 J( X( V( z) F# B% s
    ##     [0,0.3)       135         4       0               3" P$ ^3 H: h) c9 a
    ##     [0.3,0.7)       1        31       4              146 ~7 u3 o! \  Q3 T
    ##     [0.7,1]         0         2      55               4/ b/ d) P3 [1 P) K. N1 d% E
    ##  _________________________________________' h3 }# [; ~6 @$ `0 p
    ##
    + L# F: @2 c, Z, o/ h##  NRI(Categorical) [95% CI]: 0.0019 [ -0.0551 - 0.0589 ] ; p-value: 0.94806 % R$ S$ m$ h$ k5 j5 |' C
    ##  NRI(Continuous) [95% CI]: 0.0391 [ -0.2238 - 0.3021 ] ; p-value: 0.77048 . G9 M/ |  p8 R* f" E4 V' \/ ]1 J
    ##  IDI [95% CI]: 0.0044 [ -0.0037 - 0.0126 ] ; p-value: 0.28396& n7 ]( l; r  v
    ) _  \) @$ k! y9 z8 x+ `. |( e
    1' O% F2 n5 A8 Z. X
    结果得到的是相加净重分类指数,还给出了IDI和P值。两个包算是各有优劣吧,大家可以自由选择。# H& P, E1 Q7 Q  p: s& z- j, @
    , o$ K# K4 S5 D# c
    生存分析的NRI6 N3 s5 z" a0 C& L( U/ ]
    还是使用survival包中的pbc数据集用于演示,这次要构建cox回归模型,因此我们要使用time这一列了。" C% t9 A5 W4 d

    # l, _+ P8 T# @5 V* |* ]; hnricens包
    / A6 r  _2 |. T4 D+ ?9 Q: dlibrary(nricens)
    0 F( K1 k$ o; P" `' Q9 E4 D4 [library(survival): J. q' D1 Y% ^9 f
    & y  Z, {3 L# W, z1 t8 t
    dat <- pbc[1:312,]1 {' R0 J; \+ I3 u! t$ Z- r3 e
    dat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡1 L4 [2 q) w9 c% q4 d" K3 [, \
    1
    % A1 j2 V* o! a5 L3 a/ U! n然后准备所需参数:# {9 X/ K, C* z% ?

    $ e! S6 M& G* I# 两个只由预测变量组成的矩阵
    7 c& n1 b3 C, u6 |z.std = as.matrix(subset(dat, select = c(age, bili, albumin)))
    ; K1 M2 F5 R/ rz.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))
    7 B7 J, v$ p2 Z
    + m- |! z, b4 E; h$ S4 M. [# 建立2个cox模型
    % f- K  u' O% G/ O& jmstd <- coxph(Surv(time,status) ~ age + bili + albumin, data = dat, x=TRUE)" k% E6 e6 H3 h
    mnew <- coxph(Surv(time,status) ~ age + bili + albumin + protime, data = dat, x=TRUE)& t" `* A1 p( I7 m6 [+ }3 d$ H9 ]
    + b; u" [1 P8 m. O# h+ [
    # 计算在2000天的模型预测概率,这一步不要也行,看你使用哪些参数  m7 E8 s3 H0 K8 b# T# m# _2 y
    p.std <- get.risk.coxph(mstd, t0=2000)' h4 o7 ^' I! M. W/ t3 W/ |
    p.new <- get.risk.coxph(mnew, t0=2000)
    " x5 N$ U8 w: {, E6 P1 j/ `' z2 d19 B% Z0 _  ^( D6 r! B; m) _% g
    计算NRI:
    % {4 N' }$ r6 w7 v/ D! R6 @5 k5 ]: _
    nricens(mdl.std= mstd, mdl.new = mnew, 2 W7 H6 I, [+ K. K  N3 |. b
            t0 = 2000, % S" k* ^% m7 y8 U
            cut = c(0.3, 0.7),
    9 U# ~; S6 c3 A        niter = 1000,
    , J" [+ w( V+ G5 t        updown = 'category')6 P1 I+ B) t3 U- ]
    1 a7 a. S! j, z- D# q5 C" I9 r
    UP and DOWN calculation:
    2 q. w( m+ K  ^. `6 n5 v  #of total, case, and control subjects at t0:  312 88 144
    ) Z; P) Y& k' D) g
    1 D7 c9 s  q) z  Reclassification Table for all subjects:8 b) U: W0 |% R$ C
            New- J$ [, A& \" \" [5 h4 P% |6 y
    Standard < 0.3 < 0.7 >= 0.74 |4 W" f0 i* N9 ]4 D- n. g/ V: s6 B/ u
      < 0.3    202     7      0& ~" j0 J" \6 K9 _% z* N
      < 0.7     13    53      6
    " |# h* [* a1 \" n2 q, u  >= 0.7     0     0     31
    7 Y( ^' _/ x8 Z0 Y
    2 W( D0 _0 f" H( ]+ I# p  Reclassification Table for case:2 f# ?! U0 k$ Q6 b7 Y0 x" q
            New+ a5 a1 y5 c: j% G$ j4 d
    Standard < 0.3 < 0.7 >= 0.7% y/ q$ i2 q9 p1 J% V7 [+ I2 L% a" A& C& j
      < 0.3     19     3      0
    . j4 g0 k7 i3 p  < 0.7      3    32      49 D8 q$ f4 ?5 s1 N% h# y
      >= 0.7     0     0     27! R) Q" h) }; J4 V* Q

    ; z+ \1 n  b, b, d0 m7 b, f+ x  Reclassification Table for control:
    : h8 C/ Y& h$ l; q4 v        New
    ! ^# e2 D( W0 t' u$ JStandard < 0.3 < 0.7 >= 0.7( I0 O! B9 \1 _
      < 0.3    126     3      0
    & {5 @- k: ]: S0 Y0 d  < 0.7      5     7      2
    + x" N4 h% `4 q: q  V, A, y5 h  >= 0.7     0     0      1& x0 [5 k* d: N, m
    - ?" ^) L6 W# l1 [+ q* c1 i
    NRI estimation by KM estimator:
    , h! M3 t8 ?! Q$ B! G2 K& c, N: E0 v" C# O% `+ g
    Point estimates:- \0 c, f3 c& E2 \; b/ T8 |/ l
                    Estimate0 Z9 ^! ]- H+ U- s7 e" G' Z; B
    NRI           0.05377635
    1 A' z5 k# n; \- f, J% fNRI+          0.03748660' K/ \6 @+ Q1 f8 r0 @4 s- p
    NRI-          0.01628974
    , Z! x. x6 Z" `9 O# @+ Y$ D! xPr(Up|Case)   0.07708938/ m# a+ P- G8 ?8 S5 i
    Pr(Down|Case) 0.03960278
    2 a$ L4 ~/ t, G9 ]6 kPr(Down|Ctrl) 0.04256352
    8 h. e% r0 K9 c% `8 v( lPr(Up|Ctrl)   0.02627378
    1 B! Z, N$ l, E  b, O
    6 n/ M; U! V- f! LNow in bootstrap..
    % h6 Z3 A. P" z' T* O" g" W( \
    Point & Interval estimates:* Q0 h3 V6 ]* }4 u5 k
                    Estimate        Lower      Upper
    . d6 F# n0 E+ t- q; s4 FNRI           0.05377635 -0.082230381 0.16058172
    , |- \: `% O+ ?6 B! A. J$ J7 TNRI+          0.03748660 -0.084245197 0.132317769 e9 f- @1 i) \4 l& z. m6 d# b& D/ S' A
    NRI-          0.01628974 -0.030861213 0.06753616
    6 L+ z  E7 G8 KPr(Up|Case)   0.07708938  0.000000000 0.19102291
    / ?& s2 `- M( ^1 APr(Down|Case) 0.03960278  0.000000000 0.15236016% c* b( U& Q/ f2 K4 P& P# [
    Pr(Down|Ctrl) 0.04256352  0.004671535 0.098631705 i! M! r' B( G& U4 d& B6 ?
    Pr(Up|Ctrl)   0.02627378  0.006400463 0.059984244 W2 b% j- K: C+ M% W( ^3 i

    , p* G* O) ]6 I& y1
    2 a& A3 f% k% v) Y, j
    ! |5 B- `$ a; D& O) ?7 ~Snipaste_2022-05-20_21-49-38/ C# N0 }: u) c
    结果的解读和logistic的一模一样。+ w& h1 U! s" t1 E2 M9 q1 h( F0 M
    2 M( K1 i7 ?! W2 j- D
    survNRI包
    / f4 x, }* a) ?/ B# 安装R包$ c& v8 K7 q% }% [) K; v
    devtools::install_github("mdbrown/survNRI")
    5 |% P5 k: A, \9 e+ v1
    : V1 y% F  ~) r3 @加载R包并使用,还是用上面的pbc数据集。
    4 `' Z2 v5 x$ _  T3 p. S9 h6 S" h2 t0 ~
    library(survNRI)
    $ a1 M1 \- x. Q% B0 I/ y; y1
      T1 m# C; r* S7 P8 F## Loading required package: MASS; r, o% s' S& t
    1
    0 ?& G/ [3 U0 Ylibrary(survival)6 ~0 I9 i  E% N5 Z5 U; i
    + ]7 [% t6 {# S6 ?
    # 使用部分数据+ N- `3 q5 x0 G: l
    dat <- pbc[1:312,]- f) c* n+ j8 m4 R/ t8 C6 \
    dat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡
    ; }9 o, P0 W, [7 i7 a* R  X$ G0 S- }6 A4 i4 \
    res <- survNRI(time  = "time", event = "status", 4 b( R7 Z4 V7 S4 z% }* o7 F2 L: F2 f
            model1 = c("age", "bili", "albumin"), # 模型1的自变量
      Z; c2 i0 E) l0 e# ?0 v, |- O* v        model2 = c("age", "bili", "albumin", "protime"), # 模型2的自变量7 r7 ^9 z9 i- S0 ^
            data = dat, 9 o( V* U+ Z8 J6 B  u+ m
            predict.time = 2000, # 预测的时间点% P3 P) x( r1 L; y  `  H
            method = "all", 0 C/ J( Z5 l& ~9 ~0 A% ~9 s
            bootMethod = "normal",  
    0 q2 u5 ?& J' n8 C% J        bootstraps = 500, " [7 p' z, f# a  \0 `* D
            alpha = .05)
    * k0 x8 k4 r6 J5 ~- v
    / u4 H$ H+ D% b, b) J& g1& o3 H) `; z1 E, f  p
    查看结果,$estimates给出了不同组的NRI以及总的NRI,包括了使用不同方法(KM/IPW/SmoothIPW/SEM/Combined)得到的结果;$CI给出了可信区间。
    ) t+ \2 ?# ~+ F: g- _8 c! s. c& G
    res
    / s6 W1 G! ]4 H' K6 g15 ]& c$ [3 O3 t% ^: Y
    ## $estimates
    1 K. A' c5 }2 |" ~& |# ^- X##            NRI.event NRI.nonevent       NRI
    ! w* t* T  b  V# l0 ?/ ^0 C; E2 ^2 j## KM        0.20445422    0.3187408 0.5231951
    # N: G7 K0 f) X7 x* k## IPW       0.22424434    0.3273544 0.5515987) m- a1 W& m9 c' D* f
    ## SmoothIPW 0.19645006    0.3144263 0.5108763
    7 [/ A2 T4 Y) K3 _## SEM       0.07478611    0.2632127 0.3379988
    $ S% j' {% e9 s. n# _## Combined  0.19633867    0.3143794 0.5107181; s0 w: S5 p+ V
    ##
    * j/ b. C; P1 x2 e  G## $CI
    # k9 i( R) @& A+ @9 X7 a9 X## $CI$NRI.event: n" U( c4 W/ n; r
    ##                     KM         IPW   SmoothIPW        SEM   Combined5 w3 g/ t, C0 y! ~: z
    ## lowerbound -0.03915924 -0.02185068 -0.04724202 -0.1162587 -0.04737238 V, |: v7 E3 u1 I# i  x
    ## upperbound  0.44806768  0.47033936  0.44014214  0.2658309  0.44004961 ]& ?9 E$ k# T/ r, \/ ]1 {, J
    ##
    7 A$ u6 k( y- r2 D## $CI$NRI.nonevent8 s4 B! ?  A0 Z' V1 x  j2 ]7 S
    ##                   KM       IPW SmoothIPW        SEM  Combined/ ~& x5 m# C) o9 ?
    ## lowerbound 0.1317108 0.1396315 0.1286685 0.08638933 0.1286426/ o& s) z* g: \
    ## upperbound 0.7102251 0.7393216 0.6966341 0.51482212 0.6964549
    ) P+ h" O1 G) A- ?5 f4 C##
    0 Z' B" c! T& _5 E* y## $CI$NRI0 i7 o+ f0 M" Y; Q. @
    ##                     KM         IPW   SmoothIPW         SEM    Combined
    & v& ^5 y8 H' p/ }## lowerbound -0.05112533 -0.04569046 -0.05439863 -0.04132364 -0.05443409
    & g- S! U7 R3 I6 b& y' {: E2 o## upperbound  0.89306122  0.92464359  0.87970125  0.64253510  0.87953153
    1 l  w3 S# |7 y. ~$ H0 x& g## / K6 `5 I+ z) O3 B+ H3 q& N3 L
    ## 8 L7 b# V' V: y( _% O
    ## $bootMethod
    9 v$ N( U; A% F7 Y8 ^## [1] "normal"1 k, M3 D  B$ j! u6 J5 [* p# ^
    ## 8 [+ ]; R* J5 t0 `2 n- e0 O
    ## $predict.time# g5 b3 x) h# [; @8 K3 R
    ## [1] 2000
    " |6 k- k5 \5 }& I9 z. k## % N5 e- I7 z& A; e& W* Z$ v! w
    ## $alpha
    ! S* B+ y* e- Y. w4 D## [1] 0.05& o+ Z4 m, l, g" v
    ##
    ; s+ n$ T2 }4 Y+ S$ l( @5 [## attr(,"class")! Q2 p7 s* _; H8 K/ r
    ## [1] "survNRI"$ ~. `% i  S; w0 }$ h& J* X$ {
    6 n1 W6 N+ T' x
    1
    ( F4 ?9 B' `' [5 LOK,这就是NRI的计算,除此之外,随机森林、决策树、lasso回归、SVM等,这些模型,都是可以计算的NRI的,后面会继续介绍。大家如果有问题欢迎在评论区留言。
    6 X5 e/ P: j  k* }. N# K* }
    6 j5 g# @' f% ?8 N2 Q4 F4 i本文首发于公众号:医学和生信笔记5 F3 T+ N7 O. ]' i* `
    / u: H4 X# V& p! M; K7 I, [
    “ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。
    / Y1 M: u" T' W; Z! }7 T本文由 mdnice 多平台发布
    ! g  X$ D- m5 S5 e: H, d' t5 m————————————————
    1 _4 E. S+ X. g# i  v版权声明:本文为CSDN博主「阿越就是我」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    $ g, {; ~$ ^9 u; f" k8 J: ]原文链接:https://blog.csdn.net/Ayue0616/article/details/126768006
    - U/ q9 D$ P3 S! `  E' z" ]1 G6 {& @! u; Y- G5 p  R3 O* u2 b+ x0 y9 M

    * `+ t1 @/ R( }- ]
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

    关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

    手机版|Archiver| |繁體中文 手机客户端  

    蒙公网安备 15010502000194号

    Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

    GMT+8, 2026-10-8 09:41 , Processed in 0.790427 second(s), 51 queries .

    回顶部