QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2393|回复: 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
    2 Q; D! ~+ t. B$ d2 V
    净重新分类指数NRI的计算
    / m; z# x" r& Q# ]) O" Y“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。! m! V% U% E5 Y& w
    NRI,net reclassification index,净重新分类指数,是用来比较模型准确度的,这个概念有点难理解,但是非常重要,在临床研究中非常常见,是评价模型的一大利器!
    3 z4 k( m8 _! N1 u, U/ r* H8 P1 l, _. P6 K
    在R语言中有很多包可以计算NRI,但是能同时计算logistic回归和cox回归的只有nricens包,PredictABEL可以计算logistic模型的净重分类指数,survNRI可以计算cox模型的净重分类指数。
    # p! F) v% ~( T$ r* Y. A+ K$ I" }& t( G
    logistic的NRI1 T2 v- S. J) C
    nricens包, I: s0 Q6 b  C( R8 W0 I
    PredictABEL包
    : Y. Q! D; _: ~/ p5 H  m) K) {生存分析的NRI* Y* {5 Z) b! E& K
    nricens包
    & U" ]3 k, W  U6 v0 @  p: LsurvNRI包
    - {: ~, d2 b' Z- Ylogistic的NRI
    ' E' {# }0 D% H8 M7 inricens包
    6 ^" A1 w- h0 u) ~#install.packages("nricens") # 安装R包. ]# z4 l/ M6 Q3 k
    library(nricens)
    , `6 C- t$ G" z" ^1) d1 d9 I4 `/ y" B( c
    ## Loading required package: survival
    : s$ P7 B. t5 V1 i0 M  d10 N5 u% Z: ]6 A: z  L
    使用survival包中的pbc数据集用于演示,这是一份关于原发性硬化性胆管炎的数据,其实是一份用于生存分析的数据,是有时间变量的,但是这里我们用于演示logistic回归,只要不使用time这一列就可以了。
    " j" `  R: J4 g1 G7 O. b# b$ ]) ]
    8 }5 m3 [1 P8 r2 R4 Qlibrary(survival)/ b* ]% C2 u0 v; G0 X0 r
    ) b1 s3 x- q4 `4 e3 D$ f
    # 只使用部分数据" p& s0 E) e7 Z+ f6 j. j
    dat = pbc[1:312,] ; o; _- S% R9 C, h
    dat = dat[ dat$time > 2000 | (dat$time < 2000 & dat$status == 2), ]8 i1 h! d$ G( F% l0 C6 ^1 n
    ! Q" _, o  g2 ]  h/ b' Q# k
    str(dat) # 数据长这样& G. c+ D5 \" j7 C; z5 y
    1. m  M! c, e$ _" U+ S' I* M3 p( ]
    ## 'data.frame': 232 obs. of  20 variables:
    " g. V: O  I4 `5 z$ f1 t##  $ id      : int  1 2 3 4 6 8 9 10 11 12 ...- ?) F' n- Y' w6 F+ J
    ##  $ time    : int  400 4500 1012 1925 2503 2466 2400 51 3762 304 ...$ c( x: [4 O7 T* O, p
    ##  $ status  : int  2 0 2 2 2 2 2 2 2 2 ...
    & J, p+ [( [4 h##  $ trt     : int  1 1 1 1 2 2 1 2 2 2 ...
    ! d, F0 H* I0 D. s1 h7 p1 ^& \##  $ age     : num  58.8 56.4 70.1 54.7 66.3 ...- s' o6 u6 `' x+ P9 ?# c
    ##  $ sex     : Factor w/ 2 levels "m","f": 2 2 1 2 2 2 2 2 2 2 ...& V+ z, G" T8 B- k: L# S
    ##  $ ascites : int  1 0 0 0 0 0 0 1 0 0 ...* @7 ]4 h. Z5 J+ z
    ##  $ hepato  : int  1 1 0 1 1 0 0 0 1 0 ...0 {  r8 d. l0 w$ H
    ##  $ spiders : int  1 1 0 1 0 0 1 1 1 1 .... H9 M' \% T; f0 \
    ##  $ edema   : num  1 0 0.5 0.5 0 0 0 1 0 0 ...7 R: x" L6 q1 h  {% @
    ##  $ bili    : num  14.5 1.1 1.4 1.8 0.8 0.3 3.2 12.6 1.4 3.6 ...: F  r; }, D, A6 d6 ~' m5 A. l
    ##  $ chol    : int  261 302 176 244 248 280 562 200 259 236 ...
    & X3 t/ H; R$ [: x1 q! A##  $ albumin : num  2.6 4.14 3.48 2.54 3.98 4 3.08 2.74 4.16 3.52 ...+ U% q- N+ p/ O5 k3 D
    ##  $ copper  : int  156 54 210 64 50 52 79 140 46 94 ...
    1 ]9 N9 M% I( G; Y3 a##  $ alk.phos: num  1718 7395 516 6122 944 ...
    3 V  t8 E" e5 {' {6 `& a& w, E##  $ ast     : num  137.9 113.5 96.1 60.6 93 ...
    / {+ |$ l& u' n. O1 \/ k##  $ trig    : int  172 88 55 92 63 189 88 143 79 95 ...
    1 m8 ?! M: a& @' Z( Y* G# [4 q##  $ platelet: int  190 221 151 183 NA 373 251 302 258 71 ...
    4 D1 z/ C( ]5 p! w##  $ protime : num  12.2 10.6 12 10.3 11 11 11 11.5 12 13.6 ...% o& v: m! y) G% i, x
    ##  $ stage   : int  4 3 4 4 3 3 2 4 4 4 ...
    1 K- @& Z5 X. u; m; C1 `. k( {/ C
    1( C# e8 w# t- q3 j+ u; e
    dim(dat) # 232 20+ C2 h3 K5 a) I  r
    1; o, ~" b) J. z9 p4 v1 V- X( L- S
    ## [1] 232  20
    ' j, V& Q+ v1 {! B' w) h18 c' B! G0 x4 u$ y/ D2 L$ m9 n' \
    然后就是准备计算NRI所需要的各个参数。
    $ {  {0 F7 M/ e3 O& M# A2 K& j& E6 A- d$ W' n- F
    # 定义结局事件,0是存活,1是死亡& e0 e& F0 S9 s3 k( U
    event = ifelse(dat$time < 2000 & dat$status == 2, 1, 0)
    / ~3 Q9 \; H8 O% @" V* s/ N5 h2 q
    # 两个只由预测变量组成的矩阵& C: @1 U; N# n6 C# I0 H- N
    z.std = as.matrix(subset(dat, select = c(age, bili, albumin)))5 f$ Z* g5 v! D0 A% q
    z.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))
    + C0 s/ m% m: o, z+ ^2 q
    5 T3 Y, v- N% X$ C# 建立2个模型) J" V, Z' H! z' K( Z9 z
    mstd = glm(event ~ age + bili + albumin, family = binomial(), data = dat, x=TRUE)
    ) m0 b  W, o8 P1 R  I5 m, jmnew = glm(event ~ age + bili + albumin + protime, family = binomial(), data = dat, x=TRUE)2 w9 p$ [2 x' \8 S+ T
    3 c# \1 f( p% `2 T, o6 A" t5 H% `- b- z
    # 取出模型预测概率7 w! _6 c) s  Z* B* @+ N3 M+ r* U
    p.std = mstd$fitted.values
    4 M0 D2 L/ c. y2 I- R- op.new = mnew$fitted.values
    3 D$ T! j" P, H" q+ ~3 H3 q9 c- o! f8 G
    1
    1 I* [. \5 o$ W4 i- E4 v然后就是计算NRI,对于二分类变量,使用nribin()函数,这个函数提供了3种参数使用组合,任选一种都可以计算出来(结果一样),以下3组参数任选1组即可。 mdl.std, mdl.new 或者 event, z.std, z.new 或者 event, p.std, p.new。
    % w* e( V% M$ l6 ?2 x" h0 l& b/ M& a: D4 u
    # 这3种方法算出来都是一样的结果
    9 m8 ]. s7 [: q: S# Z8 d
    # H5 j  i* c# a: [8 a# 两个模型2 w+ H4 W5 n) q- b: H) ?" j
    nribin(mdl.std = mstd, mdl.new = mnew, 4 z' b& H. X) q/ g' x% y
           cut = c(0.3,0.7), ' \' l  r0 C! D* b; b: y* |
           niter = 500,
      j9 D! E* C# l8 Y, ?, k) N       updown = 'category')+ d9 R) q. X/ r% N$ o* H

    # t1 |; m" Q( H3 V6 }& k0 H# 结果变量 + 两个只有预测变量的矩阵" ]1 w+ O. o- S
    nribin(event = event, z.std = z.std, z.new = z.new,
    1 P* T; r! i, }& g6 T  _       cut = c(0.3,0.7), 3 g  a5 V$ p9 P# k, Q
           niter = 500, / o! D& y8 t$ U1 z' s
           updown = 'category')
    * ?! w4 z5 R; b
      V6 Z, \6 s) y6 \## 结果变量 + 两个模型得到的预测概率
    * M: t5 n9 `! r; u  t5 ~' u( Snribin(event = event, p.std = p.std, p.new = p.new,
    ; v" g+ x# x5 p7 E  v       cut = c(0.3,0.7), - j! ?8 |$ s$ P3 X' @
           niter = 500,
    3 F* A8 b; S0 M" H4 O: P       updown = 'category')
    $ X$ ]0 ?5 J/ Z' e  B) b# l3 E
    # A' o+ r! Q* I2 [  p: B% f* }! N17 Y+ C0 Z$ o& X. @3 R- t5 }9 g
    其中,cut是判断风险高低的阈值,我们使用了0.3,0.7,代表0-0.3是低风险,0.3-0.7是中风险,0.7-1是高风险,这个阈值是自己设置的,大家根据经验或者文献设置即可。/ R% b5 j/ I) G! s  u
    $ V" e8 x$ I7 h  _  ]
    niter是使用bootstrap法进行重抽样的次数,默认是1000,大家可以自己设置。+ I! s- s1 {9 h0 M  H0 P

    4 V/ @9 H; \; Supdown参数,当设置为category时,表示低、中、高风险这种方式;当设置为diff时,此时cut的取值只能设置1个,比如设置0.2,即表示当新模型预测的风险和旧模型相差20%时,认为是重新分类。
    2 W4 r0 n3 P7 ]* _- T
    ! J1 G, O" _7 f# m, z. x0 L上面的代码运行后结果是这样的:: K) L& i+ X, i/ f/ L5 p" o6 N

    ; M8 i: {8 F1 Z' g: N1 IUP and DOWN calculation:2 R2 |# D2 L- q0 [0 E
      #of total, case, and control subjects at t0:  232 88 144
    ) ?: o. m# l2 r0 L8 j6 j2 \2 ~: R" L$ p% W  z" j) k
      Reclassification Table for all subjects:
    0 i+ q' t8 @. S. s        New5 }7 r. [' R; m1 d4 l" L+ I
    Standard < 0.3 < 0.7 >= 0.7
    ' o& c' [- @/ [5 S  < 0.3    135     4      0
    5 {6 Y- I$ c" k1 [5 T7 }" U( ]  < 0.7      1    31      4$ ^" t) H0 B, Z+ v7 m1 O7 p/ X
      >= 0.7     0     2     55
    , e2 A8 F6 P3 k0 y# l# x) [1 a! ]2 \4 F% c  D
      Reclassification Table for case:" [' ^$ A. E! x% q5 L
            New. m" C' Q% e! X% `6 I
    Standard < 0.3 < 0.7 >= 0.73 H- x$ k- \2 h
      < 0.3     14     0      0! v+ ^6 y& {+ h5 ?
      < 0.7      0    18      3
    # ?/ }+ D9 h- j9 K' X& h  >= 0.7     0     1     52
    & c( B  M: O1 i7 R6 H3 ]) O
    ' C* A. }0 u  g4 }9 s  Reclassification Table for control:& b( [* _$ H5 r) O5 N3 S2 \; b
            New
      a( Y, Z2 x4 F' s& [Standard < 0.3 < 0.7 >= 0.7
    : O$ N) h# x$ S  < 0.3    121     4      08 b5 A4 l! i- f
      < 0.7      1    13      17 _) P- b" K# z0 q5 P  [" i$ H
      >= 0.7     0     1      3+ b4 D) I2 {1 p
    : [. g7 D# R+ s" D0 E8 X  c
    NRI estimation:  S/ m3 i) h# O! j0 v
    Point estimates:
    * ]' |) M- K. |& v/ _" _) M" L" l                  Estimate
    . t5 Q/ s0 U" \4 oNRI            0.0018939399 T, N. K$ _# e' X' Z0 _- o
    NRI+           0.022727273
    " f3 q) R: [2 w7 E8 t% h! sNRI-          -0.020833333
    9 U; K, Z6 `4 G, O% IPr(Up|Case)    0.034090909, M! \* a% }/ v- r6 N
    Pr(Down|Case)  0.011363636. I% C$ j- m6 O4 \. F, p1 m/ h- m9 ?
    Pr(Down|Ctrl)  0.013888889# Z( o' R0 J9 {, ^2 f/ X
    Pr(Up|Ctrl)    0.034722222% h4 P3 O; N, W  L* i

    6 R2 p9 t, ~% v$ F$ WNow in bootstrap..3 o$ T. E9 v/ Y* |: L6 l* s
    ( E% ~0 i* a9 ?# U  p# ?5 q
    Point & Interval estimates:
    ! ^# z/ x0 T  K7 a7 a: m                  Estimate   Std.Error        Lower       Upper
    2 l/ F/ Z" p" dNRI            0.001893939 0.027816095 -0.053995513 0.055354449  n9 }; a% @, N1 D- e9 E' F( I5 l
    NRI+           0.022727273 0.021564394 -0.019801980 0.065789474
    ! H% u! w" r4 m: NNRI-          -0.020833333 0.017312438 -0.058823529 0.007518797/ p. w2 u5 B$ F7 j& ?9 v5 a# q5 r
    Pr(Up|Case)    0.034090909 0.019007629  0.000000000 0.072164948
    9 h- B/ Q: i2 ^0 G- ~& H8 J0 wPr(Down|Case)  0.011363636 0.010924271  0.000000000 0.039603960
    3 Y; ^$ ?5 ^" {4 ^9 l2 }Pr(Down|Ctrl)  0.013888889 0.009334685  0.000000000 0.0352112685 Y7 J$ j0 h- [+ V3 Q0 B
    Pr(Up|Ctrl)    0.034722222 0.014716046  0.006993007 0.066176471; u5 p$ Q4 S) f, y) G0 }4 q

    ( ?! m# Q' k' R/ ]& Z. n5 V1
    4 \0 X! E" B& x2 W* ~首先是3个混淆矩阵,第一个是全体的,第2个是case(结局为1)组的,第3个是control(结局为2)组的,有了这3个矩阵,我们可以自己计算净重分类指数。
    # k2 d- w2 N& T0 }1 g* N$ W# U- Q  a  b/ d
    看case组:5 V, Z# p/ z/ j# w  s& K& d
    4 E$ a9 j3 O; _$ P0 H
    净重分类指数 = ((0+3)-(0+1)) / 88 ≈ 0.022727273+ n5 y( A; V5 e3 j  ]1 i

    # y* L+ J; m& I, e再看control组:7 w/ ]" a& `; }+ s

    ( V5 [, g; l) M" r3 o  t# j净重分类指数 = ((1+1)-(4+1)) / 144 ≈ -0.020833333# @! ]- ]' q7 \
    : C" V! Q/ |7 T1 U& V5 v& W
    相加净重分类指数 = case组净重分类指数 + control组净重分类指数 = 2/88 - 3/144 ≈ 0.000315657% D4 q' ?- [1 S9 ^' x0 y
    + g2 C, y( i8 P# u! A
    再往下是不做bootstrap时得到的估计值,其中NRI就是绝对净重分类指数,NRI+是case组的净重分类指数,NRI-是control组的净重分类指数(和我们计算的一样哦),最后是做了500次bootstrap后得到的估计值,并且有标准误和可信区间。4 r6 W$ g( m% z) Z+ C8 k& a! f
    ! V8 \% p4 `& z8 W) g3 ^
    最后还会得到一张图:  o1 t  x8 V$ v6 h

    , B4 X: J# C" _6 S这张图中的虚线对应的坐标,就是我们在cut中设置的阈值,这张图对应的是上面结果中的第一个混淆矩阵,反应的是总体的情况,case是结果为1的组,也就是发生结局的组,control是结果为0的组,也就是未发生结局的组。1 J. d0 x7 s5 N

    & o  y3 I3 u  |5 y; z: jP值没有直接给出,但是可以自己计算。' h" {. Y8 c; d$ V

    ; l1 }6 Z% h: w1 H' C0 u/ X7 Q" }# 计算P值# O. i( L, R, U5 {7 i
    z <- abs(0.001893939/0.027816095)
    # ]0 f- b. d! o& e: ]- t' sp <- (1 - pnorm(z))*2% g& ]" J6 a# ^" j/ O" h& n
    p5 V, O4 x2 g- ~4 h
    1: s5 c! t- `6 }: y5 b5 B
    ## [1] 0.94571575 }2 D4 ~& Q, W9 Z. D' u7 `
    1
    1 u) Z# B0 x6 j& g3 R& v' i; m  ~( TPredictABEL包8 B  Z. T( C; U! I8 q
    #install.packages("PredictABEL") #安装R包5 z+ S- m& t! H' C) T6 ]2 d, j: D
    library(PredictABEL)  + @: ]0 j# }! r4 O5 x; e
    , a; G% h& O# Z7 k
    # 取出模型预测概率,这个包只能用预测概率计算
    - F  Q( H( l, O$ b  Zp.std = mstd$fitted.values
    0 X8 b$ x# i" k0 q% P- v5 r. |p.new = mnew$fitted.values
    + C, e+ k# r% P, c" v18 h# f& _& t) ~* V5 N  H4 m
    然后就是计算NRI:
    * @! r! k5 @: `/ ~0 _$ u! Y
    1 I7 h% U/ A- D! |( k7 L* @dat$event <- event
    6 p$ B' l) R1 b& r. _& O0 A  J1 H" ?+ C5 N$ y
    reclassification(data = dat,
    - \) J) w5 e% q1 |/ c/ |                 cOutcome = 21, # 结果变量在哪一列1 f+ h8 M" x. H# `6 ^
                     predrisk1 = p.std,
    1 q0 l1 N" p# c! _' z; _                 predrisk2 = p.new,
    " E  W* ?. d) r6 W; d" ~( _8 w                 cutoff = c(0,0.3,0.7,1)
    - @. w- `! b" `1 w9 Z( w                 )9 h" \1 t; z% {0 ?7 b5 Z
    1
    ; |1 Z; I% U& p( v* `##  _________________________________________
    / @* |' D* U  ^##  ) w. O  A/ y8 ~7 g2 ]
    ##      Reclassification table   
    ( f& _8 O, O. x$ S( |' g##  _________________________________________
    + Z) v/ C6 v% e4 q4 x## ' R, ?: j' z' V4 X
    ##  Outcome: absent
    ( C" h) W: v! Q  W1 I! F##   
    1 D7 s( H* Q9 C/ A' _! d. q##              Updated Model3 T  p* v+ V2 f% X4 O7 M
    ## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
    $ W' P2 D- T9 n4 X* R0 R  ^0 @* u& P##     [0,0.3)       121         4       0               39 s6 _) Z4 I4 C7 Q5 M2 Y
    ##     [0.3,0.7)       1        13       1              13
    " b# v0 \* V6 l! k5 g. P3 f: N0 J##     [0.7,1]         0         1       3              25
    ! ~' `. k$ d. H" b' }& ~& h##
    5 Q( J6 a& a( O" ?##  
    ( P% D' s% @* f% _2 [. Y##  Outcome: present
    7 T' i/ a8 e+ C8 Y. v3 @##   
    1 v+ P: |8 N4 h# H0 A: v##              Updated Model
    " {7 q* a( i8 y) c% C4 u## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
    / `& S$ T0 _6 b" B, b##     [0,0.3)        14         0       0               0
    % W* m" W  L1 ~; C) @+ Z2 ~( O##     [0.3,0.7)       0        18       3              14
    % ^  g7 z! ^+ y) H1 m##     [0.7,1]         0         1      52               2
    / \0 E4 v) G6 F0 }' T##
    3 m1 m0 D' G- [" M$ e##  % T  T/ |  B. t  o" A
    ##  Combined Data # n1 R/ ^" L* X' M( f% `. |# T
    ##   
    % x7 z, m9 y" |5 P##              Updated Model
    ) S3 z  V3 U, A4 p0 F5 j8 y' Y  I## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
    : r7 O5 y' D9 L3 R, _##     [0,0.3)       135         4       0               37 D& l- o0 i9 ]7 N% j6 _4 a
    ##     [0.3,0.7)       1        31       4              14. l8 T/ n+ v' Z; l
    ##     [0.7,1]         0         2      55               4
    6 E/ G5 T" [; r1 B" X5 p! L% d- @##  _________________________________________
    & e! ?2 z# A" h6 n# ^2 c+ c) x##
    5 B3 h, [$ M5 E2 {0 U- W##  NRI(Categorical) [95% CI]: 0.0019 [ -0.0551 - 0.0589 ] ; p-value: 0.94806 6 P2 \% s" \2 H- l
    ##  NRI(Continuous) [95% CI]: 0.0391 [ -0.2238 - 0.3021 ] ; p-value: 0.77048
    & Y3 R3 Z. O) U* R0 g* l##  IDI [95% CI]: 0.0044 [ -0.0037 - 0.0126 ] ; p-value: 0.28396& M7 k: t5 c9 G! q7 d% `

    6 U" r, K. X8 B9 X1  Z) z% [# `0 u0 G" \. h
    结果得到的是相加净重分类指数,还给出了IDI和P值。两个包算是各有优劣吧,大家可以自由选择。
    ( ~3 c7 V3 a; C: l" r; i2 o0 L6 E1 c* j5 w& n! I
    生存分析的NRI! q! B6 {; f7 g# F
    还是使用survival包中的pbc数据集用于演示,这次要构建cox回归模型,因此我们要使用time这一列了。/ w( G- Q6 a* _
    $ [# j" N( T( o
    nricens包
    : F/ K' _# x6 |8 h7 B3 llibrary(nricens)
    ; Y8 ?8 [" h/ Slibrary(survival)) S; O/ S4 T' H) j$ A) Y4 _

    4 Z* a, A0 Y( M, {, J; ydat <- pbc[1:312,]
    % t) p4 J5 q; U0 w5 ]$ mdat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡$ L& @" N# {/ |0 {4 J
    1
    " n- t* P- l- G" A; r然后准备所需参数:
    : [) Y, [% m/ m2 u5 |
    0 l! ^: Z* g0 @) |  E' M, [# 两个只由预测变量组成的矩阵
    6 |7 j4 R5 I  A) Hz.std = as.matrix(subset(dat, select = c(age, bili, albumin)))0 T. D6 j& r1 A% L
    z.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))/ O- ?& }: Y  @2 g" `5 K! ~
    / U( `$ h" b( e% R6 x
    # 建立2个cox模型
    * C" ^7 A% O( vmstd <- coxph(Surv(time,status) ~ age + bili + albumin, data = dat, x=TRUE)7 B' l" U, i) z7 d
    mnew <- coxph(Surv(time,status) ~ age + bili + albumin + protime, data = dat, x=TRUE)6 P1 Q3 d# b; }
    9 _4 T3 s( ?  ^2 K# H
    # 计算在2000天的模型预测概率,这一步不要也行,看你使用哪些参数0 j3 F! t" ]" U" \
    p.std <- get.risk.coxph(mstd, t0=2000)% i; `) C. Z* u* A7 a
    p.new <- get.risk.coxph(mnew, t0=2000). h9 C5 w2 E+ m+ D, ~
    10 n2 ~7 [* B! x8 {  y  v' X2 a- R
    计算NRI:1 B' h  T  F/ @$ o$ n

    , b  F+ r# D+ m" T  T: cnricens(mdl.std= mstd, mdl.new = mnew, $ y/ z% K: Y# ~
            t0 = 2000, $ {; J  o3 E) x5 S
            cut = c(0.3, 0.7),
    8 g! H. ~  C( u        niter = 1000,
    * b1 n* ~7 W9 P: _6 |0 X        updown = 'category')" {0 P; h4 p' ]! G: r; `6 B4 ?- |

    , T4 v, u) ^" i) hUP and DOWN calculation:5 Q& c4 Z0 h" N2 F8 {/ O
      #of total, case, and control subjects at t0:  312 88 144* `" y) g5 f* H2 `( R
    % a6 j8 a# ]2 l
      Reclassification Table for all subjects:; B5 O0 Y9 W5 v: V, z# h
            New
    0 ^9 z% w2 G' K( J* UStandard < 0.3 < 0.7 >= 0.7* c0 _* x8 G# v3 a; L- G( B
      < 0.3    202     7      08 w' A5 N4 W9 X% [. Q& m! t
      < 0.7     13    53      6
    7 S3 ^8 {+ J: @, r2 U1 t2 m9 N7 O  >= 0.7     0     0     31: M& |# d, ^4 K2 p

    % x' Y6 G, j! y5 N  Reclassification Table for case:% b* L# M, j2 O: [: t9 |2 N0 o
            New
    5 n% w  |* p: w0 s& t0 j# D3 _Standard < 0.3 < 0.7 >= 0.7& W/ y2 v" m5 p
      < 0.3     19     3      0
    % ^6 H8 P+ L$ P; Y! q# R2 H0 X: a  < 0.7      3    32      4+ v0 I  l  m, R# n
      >= 0.7     0     0     27
    5 r0 q- \7 Q7 p9 G9 h( A2 M
    $ ]/ ~+ ^6 u2 s1 |  Reclassification Table for control:
    ! _/ S4 V0 y4 Y$ B        New$ Z( d. x  z4 f8 p$ Q' _1 {6 L
    Standard < 0.3 < 0.7 >= 0.7
    : q: a# A$ z8 \+ j, F  < 0.3    126     3      0/ c8 a! [& c$ @2 q2 Y
      < 0.7      5     7      2; _1 a# T. F) U
      >= 0.7     0     0      1( q, ]+ j( E. S( J# P9 i  [

    ) w6 I4 W, b) _NRI estimation by KM estimator:; K$ E0 u  z1 H: o& a& d# R9 {( G/ {

    6 U2 _& k1 |' J" ]: R$ n* j8 \2 [Point estimates:6 s8 l/ q6 ?- J8 f3 p
                    Estimate
    , c! y, L6 h+ C) sNRI           0.05377635
      Z( K9 b# J2 Q( e( }& rNRI+          0.03748660
    : I/ G$ L. y6 k. mNRI-          0.01628974
    $ z+ w. J& x  C2 cPr(Up|Case)   0.07708938' Q* r% b( Z/ M4 w" E/ d
    Pr(Down|Case) 0.03960278) `1 \" r6 p7 ?! |+ z6 g  K
    Pr(Down|Ctrl) 0.04256352+ u+ Y0 ^' `) ~2 D/ f
    Pr(Up|Ctrl)   0.02627378
    # H) I  ^2 T1 Z  b1 e
    + S$ i' M- Q; ~# ?: }0 gNow in bootstrap.." n+ E$ |) t( H* l/ o

    8 H$ R- a; t/ p. S: OPoint & Interval estimates:+ s9 f  W  {# R* [' N+ `0 M) B& ~
                    Estimate        Lower      Upper
    3 t/ V# k+ L; R. J" Q1 a6 ONRI           0.05377635 -0.082230381 0.160581720 A0 L4 w' ~: C- e  g8 n
    NRI+          0.03748660 -0.084245197 0.13231776* P. ]. X! f# K/ ^
    NRI-          0.01628974 -0.030861213 0.06753616
    % s$ @: [7 @( ~8 bPr(Up|Case)   0.07708938  0.000000000 0.191022911 F3 {) F2 N' r& q+ J) q0 ]
    Pr(Down|Case) 0.03960278  0.000000000 0.15236016
    5 V9 m7 r! u6 y% }Pr(Down|Ctrl) 0.04256352  0.004671535 0.098631706 ~$ f  r2 g7 |: }* r- C
    Pr(Up|Ctrl)   0.02627378  0.006400463 0.05998424
    * `- ]# S1 U- G* [) v/ }, F+ V/ D; {/ q. x# ~
    1
    6 t$ T) U8 t* I& G* N4 ?2 }
    + q- z0 D; E) ^' C! c& ?8 _Snipaste_2022-05-20_21-49-38/ r# v/ D& l/ G- F4 n$ I6 J: U
    结果的解读和logistic的一模一样。2 n* F4 j5 a* i) y  G1 u. l
    ( ~* D8 H. y" q( \% K+ j& x8 @
    survNRI包
    & Y1 T# n1 J- P# ^+ D7 N! C# 安装R包# k. a0 D' H( C. `& J
    devtools::install_github("mdbrown/survNRI")
    5 H5 _  u7 i, h8 D; Y: {1
    - o$ f3 b3 `" X+ r' e# r7 \加载R包并使用,还是用上面的pbc数据集。
    3 j" O: E3 {2 W0 s3 T- E. N& Y9 O# `- l
    library(survNRI)+ \" X; `, \0 o' k. ^% ^
    1
    4 |3 d7 E; t% x! S5 a$ x" p! p- w2 a## Loading required package: MASS7 X# F! |) s" P" L+ M& N
    1' K" ?) e/ R9 R5 h$ |
    library(survival)& d0 }( y5 ]0 Z! O1 v5 g! A

    ' p# `+ k5 P; x% K# 使用部分数据
    3 u0 q2 b- E! l  Zdat <- pbc[1:312,]
    % U! g7 z  r9 K! v% c9 e4 v% e& Ddat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡2 o6 Z7 n0 j. x6 `% I1 D* \

    4 w; d% \9 n/ C; Tres <- survNRI(time  = "time", event = "status",
    % I# K4 w1 a; `* V        model1 = c("age", "bili", "albumin"), # 模型1的自变量
    0 _: L! i5 j+ s( t2 c  j        model2 = c("age", "bili", "albumin", "protime"), # 模型2的自变量
    3 e, h5 T/ s9 {& g* |. p        data = dat, ' D8 X& N8 t& \4 |7 ~# t
            predict.time = 2000, # 预测的时间点, b7 k- E; |3 z4 S
            method = "all", ) J# v$ U0 b9 d/ B0 _; t
            bootMethod = "normal",  
    ) ^% k- f% B  M        bootstraps = 500,
    + g1 Y# J2 `4 b0 @, H" ~3 e9 s9 o. D        alpha = .05)
    ! @6 p# n0 l4 @+ s3 Y
    , G9 a- U. s( j( \9 g/ ?3 |1
    $ r  A$ f0 V, X( f4 X查看结果,$estimates给出了不同组的NRI以及总的NRI,包括了使用不同方法(KM/IPW/SmoothIPW/SEM/Combined)得到的结果;$CI给出了可信区间。8 k& b! @* I3 M* \% p
    ) J: m1 J- ~: z6 ~( \
    res
    6 R( v; ?* o0 T! u$ c1
    5 t3 H, Z! S8 X# i! K## $estimates) P  r- G+ J; {( ]0 {
    ##            NRI.event NRI.nonevent       NRI4 u' A7 O9 I3 H$ U; [) z: W
    ## KM        0.20445422    0.3187408 0.5231951! ]5 h2 f& X- m9 `) w
    ## IPW       0.22424434    0.3273544 0.5515987
    8 o% n- u3 b: M; x- K## SmoothIPW 0.19645006    0.3144263 0.5108763
    ( f" k6 t) k/ D# H' K# a$ `## SEM       0.07478611    0.2632127 0.33799880 i" V, d- n$ d; ~' k( m) \  i. X5 i
    ## Combined  0.19633867    0.3143794 0.5107181) S3 R0 \+ t# c: {8 c
    ## 9 E9 j: X5 c9 {3 O% B
    ## $CI# B6 _* u3 t2 q( K# h  Q2 i
    ## $CI$NRI.event
    6 t  g: N' i7 R$ {) O1 L2 ], A) I0 L##                     KM         IPW   SmoothIPW        SEM   Combined
      _3 y% ^. h( n: `## lowerbound -0.03915924 -0.02185068 -0.04724202 -0.1162587 -0.0473723
    7 W( y9 d8 P6 e$ A4 t' E7 }" }$ \## upperbound  0.44806768  0.47033936  0.44014214  0.2658309  0.4400496; [! y* |( v. g' e3 ~1 g
    ##
    ( c1 P+ d2 G2 S3 u- h! s) V) x## $CI$NRI.nonevent
    & l' Z. r8 j8 R% B' v7 B##                   KM       IPW SmoothIPW        SEM  Combined
    8 q0 k7 _- n! L+ n7 x# C## lowerbound 0.1317108 0.1396315 0.1286685 0.08638933 0.1286426
    6 T2 J% j5 C) h; R  s) O## upperbound 0.7102251 0.7393216 0.6966341 0.51482212 0.6964549  s% _7 p- _1 q7 A! o7 C
    ## % {3 ?& T; V' d9 Q9 q  U
    ## $CI$NRI  z5 i% _  G0 m8 N6 y4 J
    ##                     KM         IPW   SmoothIPW         SEM    Combined% C( L) p4 {; ?( Q
    ## lowerbound -0.05112533 -0.04569046 -0.05439863 -0.04132364 -0.05443409
    , t9 D% b% v0 o## upperbound  0.89306122  0.92464359  0.87970125  0.64253510  0.87953153
    6 A0 K& H* |$ _+ M: B. M##
    2 K% P0 V1 h: I* t## 6 `; x4 A+ p' r
    ## $bootMethod  r) b0 s) a0 Z: Q& u; C
    ## [1] "normal"
    6 m4 l: m+ l3 N2 ]  J* x( I; T## $ o" n! F: H8 b
    ## $predict.time: k+ z( I/ Z+ K
    ## [1] 2000, m  g$ G8 c3 d
    ##
    ! `0 |7 m: q- R/ F2 i## $alpha
    $ C6 p. s" \' T5 ]/ Q- f## [1] 0.05. m+ B, L/ ?$ B- q% d- ?7 |9 I
    ##   Q" h, s$ H, r' x4 Y' g
    ## attr(,"class")
    ! L  Z8 \6 h2 _/ I; i/ m## [1] "survNRI"+ }7 r2 U" |1 C# M$ [8 [  M
    # i2 j- b- t( ~0 Z( Q$ x3 _  S
    1* Y1 b; O/ O; T' W# t
    OK,这就是NRI的计算,除此之外,随机森林、决策树、lasso回归、SVM等,这些模型,都是可以计算的NRI的,后面会继续介绍。大家如果有问题欢迎在评论区留言。/ C) k: w( f9 h8 m- _4 Q

    . X" v" x+ `. a3 V  r+ F. S7 ^本文首发于公众号:医学和生信笔记
    4 ~& ?) I; A7 o0 g7 z; p
    . J) f" d. b! O4 ]* P7 q) \$ `“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。
    # B" C0 b( a4 l  }8 O本文由 mdnice 多平台发布0 T$ G: N9 f3 p1 f. v
    ————————————————+ Q9 L9 h' e! p
    版权声明:本文为CSDN博主「阿越就是我」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    3 e+ ^8 N+ j9 V6 ?" {0 w. b9 l原文链接:https://blog.csdn.net/Ayue0616/article/details/126768006  U) O0 y9 T7 [$ r, H; U

    ; J4 d, P, ?% m
    3 l0 R5 ~, D3 y4 M  N# w: \
    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, 2025-8-7 01:27 , Processed in 0.664376 second(s), 51 queries .

    回顶部