QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3179|回复: 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
    * F* [, G! {7 y- b8 B9 M- V/ a
    净重新分类指数NRI的计算
    $ \. W! K5 v7 q/ h1 N“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。3 X; ]+ F+ d3 P+ `" U2 x
    NRI,net reclassification index,净重新分类指数,是用来比较模型准确度的,这个概念有点难理解,但是非常重要,在临床研究中非常常见,是评价模型的一大利器!: ?' C5 A/ w4 \3 `/ T1 W

    3 J  ?* W% |2 w# X在R语言中有很多包可以计算NRI,但是能同时计算logistic回归和cox回归的只有nricens包,PredictABEL可以计算logistic模型的净重分类指数,survNRI可以计算cox模型的净重分类指数。
    1 Y; D& z7 p3 B; ?2 B6 h# Z( W% i" X
    logistic的NRI
    * G. ], \' ~- \) ]nricens包! ^7 A& r% H/ B. z2 `# `9 x  A
    PredictABEL包
    1 |2 c. o+ L$ Q) y生存分析的NRI6 b* m" k) b2 F, x. k1 Y) h
    nricens包
    - D6 b. _8 P3 Q2 R% y3 C9 DsurvNRI包
    * A+ h2 i6 f* @$ m: u4 Alogistic的NRI  q; V) D1 U1 F
    nricens包2 m1 F3 y7 z) O; o+ n5 @4 R
    #install.packages("nricens") # 安装R包
    1 c+ \+ H; [$ h6 T/ @. Mlibrary(nricens)
    & c5 @' r0 C3 J1 G. t- ]9 }7 y1
    $ O6 r6 i7 s0 n2 N9 y## Loading required package: survival1 l9 W/ K' u+ n* w+ E% x6 q
    1; i5 Z* a+ v0 c, G" `% @
    使用survival包中的pbc数据集用于演示,这是一份关于原发性硬化性胆管炎的数据,其实是一份用于生存分析的数据,是有时间变量的,但是这里我们用于演示logistic回归,只要不使用time这一列就可以了。6 v0 a) B6 J  {- F
      n- ~- V; c9 D
    library(survival)
    ' u- X  m, @$ ?% U* v+ x1 l+ `# C! c
    # 只使用部分数据; i7 k, z9 p# X
    dat = pbc[1:312,] " ?) ]# l# X8 h
    dat = dat[ dat$time > 2000 | (dat$time < 2000 & dat$status == 2), ]
    2 c7 y8 i8 c5 N% O6 X: `  M$ x, I0 s! v$ o  l1 k+ x% L
    str(dat) # 数据长这样
      _& f- C& K; m4 E- J# q1# `/ s- h9 `! V$ g
    ## 'data.frame': 232 obs. of  20 variables:% {* e% o7 ^. H) v6 p) M( |% d
    ##  $ id      : int  1 2 3 4 6 8 9 10 11 12 ...
    3 N1 w2 Q: y- X& I6 u##  $ time    : int  400 4500 1012 1925 2503 2466 2400 51 3762 304 ...
    8 Q( J$ F* w9 G3 }" P/ I) d, [##  $ status  : int  2 0 2 2 2 2 2 2 2 2 ...( G( K" H. a, \+ C# L+ p6 m# e2 r
    ##  $ trt     : int  1 1 1 1 2 2 1 2 2 2 ...
    1 h8 [9 Y- X6 O  k+ ?7 C##  $ age     : num  58.8 56.4 70.1 54.7 66.3 ...
    6 `" j& b# ?( b7 q3 Q0 g1 o% p##  $ sex     : Factor w/ 2 levels "m","f": 2 2 1 2 2 2 2 2 2 2 ..., F% x! y! ^$ W: f  s
    ##  $ ascites : int  1 0 0 0 0 0 0 1 0 0 ...
    & R5 }* z% u2 C( H' |##  $ hepato  : int  1 1 0 1 1 0 0 0 1 0 ...
    ! g+ Z* j; W3 Q+ i/ L+ ^& e- v& v##  $ spiders : int  1 1 0 1 0 0 1 1 1 1 ...- ^* d! `3 G8 o: c1 S  \& F5 k8 r% w& U, g
    ##  $ edema   : num  1 0 0.5 0.5 0 0 0 1 0 0 ...
    8 E7 A7 d& ^* F: ^9 z##  $ bili    : num  14.5 1.1 1.4 1.8 0.8 0.3 3.2 12.6 1.4 3.6 ...- f% r& M( ?( G% ?2 L! }0 b
    ##  $ chol    : int  261 302 176 244 248 280 562 200 259 236 ...$ O) J: \- G4 w5 r( Y- {, j. y+ R
    ##  $ albumin : num  2.6 4.14 3.48 2.54 3.98 4 3.08 2.74 4.16 3.52 ...% _9 i& m# o/ f
    ##  $ copper  : int  156 54 210 64 50 52 79 140 46 94 ...' p% x& M) y5 g$ B+ l( A# e
    ##  $ alk.phos: num  1718 7395 516 6122 944 ...3 E9 G& B0 W- g6 c2 D( r- [" A
    ##  $ ast     : num  137.9 113.5 96.1 60.6 93 ...
    7 q/ y4 k& U5 R0 j##  $ trig    : int  172 88 55 92 63 189 88 143 79 95 ...
    / L  ^# z# d& n, u* l, d##  $ platelet: int  190 221 151 183 NA 373 251 302 258 71 ...
    # S6 |2 W6 B: @. j, W/ d( t##  $ protime : num  12.2 10.6 12 10.3 11 11 11 11.5 12 13.6 ...
    8 b' C0 r( H3 V3 u" N5 i9 R  f##  $ stage   : int  4 3 4 4 3 3 2 4 4 4 ...
    : k7 c1 j: l: w6 `1 O7 E8 U$ E6 G5 s: M+ Z+ G
    10 d5 K# \2 |) C; E( Y( p- A
    dim(dat) # 232 20
    4 w! V! V5 n2 G- @* b6 K' H5 k5 X1" `7 c( t- D* T# D7 ^7 A2 e. P
    ## [1] 232  20
    # B; v) h7 G" S, ]  n& V' n. o: g; {1
    7 Z9 S1 Y" D; J  U然后就是准备计算NRI所需要的各个参数。- q9 G3 G# a) l6 [: q+ U$ `" [

    1 M5 ~0 v9 b8 p# P- ]7 w# 定义结局事件,0是存活,1是死亡
    & i  z1 Z8 s( T  l% r6 ?+ r4 Aevent = ifelse(dat$time < 2000 & dat$status == 2, 1, 0): B4 g$ T+ u3 {6 d
    $ ]/ w  Z: W. a
    # 两个只由预测变量组成的矩阵: r& `! ^5 q* b* U/ S0 p3 m0 i
    z.std = as.matrix(subset(dat, select = c(age, bili, albumin)))
    * P6 J8 I) {1 t: x4 ^z.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))
    / P& z$ X  F8 c  F6 u
    2 m% ]8 G) }+ _0 \6 c5 j) u# 建立2个模型7 L) Z( w. f$ e" E( V6 H
    mstd = glm(event ~ age + bili + albumin, family = binomial(), data = dat, x=TRUE)( T( Y! }3 a/ \; k5 T/ }% x4 u
    mnew = glm(event ~ age + bili + albumin + protime, family = binomial(), data = dat, x=TRUE)
    - H0 |3 @% }% K+ \! n: t) A2 J9 Q/ P) Z
    # 取出模型预测概率
    4 ~$ r5 n+ E( W) s  |7 i4 }p.std = mstd$fitted.values6 B" w& b9 d4 G1 M7 X
    p.new = mnew$fitted.values
    2 M9 t2 Q- p7 T2 [) I
    ' B: G( G3 U1 b& U18 n0 u! S, f' ?& m2 p  g: d
    然后就是计算NRI,对于二分类变量,使用nribin()函数,这个函数提供了3种参数使用组合,任选一种都可以计算出来(结果一样),以下3组参数任选1组即可。 mdl.std, mdl.new 或者 event, z.std, z.new 或者 event, p.std, p.new。7 _& \  P8 V+ ]0 B
    9 n) U' G; _/ v& j6 A
    # 这3种方法算出来都是一样的结果
    / V! u" g, g. `5 G1 w) s6 p
    - L5 E1 q4 y/ s) S# 两个模型
    ; H. B% E$ p6 N& L' Pnribin(mdl.std = mstd, mdl.new = mnew, 9 v5 C; C! N/ S8 c& c) J1 d) }* ^
           cut = c(0.3,0.7),
    & M1 B, |8 c- S       niter = 500,
    ' u% R. ]' B( C  |7 p7 D0 w) z       updown = 'category')
    ( R0 [' E, c# j4 X6 Y; _: \+ e" r  i) i7 I/ b
    # 结果变量 + 两个只有预测变量的矩阵
    , F7 z* W, ~+ y% c. O$ C- Ynribin(event = event, z.std = z.std, z.new = z.new,
    5 f( D9 D7 }/ ]) |2 ]2 @       cut = c(0.3,0.7), & g% j; x5 k! x0 ?& Z8 G4 u3 l
           niter = 500,
    % G; _7 E8 a9 f; ?- h       updown = 'category')
    ; N% _  Q/ h+ u. b
    ) W5 n2 h. ^0 ~4 n) r" ~; ]2 e4 P( k## 结果变量 + 两个模型得到的预测概率7 ?) m: a; s6 ]4 ]& i5 Y$ y, s: u
    nribin(event = event, p.std = p.std, p.new = p.new,
    ( _2 Z3 `9 Y! M/ n8 l       cut = c(0.3,0.7), : h! U5 u1 W* i9 t4 U
           niter = 500, ' B2 |/ `9 R8 y
           updown = 'category')3 i* g  z4 c- m: a+ b

    : j5 p) D) Q1 R. p15 M( ?1 t- ?  A; V" K; @
    其中,cut是判断风险高低的阈值,我们使用了0.3,0.7,代表0-0.3是低风险,0.3-0.7是中风险,0.7-1是高风险,这个阈值是自己设置的,大家根据经验或者文献设置即可。3 ~& n3 z8 k8 q
    , m- L( b" m6 Y3 q/ b
    niter是使用bootstrap法进行重抽样的次数,默认是1000,大家可以自己设置。
    8 f3 n* }  @3 y; _* w# B
    3 \$ J) J. l1 Vupdown参数,当设置为category时,表示低、中、高风险这种方式;当设置为diff时,此时cut的取值只能设置1个,比如设置0.2,即表示当新模型预测的风险和旧模型相差20%时,认为是重新分类。
    5 y* {/ e2 J1 Q0 C2 a/ y/ v  K2 h; V. ^$ f+ Z8 K2 D- X
    上面的代码运行后结果是这样的:. a  O4 o/ V; O% ?/ o( ?; d

    9 ]+ L2 i; S/ {* l7 K, r- A. pUP and DOWN calculation:0 s/ ~/ {9 ^- w5 b" Y2 t: l
      #of total, case, and control subjects at t0:  232 88 144
    : I3 r3 F& g* m9 w( B% s" y& ?' Z9 y' w/ g' H# m* T0 D
      Reclassification Table for all subjects:
    6 \# A% c: o% U: k. K, O' @6 m2 I        New
    # M: T7 Q: E; KStandard < 0.3 < 0.7 >= 0.7
    3 I; `9 a; o' p  < 0.3    135     4      0
    ! h+ t5 t, x6 W; }  < 0.7      1    31      43 y- H* Q1 u' s9 b& }
      >= 0.7     0     2     55& n5 v) u* Y# G+ H2 M* i
    ! R* {. w$ k5 d6 u$ f% O
      Reclassification Table for case:
    % \4 J/ w7 P, J5 e9 p        New# T$ s& _+ N4 Y1 u& F4 W0 T5 K! D
    Standard < 0.3 < 0.7 >= 0.7
    7 ?! X8 k4 f& T' h1 z0 q# B  v6 O1 T  < 0.3     14     0      0
    6 X9 X% S; ?: P  < 0.7      0    18      3
    ( o% `" g& g4 Q# n, f6 |" L  >= 0.7     0     1     52! T3 T; `& n9 b0 h) W
    2 [8 M$ p6 o) ]. `5 P2 j
      Reclassification Table for control:
    7 y# P; e) @) P/ k; w7 L, n& C        New6 Q- R3 k9 Q( l) y
    Standard < 0.3 < 0.7 >= 0.75 q: G4 n0 J( n3 t3 }- z
      < 0.3    121     4      0
    - J/ v1 ]9 d2 I  T  < 0.7      1    13      1
    ' s8 a& _4 N- s: T  >= 0.7     0     1      3$ X% z. _8 K* {; n
    0 ?7 Y9 l$ D8 ?; j0 S
    NRI estimation:
    . B* n/ g! j  v5 I, ?- o# p$ vPoint estimates:$ f+ B, a! L2 c2 Q
                      Estimate
    . U- M6 i. u4 v! A5 X0 M* L5 \NRI            0.001893939
    7 J1 w" l; ~! T# E* n4 L1 INRI+           0.022727273
    8 b6 `/ Y1 r8 a/ h6 N7 x; kNRI-          -0.020833333
    0 k, z/ x' t# N: y$ ~+ V' T! YPr(Up|Case)    0.034090909) r5 `  R, H+ V) ^7 G" L
    Pr(Down|Case)  0.0113636366 R2 Z4 E, _3 `9 c
    Pr(Down|Ctrl)  0.013888889( R" @2 \9 u/ S
    Pr(Up|Ctrl)    0.034722222. V& t" \4 y, O4 w/ Q
    ) Q% g3 w. C; p9 W4 k
    Now in bootstrap..  D3 h' J2 w! m& Y' o5 i1 ?
    & ]. \3 S5 {( A3 Y0 C& p  B/ Q7 @
    Point & Interval estimates:4 h1 U/ O8 J+ }2 S, `! z
                      Estimate   Std.Error        Lower       Upper
    8 {* b5 ]6 @& R/ nNRI            0.001893939 0.027816095 -0.053995513 0.055354449
    + t3 w+ c8 a1 L" v* hNRI+           0.022727273 0.021564394 -0.019801980 0.065789474- y6 ^  d$ c0 P% v9 ^, N' k+ {8 s
    NRI-          -0.020833333 0.017312438 -0.058823529 0.007518797
      a: P% |: ^" i2 A5 bPr(Up|Case)    0.034090909 0.019007629  0.000000000 0.0721649486 j7 r! F& o: r, ?2 I1 F8 t2 J" Q
    Pr(Down|Case)  0.011363636 0.010924271  0.000000000 0.039603960
    7 O  Y- I7 l; \9 z* B- EPr(Down|Ctrl)  0.013888889 0.009334685  0.000000000 0.035211268
    , t+ O2 }4 H( @* j6 c5 P2 y; \Pr(Up|Ctrl)    0.034722222 0.014716046  0.006993007 0.066176471$ A- h) L) I: n& a% F9 D9 {2 D. _6 K

    6 `& a' w$ Y; e# S8 U( L1
    ( J/ Y* r' Y- F首先是3个混淆矩阵,第一个是全体的,第2个是case(结局为1)组的,第3个是control(结局为2)组的,有了这3个矩阵,我们可以自己计算净重分类指数。  z5 c! s0 a( _% z0 _
    / O7 J& a$ l, I
    看case组:
    0 o/ ~, N# |/ q" G! r9 O
    $ X+ h: ?$ H) L7 D2 A! a9 q净重分类指数 = ((0+3)-(0+1)) / 88 ≈ 0.022727273! N+ f  ?8 {. Y2 Q6 `

    " b' `3 L& C" w. H2 ]7 o8 u  \0 j再看control组:% E" s2 e6 S: P2 M

    2 p: j; |% \6 k: X1 B/ A6 I净重分类指数 = ((1+1)-(4+1)) / 144 ≈ -0.0208333336 ?3 G7 D" W$ w  @

      B- S/ F$ y' f( Y% s相加净重分类指数 = case组净重分类指数 + control组净重分类指数 = 2/88 - 3/144 ≈ 0.000315657) |; c9 {7 T" Y1 r, c9 b1 l

    + z0 z- n) k; P1 W2 I5 x再往下是不做bootstrap时得到的估计值,其中NRI就是绝对净重分类指数,NRI+是case组的净重分类指数,NRI-是control组的净重分类指数(和我们计算的一样哦),最后是做了500次bootstrap后得到的估计值,并且有标准误和可信区间。
    6 j+ `0 U' u2 G9 l7 H, n. C4 G0 H" J; p
    最后还会得到一张图:
    6 ]% G7 u1 e3 ~/ F3 ^0 b( h, t' G
    - r6 U) x4 |) m- f5 G4 ^这张图中的虚线对应的坐标,就是我们在cut中设置的阈值,这张图对应的是上面结果中的第一个混淆矩阵,反应的是总体的情况,case是结果为1的组,也就是发生结局的组,control是结果为0的组,也就是未发生结局的组。9 g/ y  x; \7 x# A9 B

    ) r7 i, S5 F3 C7 I  wP值没有直接给出,但是可以自己计算。4 o$ _0 _$ T6 j; M9 U* W. m! v
    . u& A/ {2 {3 E
    # 计算P值
    3 w8 k- |" g+ W, q! S  tz <- abs(0.001893939/0.027816095)% v) A- m. b$ i1 h: o
    p <- (1 - pnorm(z))*2
    & w  T6 R. n& @- y! vp3 b% Y  Z8 J& c6 x  s( R
    11 }) b* C7 t5 P8 |7 a) D, I, d2 h/ U2 _
    ## [1] 0.9457157
    1 C% w8 X" x: F" c' }- D" R' W& E( h15 x; _7 A/ T% q/ O. X3 Q( ^# R
    PredictABEL包- G: J4 C  s2 W& z' }) T7 L8 c( `
    #install.packages("PredictABEL") #安装R包1 [# _2 L, i' E- p4 I: B
    library(PredictABEL)  
    % r# V  {9 Z  \9 y% X( e- G+ u+ R9 V% [. m2 j2 |  r. I3 ?  Q  B
    # 取出模型预测概率,这个包只能用预测概率计算
    . k2 \- C* [4 |5 m1 I: rp.std = mstd$fitted.values+ X' W$ c% P0 P9 P9 _7 G" m3 m$ U
    p.new = mnew$fitted.values ) U7 K# G, Z7 I( L, V7 _  k
    1
    * _) a$ K) |) X2 T) S  B然后就是计算NRI:+ b' T; G6 r4 {; J7 I

    * d; z: W5 j9 D' |6 i: l- tdat$event <- event
    3 I1 s3 d/ k/ W
    # W0 z) l  v6 ^) C4 Lreclassification(data = dat,7 @6 X/ h( I/ ?& g
                     cOutcome = 21, # 结果变量在哪一列
    & `9 A  S- J, Y9 n, f' y1 D                 predrisk1 = p.std,
    " C6 u5 `% |1 T$ ?, `/ Z; K                 predrisk2 = p.new,$ S0 M: P; y% C& n) c: |: A! P
                     cutoff = c(0,0.3,0.7,1)- @+ `8 e  o; v7 i0 s
                     )
    5 `- ~, ]( \7 L18 T: y9 n* G$ }& q
    ##  _________________________________________
    : U6 ~) g& B0 D3 P+ J( e+ Z" v##  3 g; @) o/ l8 K) l. F, `* H0 J
    ##      Reclassification table    $ {, j: X+ A9 y! h
    ##  _________________________________________" z, _- e( w+ x. t1 I5 N
    ## : ?0 G& {# l7 H  h
    ##  Outcome: absent , N& G2 D2 o2 s) S* c
    ##   
    * W' T. x  S) a4 L: v  K6 I##              Updated Model
    ' w, F6 v/ }3 Q! Q## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
    9 k5 |1 f: m8 ]2 J5 S9 J##     [0,0.3)       121         4       0               3
    6 k4 W9 T  ?4 g% U; J; s( u/ R##     [0.3,0.7)       1        13       1              13! B- i1 x8 h+ R! _2 s: h
    ##     [0.7,1]         0         1       3              256 r1 W7 b) c8 n2 l0 Z. {
    ##
    & g' S" C6 |/ @% G" k" Y##  
    , Z( k8 {8 t" u3 H. n1 K##  Outcome: present
    7 h  U9 {; H8 j4 i  q5 J" M( S##   
    1 g) y6 D! i0 i2 T3 A7 D. @##              Updated Model
    ' A* n% @: \+ h  r3 j4 l3 x## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified  m! @+ {- s# R* d7 _# Y  C: ]
    ##     [0,0.3)        14         0       0               0# b' y6 [5 b2 j8 @( T4 I2 C. \
    ##     [0.3,0.7)       0        18       3              14
    ) y) w# S& Q6 h  Y  J1 p##     [0.7,1]         0         1      52               2
    5 T) _3 t9 E6 z6 ?  a##
    ! ]# _7 W; q6 Y' u2 \# u' d+ ~7 V' Y##  
    8 Q) w4 k+ [  _) y5 C##  Combined Data
    - f( m/ M* d: J! A, Q1 u##   : y* J% H0 l6 j4 h- S& S% e4 J; S
    ##              Updated Model
    ( g% ^! g& z( ?. h+ k6 L8 y## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
    3 E$ U$ }2 |. P, H- k. Y##     [0,0.3)       135         4       0               3
    - e; [' d" m# Y% g##     [0.3,0.7)       1        31       4              14  f$ P+ b" g% ?  |/ i+ K1 I$ k
    ##     [0.7,1]         0         2      55               45 D0 [- P& f! v1 u& h
    ##  _________________________________________! A4 U. v. J/ N7 {
    ##
    2 K& g; g/ r- P$ \! Q4 t2 P9 n3 S##  NRI(Categorical) [95% CI]: 0.0019 [ -0.0551 - 0.0589 ] ; p-value: 0.94806
    1 b; w' v6 N  S: K9 |- E9 U% y##  NRI(Continuous) [95% CI]: 0.0391 [ -0.2238 - 0.3021 ] ; p-value: 0.77048 ( Z3 w$ U" O& \& O
    ##  IDI [95% CI]: 0.0044 [ -0.0037 - 0.0126 ] ; p-value: 0.28396: u( o% x7 U- r8 L1 w

    : E" {& U8 c; \7 ?+ e& P1) K/ Z" t, N/ r* u, k* R" O
    结果得到的是相加净重分类指数,还给出了IDI和P值。两个包算是各有优劣吧,大家可以自由选择。
    - h6 K$ [' Q9 P, n; T
    8 r8 A/ x: \; p9 @生存分析的NRI
    ! o$ a- b& L4 ]' N! y+ B. I+ D8 w# R还是使用survival包中的pbc数据集用于演示,这次要构建cox回归模型,因此我们要使用time这一列了。6 T& |( q6 y8 c, `; I
    # |1 k  o0 h7 a
    nricens包
    # }8 X' w# c: a. rlibrary(nricens)4 F0 Q" `; \1 k4 c
    library(survival)5 R8 A, ^0 J; m; @' ?) I9 |
    . c9 E! S1 J7 Q& T7 R: k
    dat <- pbc[1:312,]* f3 x9 o" O; V3 Q( e
    dat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡
    " X0 y! G/ [! N4 a+ S& x3 S* ?: @1, N9 B& I( ^- Y0 @; t
    然后准备所需参数:8 E4 U; M! U9 ]3 x& g
    , E; }0 [6 M' ^+ |
    # 两个只由预测变量组成的矩阵
    * b0 |" f' j! Wz.std = as.matrix(subset(dat, select = c(age, bili, albumin)))
    + l# c: m; {. X1 j- J2 {9 r5 Iz.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))
    ( z: K6 R" b; P" ^. E
    1 d( ~7 E- V7 x, |9 n: p# 建立2个cox模型
    . `% S7 d% y' K  {/ pmstd <- coxph(Surv(time,status) ~ age + bili + albumin, data = dat, x=TRUE)2 r. K7 x5 F+ L& n* C2 |6 y$ g
    mnew <- coxph(Surv(time,status) ~ age + bili + albumin + protime, data = dat, x=TRUE)( W# q* ^' G: Z& V& ^* n# W, D) P

    3 v8 O! w4 l; i& }  J) x# 计算在2000天的模型预测概率,这一步不要也行,看你使用哪些参数
      n. r! r$ }% A# `( Lp.std <- get.risk.coxph(mstd, t0=2000)$ k( I3 p7 M% O/ h& O% N8 b
    p.new <- get.risk.coxph(mnew, t0=2000)
    4 z# d# h% ^- u* ?: }) o0 k1
    / J6 b$ b5 D/ m! ^计算NRI:% _. q! P( B# p. L/ f# f9 z7 J

    6 E: D8 W0 Q4 mnricens(mdl.std= mstd, mdl.new = mnew,
    8 ]2 Z8 ]# i7 W7 I        t0 = 2000,
    * p* Y$ w5 P7 v# T) t        cut = c(0.3, 0.7),2 {/ [) d% m% C1 v- @  ~' f
            niter = 1000, . p  X1 t% l! \% ^2 f+ t* y* X
            updown = 'category')
      J1 ]+ H; _7 _- B1 f" C5 Z  K7 X6 a1 h& h' B, U% E8 H" E
    UP and DOWN calculation:
    ( m! D* n; N1 n$ E6 l1 S1 V  #of total, case, and control subjects at t0:  312 88 144/ B! r# j8 \8 G0 o

    / S( c! A2 @# \  m! P+ g, b+ b* j  Reclassification Table for all subjects:
    9 r* j# x5 C& D/ s. ], U5 i- ]        New5 {4 z7 r; K# ]" V3 P
    Standard < 0.3 < 0.7 >= 0.7/ D8 o) g  w4 ^7 m
      < 0.3    202     7      02 ?  [% b% Z1 j# H7 ?
      < 0.7     13    53      6( F" f6 C3 |+ ]5 P
      >= 0.7     0     0     31
    8 @  h$ `. u- u. ]4 q. Q
    5 @9 R- s5 ?. e& g  Reclassification Table for case:
    / e8 c* G6 i: W8 ~+ _8 Y+ T2 a        New: m" E  v  n6 _5 R+ _5 n8 S
    Standard < 0.3 < 0.7 >= 0.7
    8 c. _5 ?- c7 K! K& E, [( y) e" r  < 0.3     19     3      08 w9 g% [5 b0 w7 C
      < 0.7      3    32      4; T6 Z, e3 k; L/ B  h: c
      >= 0.7     0     0     27% W/ K6 _, h/ W2 R( b* c) w
    * o2 [/ y/ p4 v% U" s! K
      Reclassification Table for control:0 h0 \2 I4 D$ c6 L7 y" K! @* ~- b6 R
            New! e) c! ?% ?$ f) M" ]& Y
    Standard < 0.3 < 0.7 >= 0.7
    ; d# n! e8 T! @& U  < 0.3    126     3      0
    , P6 i3 v1 I) o  `  < 0.7      5     7      27 L" p( m% v3 [. p. ^1 J+ z8 o
      >= 0.7     0     0      1$ a# g5 q/ _& ^" S

    . ^/ g( G0 N- P/ A3 l. t2 D3 E2 \NRI estimation by KM estimator:
    5 e& A1 y5 _: v, H8 l8 G! T# K
    6 l& l  W! |7 s  nPoint estimates:
    # Q8 T7 w  d+ [  F( F7 x' V                Estimate
    . Y* q# b, B, Q3 I* U! NNRI           0.05377635! f3 j. Q4 u4 N4 a, f
    NRI+          0.03748660
    - o# Y* k0 ]) s& B% Z5 UNRI-          0.01628974
    $ h. Y: G- a5 K* d' ~1 x1 qPr(Up|Case)   0.07708938
    $ _& U& D0 r' K: j- ]# qPr(Down|Case) 0.03960278. U4 E/ \- A: B
    Pr(Down|Ctrl) 0.04256352
    ' }+ D/ W% N0 i' K1 vPr(Up|Ctrl)   0.02627378
    7 x7 R) l  m6 E, h& }+ a! |5 v* I$ ?4 [- R3 g' l) A+ h
    Now in bootstrap..
    " n7 F) q/ ?0 _9 J+ T' a3 L1 j) c+ W( P0 I* F1 y1 n
    Point & Interval estimates:' e+ V3 a  _/ u: L
                    Estimate        Lower      Upper4 Z, D6 n5 R9 j& M8 b3 u
    NRI           0.05377635 -0.082230381 0.160581721 L6 D* Y3 ~  t4 w* s
    NRI+          0.03748660 -0.084245197 0.13231776
    5 i5 Y7 t' ?5 Z8 cNRI-          0.01628974 -0.030861213 0.067536164 i6 {2 Q* H% O) E% J- K! s# j( \
    Pr(Up|Case)   0.07708938  0.000000000 0.19102291
    , I( E( D" @) m4 iPr(Down|Case) 0.03960278  0.000000000 0.152360160 J0 o* b' o9 F3 Y8 H. `( `
    Pr(Down|Ctrl) 0.04256352  0.004671535 0.09863170: J2 k! l! B8 u& R; t
    Pr(Up|Ctrl)   0.02627378  0.006400463 0.05998424
    ( Z$ X% k1 g0 {, U2 X
    1 z: v/ |: ^5 e14 z8 A" U" p3 Q" Y4 ~& U1 Q+ w4 D
    / F( a" p& h5 E" K3 d
    Snipaste_2022-05-20_21-49-38
    ) s9 v) V: z% z% {8 T6 j结果的解读和logistic的一模一样。- s) `0 N8 X: p* }
    # N7 O! J" i2 f6 F! ]
    survNRI包
    9 y3 v: Y0 U7 F* T. h/ @: k5 d7 G# 安装R包
    $ s* b7 V, A$ D; gdevtools::install_github("mdbrown/survNRI")/ r+ x% m8 H/ d8 h- p
    1% k4 f! H- P* x
    加载R包并使用,还是用上面的pbc数据集。6 n; n* e; H: Y& Z% ?% @6 B
    ( n2 d9 p  }5 p1 t
    library(survNRI)
    : i* c4 [: A: K! |) H1
    $ Z2 i4 [% C7 J0 l4 T## Loading required package: MASS
    - K' g" l8 h- l7 `- Z$ u: I3 r! Z" D' |1/ ?) G2 y# P+ z9 _
    library(survival)) r, W4 C' q' e2 X3 M, }
    7 ?3 |% J# a7 t* e& m3 m" T! q
    # 使用部分数据
    ; d: b( G, x3 H! m8 z8 tdat <- pbc[1:312,]1 m% e+ l% W2 D9 Z5 f; r) b% Y
    dat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡
    : E+ I5 C: }4 k1 j7 n
    # k  f. s1 X. o' y8 j5 Ires <- survNRI(time  = "time", event = "status", % m! T# {+ a  D
            model1 = c("age", "bili", "albumin"), # 模型1的自变量( Y  T( h& t6 N2 [! E
            model2 = c("age", "bili", "albumin", "protime"), # 模型2的自变量
    , L7 D" P% a. G        data = dat, 3 I; A8 E. i  p: O3 A. ?: V, }
            predict.time = 2000, # 预测的时间点
    6 s1 E+ w# e  Z: v; T        method = "all", 2 k5 N- p, Y. X2 W7 ~- y8 I
            bootMethod = "normal",  
    0 d+ E# `( y' I+ |# [2 T: z& Y        bootstraps = 500, / H  r$ f9 ~4 e2 V9 r
            alpha = .05)/ I. y& H: m# k4 g+ G8 y

    * X8 b. {! `9 J: ~6 p* W- P1 _% T1
    ! M5 }  L1 B/ ^9 [" d4 `/ ~) |查看结果,$estimates给出了不同组的NRI以及总的NRI,包括了使用不同方法(KM/IPW/SmoothIPW/SEM/Combined)得到的结果;$CI给出了可信区间。
    ( s* \+ H! T1 f# y3 x4 o8 a; j) `+ T' b2 P, d" e+ ^
    res
      ]1 Z2 a8 x1 @" d14 @' J, Z. V) @, w% [# s2 V2 p
    ## $estimates
    ( A3 H( ^9 z+ @' C##            NRI.event NRI.nonevent       NRI
    / |* L0 p0 x; U$ W6 p) _## KM        0.20445422    0.3187408 0.5231951
    - {, k9 u/ P6 o0 M4 v/ B## IPW       0.22424434    0.3273544 0.5515987
    & g1 B$ s% f4 p. p$ Q0 B## SmoothIPW 0.19645006    0.3144263 0.5108763/ n* M( ^0 e. s* u! `
    ## SEM       0.07478611    0.2632127 0.33799881 t" i) \% ?+ F$ P( B) B
    ## Combined  0.19633867    0.3143794 0.5107181
    ; a5 k$ y# w% h7 L9 A+ f! B& v  H##
    4 z5 C$ l8 w- \' B. `## $CI  p: R$ X7 i  Q! i3 q% [! D
    ## $CI$NRI.event
    5 K7 l: f% {1 ?##                     KM         IPW   SmoothIPW        SEM   Combined9 t3 J$ H' Y. C* y& I2 h
    ## lowerbound -0.03915924 -0.02185068 -0.04724202 -0.1162587 -0.0473723
    4 a) D  A9 M7 @## upperbound  0.44806768  0.47033936  0.44014214  0.2658309  0.4400496
    + N, O; O8 F3 \7 ^( w##
    6 ?! T4 q; r- y$ W* o! Y' t: P% K## $CI$NRI.nonevent
    - F6 j- g) D1 V##                   KM       IPW SmoothIPW        SEM  Combined
    ; T3 r1 V* g0 v( f! w5 D## lowerbound 0.1317108 0.1396315 0.1286685 0.08638933 0.1286426: X9 H6 {- U+ }8 T' K- K6 V, E
    ## upperbound 0.7102251 0.7393216 0.6966341 0.51482212 0.6964549; u6 r# m$ g2 o. t. C# z( Z
    ##
    " |9 S! v' Q& M, ]3 y+ I0 I% Y## $CI$NRI
    4 u& ?5 Q, Z9 J##                     KM         IPW   SmoothIPW         SEM    Combined
    + s4 a4 y* L  k. y2 J# G+ T## lowerbound -0.05112533 -0.04569046 -0.05439863 -0.04132364 -0.05443409+ y" d* y( d- q( k) R/ X+ k
    ## upperbound  0.89306122  0.92464359  0.87970125  0.64253510  0.87953153
    8 r' `) O# A6 f##
    # T9 x* L: q% ?* [; ~: N# r##
    ; y. l( j% i/ u4 C( c9 C) B3 G7 q## $bootMethod
    + v! D6 Q  g  e; N! P## [1] "normal"0 k2 K2 d- e+ k2 F' F! J; d' K3 h
    ## 0 J) M1 h" X+ b5 w" D
    ## $predict.time
    1 l( P; x# b  w) b4 E## [1] 2000/ a: T: l9 k$ j$ |' B+ p
    ## 4 t3 [; p0 p. y/ K, ]
    ## $alpha% `7 _4 g: }  N: Z+ b
    ## [1] 0.05
    * ]* g  Q4 k  L8 C4 x+ o6 E## " K1 D& G3 Q; I; P, ]$ ]. x  w7 l9 F2 Z7 @
    ## attr(,"class")
    : \- k4 X5 D1 {) o## [1] "survNRI"
    3 V: L  M9 w  q$ u7 k# H/ D" N3 ?, e% N" ^! p
    1" |3 Q4 B$ C: g" C& |4 a1 `: H
    OK,这就是NRI的计算,除此之外,随机森林、决策树、lasso回归、SVM等,这些模型,都是可以计算的NRI的,后面会继续介绍。大家如果有问题欢迎在评论区留言。
    # @- V6 ?6 l2 U1 g7 x; g4 Y! M4 {
    本文首发于公众号:医学和生信笔记8 k$ D  [. j. Z0 x! N. I) {% f
    ' p% n4 w9 e* W  z: v7 R$ F# L
    “ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。
    . k0 \. T4 p# y本文由 mdnice 多平台发布
    ! [7 Z6 k6 f( U8 ?————————————————
    ( R  X# M1 z" ], @版权声明:本文为CSDN博主「阿越就是我」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    ) F9 V1 w1 P; f0 l& |原文链接:https://blog.csdn.net/Ayue0616/article/details/1267680063 k+ _# C. o& L
    7 D+ q' J1 f3 C* t! Z( `

    , p  m: @$ H4 `5 d; ^- G
    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 10:44 , Processed in 0.856292 second(s), 51 queries .

    回顶部