QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3023|回复: 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
    " W- W# b& G% X7 t1 w! f% W
    净重新分类指数NRI的计算
    $ T" F& q3 O+ ^3 U% b. O/ v“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。
    - x/ }% o4 R; e( d+ K8 cNRI,net reclassification index,净重新分类指数,是用来比较模型准确度的,这个概念有点难理解,但是非常重要,在临床研究中非常常见,是评价模型的一大利器!
    9 m; F$ Q& d! _
    ) p& t% r% P& m  n; r1 @' E/ E1 X在R语言中有很多包可以计算NRI,但是能同时计算logistic回归和cox回归的只有nricens包,PredictABEL可以计算logistic模型的净重分类指数,survNRI可以计算cox模型的净重分类指数。
    ' E) M' A1 w2 u/ L/ d) N$ l" g
    + s2 W3 c: u* x* C  m$ slogistic的NRI
    ! n. j# K& ^( C( Anricens包" v6 w& H: W# O3 q9 A% b4 B* t
    PredictABEL包9 b3 Z: A; G4 o8 ?& K7 T6 n% X, C
    生存分析的NRI
    - S9 A/ M1 ?9 }1 L( ]nricens包, F7 ], ?, |5 ?- ]+ ^& e+ c' x& ]
    survNRI包/ w6 S! G( K  B$ c: |9 M
    logistic的NRI/ I" R$ w1 w" `5 i* @! S) p: }
    nricens包& v9 A& O+ Z3 o4 U
    #install.packages("nricens") # 安装R包
    : Q1 [, P" Y0 l! }$ z' R7 I# mlibrary(nricens)0 |& S7 d  E/ W+ f# Q% P: q
    16 o( M8 k- R  C% M: R; ]2 r
    ## Loading required package: survival
      u; [. U7 _- n/ r1
      h. @, I8 s1 y使用survival包中的pbc数据集用于演示,这是一份关于原发性硬化性胆管炎的数据,其实是一份用于生存分析的数据,是有时间变量的,但是这里我们用于演示logistic回归,只要不使用time这一列就可以了。
      `8 O/ J& U( c/ {" [
    5 {/ ]$ ^3 x9 q+ J! _library(survival)$ P( n% [# O0 O6 ~' s& x% W& z* P
    8 ]3 E/ @- d1 N/ ]' H6 @
    # 只使用部分数据& W2 o& G) k; z4 `. i. L
    dat = pbc[1:312,] + ^$ k( P& P0 Z2 Z% N1 e
    dat = dat[ dat$time > 2000 | (dat$time < 2000 & dat$status == 2), ]+ k1 I9 o1 x) i7 i% Q

    ! D0 x. H" @( _# S$ q3 Qstr(dat) # 数据长这样- n7 i" C: w6 l; p8 T
    1" R1 ~; `: @6 F9 ?; {
    ## 'data.frame': 232 obs. of  20 variables:& c- T4 m* b- K( ^
    ##  $ id      : int  1 2 3 4 6 8 9 10 11 12 .../ T$ S3 r+ ^2 w
    ##  $ time    : int  400 4500 1012 1925 2503 2466 2400 51 3762 304 ...6 _  A7 f/ s; r7 b: R1 u4 K
    ##  $ status  : int  2 0 2 2 2 2 2 2 2 2 ...
    + H" E* j' C6 t1 P9 m##  $ trt     : int  1 1 1 1 2 2 1 2 2 2 ...
    4 |. m& ~, I2 v4 U# H$ i9 G##  $ age     : num  58.8 56.4 70.1 54.7 66.3 ...+ F1 U8 r3 o/ C9 V' e+ R
    ##  $ sex     : Factor w/ 2 levels "m","f": 2 2 1 2 2 2 2 2 2 2 ...6 q: l, ^2 |4 V& G& q/ d
    ##  $ ascites : int  1 0 0 0 0 0 0 1 0 0 ...$ N6 \) a6 v6 c; U
    ##  $ hepato  : int  1 1 0 1 1 0 0 0 1 0 ...2 x5 J0 x  ]# g, r
    ##  $ spiders : int  1 1 0 1 0 0 1 1 1 1 ...# I2 v' P7 W0 ?
    ##  $ edema   : num  1 0 0.5 0.5 0 0 0 1 0 0 ..., m" ]8 n- Q+ w* d, l
    ##  $ bili    : num  14.5 1.1 1.4 1.8 0.8 0.3 3.2 12.6 1.4 3.6 ...
    8 Q% C0 |7 y" W% Z. L) }##  $ chol    : int  261 302 176 244 248 280 562 200 259 236 ...2 V% i, Q# j0 H3 B8 X% d
    ##  $ albumin : num  2.6 4.14 3.48 2.54 3.98 4 3.08 2.74 4.16 3.52 ...
    8 r* Z, K7 ?% I' a##  $ copper  : int  156 54 210 64 50 52 79 140 46 94 ...
    9 Y1 l5 N7 H7 E) C. S1 t##  $ alk.phos: num  1718 7395 516 6122 944 ...1 X  }: ]8 R) F4 o
    ##  $ ast     : num  137.9 113.5 96.1 60.6 93 ...7 A" s2 p2 q0 Q( |) n
    ##  $ trig    : int  172 88 55 92 63 189 88 143 79 95 ...
    / U: q  X- Z8 a0 G6 F, P' z- i##  $ platelet: int  190 221 151 183 NA 373 251 302 258 71 ...5 ^/ s- e+ B5 D9 x; \  w
    ##  $ protime : num  12.2 10.6 12 10.3 11 11 11 11.5 12 13.6 ...- R( }9 q( `0 W2 ?$ Y7 e
    ##  $ stage   : int  4 3 4 4 3 3 2 4 4 4 ..." k- |: \6 l; {' ^& l$ y

    $ C, W! ]. V* _$ o1 {% _6 V17 F! Q. m7 h' E# ~; l3 i* R
    dim(dat) # 232 20
    7 h; f7 ?. R4 ^9 G3 A2 X7 \1) Q, d2 m( _; X' D8 R
    ## [1] 232  20# k: b$ v5 X2 y# i5 ^+ ~
    1. ~2 h' H5 Z! q
    然后就是准备计算NRI所需要的各个参数。' T7 G3 B. s% H3 B8 x
    7 k# Q& g/ ?0 y& U  z
    # 定义结局事件,0是存活,1是死亡
    % T+ j# b& p* H  P. D6 \4 v. s; tevent = ifelse(dat$time < 2000 & dat$status == 2, 1, 0)
    ' Y. `2 K0 X+ j4 j
    0 C1 {$ r8 P7 T# 两个只由预测变量组成的矩阵
    # y+ `/ A: q" @  O! z1 k5 oz.std = as.matrix(subset(dat, select = c(age, bili, albumin)))
    ) W2 _! N! ~' U* Bz.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime))). N0 C' l5 X& J' ?

    + z& }) x! C% Z5 s/ s1 C# 建立2个模型
    $ ], g  m& J" mmstd = glm(event ~ age + bili + albumin, family = binomial(), data = dat, x=TRUE)
    ; _+ E( b% R  F, Z' v# A; ~) }' cmnew = glm(event ~ age + bili + albumin + protime, family = binomial(), data = dat, x=TRUE). Z) {. U5 r3 w$ f( i/ i. t! L7 n
    2 w5 v! j+ }8 d
    # 取出模型预测概率/ P- a: n( @8 \# A
    p.std = mstd$fitted.values/ Y: T" ^! C( s! ]) v+ q9 ^1 }* i' r
    p.new = mnew$fitted.values
    4 E& {1 t/ L: t# X
    + @; b# K4 i, N, F' J( K7 F3 _1
    4 O' a$ }8 ]5 R! O$ |* r& s# Z7 }1 p然后就是计算NRI,对于二分类变量,使用nribin()函数,这个函数提供了3种参数使用组合,任选一种都可以计算出来(结果一样),以下3组参数任选1组即可。 mdl.std, mdl.new 或者 event, z.std, z.new 或者 event, p.std, p.new。9 R; S* W+ o! y2 \
    4 H+ T5 m/ J+ E! f7 h1 i% B8 U7 V; Q/ h
    # 这3种方法算出来都是一样的结果5 d4 a2 k  U2 h' D: T  [( s
    ( w7 P: k) @2 X  }; o  R0 K
    # 两个模型* }4 d# J, r) Q1 o/ x* D
    nribin(mdl.std = mstd, mdl.new = mnew,
    ; s0 S! s$ K0 a, O       cut = c(0.3,0.7),
    3 K* m% u( M2 E1 A! f; {       niter = 500,
    5 o6 J8 H3 @6 H6 C$ X       updown = 'category')9 w6 J9 c/ B* j7 P! Z5 n

    6 |4 n/ ^/ i, o( G- W6 F% ~# 结果变量 + 两个只有预测变量的矩阵
    # @- R4 C8 `0 O# `nribin(event = event, z.std = z.std, z.new = z.new,
    # I  k& J. A- b; g( x. Q       cut = c(0.3,0.7), & y) l. S8 H7 p9 K1 t
           niter = 500, 1 r, e/ X' J2 e0 V
           updown = 'category')
    0 i# v6 T6 k% X- m# K# Q
    " ?2 q: L2 r" ]- V/ ^8 u8 j## 结果变量 + 两个模型得到的预测概率
    ! E. a9 z7 A+ V9 w- gnribin(event = event, p.std = p.std, p.new = p.new,   f& X' p! v( C! v
           cut = c(0.3,0.7),
    2 }# z/ P7 O4 m( w3 E, w* F       niter = 500, # ~+ l, n; k7 ~# u% n
           updown = 'category')
    + N3 o1 s' J: a. B6 F7 L6 X, M- O
    4 ~1 M# n0 ~  G- B& e1+ I+ `! x+ D$ B, K- F0 A  q% g4 S
    其中,cut是判断风险高低的阈值,我们使用了0.3,0.7,代表0-0.3是低风险,0.3-0.7是中风险,0.7-1是高风险,这个阈值是自己设置的,大家根据经验或者文献设置即可。+ {# e) ]" V+ V# |! E1 z

    . u. ?4 g5 B9 X9 O: J/ ~/ m% u, Jniter是使用bootstrap法进行重抽样的次数,默认是1000,大家可以自己设置。* k: e; V( u% V( x/ K# o

    . {/ R4 D3 ?& s4 xupdown参数,当设置为category时,表示低、中、高风险这种方式;当设置为diff时,此时cut的取值只能设置1个,比如设置0.2,即表示当新模型预测的风险和旧模型相差20%时,认为是重新分类。
    ) p6 v# V. q. t8 q) A1 K% G8 i' U
    $ M, N/ o, f/ {7 d! u上面的代码运行后结果是这样的:
    ! B2 y( m( C. |5 X( O
    * F7 k6 ?  _4 U7 j1 GUP and DOWN calculation:
    , B" h7 A+ K( J; i  #of total, case, and control subjects at t0:  232 88 1442 q& M7 m4 s2 F( z

    5 c8 ?& q! n+ x  Reclassification Table for all subjects:
    & V. l# O0 h+ ]: V& Z        New
    : A5 z! @9 U! J* V4 }Standard < 0.3 < 0.7 >= 0.72 {4 t9 ]7 Q2 J+ D, R" @
      < 0.3    135     4      0
      H7 h' _! E4 C& d) b, t' E8 U3 J  < 0.7      1    31      4
    - P4 h( e( k' q0 X  >= 0.7     0     2     558 g' l) C. u  z+ c. ^

    ; T& h3 K, t/ @  Reclassification Table for case:9 v) X  z  y# h1 C% f4 u, X
            New
    0 |5 h# n- E; O- AStandard < 0.3 < 0.7 >= 0.7
    * d, O0 E( R$ q0 t  C% Y  < 0.3     14     0      07 p2 @4 M% c% h( ?- q% Z
      < 0.7      0    18      3
    1 J% j: N  B9 b8 W, _  >= 0.7     0     1     52
    : c3 y; q0 d/ }# g+ E& X& ^8 H* o8 f4 Q* S" V5 D
      Reclassification Table for control:' N! ~0 N5 m7 c; z4 }7 }. t/ o% M
            New
    " E; ]- {  P# Q3 fStandard < 0.3 < 0.7 >= 0.7
    8 g& Z/ q; O$ j5 L) s  < 0.3    121     4      01 x( r1 E, q* a. R
      < 0.7      1    13      10 e. _" N! n( t, F5 {- L9 k9 ^; H
      >= 0.7     0     1      35 B* T  u( d, M2 @

    7 C  c0 d4 Y9 r# n% t6 ^& \: ^3 [1 _NRI estimation:
    5 x, \9 q3 B" X6 v6 |0 a! {Point estimates:
    , U! [$ z& Q; b- L8 s                  Estimate
    5 f/ L3 c1 u% s6 @! v0 x4 Y) ?NRI            0.001893939$ h% |: {* {$ a
    NRI+           0.022727273
    ' e7 U7 w" q; t1 M/ \NRI-          -0.020833333! F$ o' s, s* h$ B6 ~/ H$ \
    Pr(Up|Case)    0.0340909098 `( T% F$ \/ J% _* S% V3 a
    Pr(Down|Case)  0.011363636
    2 j) T' R/ C1 z- Z! b9 iPr(Down|Ctrl)  0.013888889
    ! H! ]$ Q, U! k7 H! ]8 o5 \7 vPr(Up|Ctrl)    0.0347222221 r5 _, A1 q6 [9 J

    ) K- p0 T- ~' M/ l- H  SNow in bootstrap..
    % j- b; O  ^3 E/ X" [. M, i1 m& A  {; l* @  P. v, b3 x
    Point & Interval estimates:- r, H  G' n% W& I9 W4 b( ^
                      Estimate   Std.Error        Lower       Upper
    0 F' c$ o6 K* tNRI            0.001893939 0.027816095 -0.053995513 0.055354449
    ) U6 f6 W  m1 C2 hNRI+           0.022727273 0.021564394 -0.019801980 0.065789474
    0 Y* N1 W4 R) x/ cNRI-          -0.020833333 0.017312438 -0.058823529 0.007518797
    * C; T3 }) h1 F' p; Y, cPr(Up|Case)    0.034090909 0.019007629  0.000000000 0.072164948, x. W+ U& F: |( Q2 N
    Pr(Down|Case)  0.011363636 0.010924271  0.000000000 0.039603960, U* s" B% L1 y4 K( C+ J5 K& i3 g
    Pr(Down|Ctrl)  0.013888889 0.009334685  0.000000000 0.035211268
    ; V$ y' ^5 `+ FPr(Up|Ctrl)    0.034722222 0.014716046  0.006993007 0.066176471
    " p# {/ A5 x& Q, q" e6 z- N" X$ v
    ) ^% x! R6 g( L' I" m, v1
    8 O2 ?8 J& z) P" m首先是3个混淆矩阵,第一个是全体的,第2个是case(结局为1)组的,第3个是control(结局为2)组的,有了这3个矩阵,我们可以自己计算净重分类指数。8 Q7 s9 Y: ?, z! E, b

    0 R! M5 Y4 C, v, Y: t% p看case组:
    - H6 Z8 |8 u9 u, w/ g
    ! o: z0 {5 w( O! P  m! k. V9 v净重分类指数 = ((0+3)-(0+1)) / 88 ≈ 0.022727273
    % e3 ]7 X% Q( s" j, {
    - a( L. ]% ^, i8 C: ^再看control组:
    , P6 u* b' i$ E$ n9 z' E2 O3 @
    净重分类指数 = ((1+1)-(4+1)) / 144 ≈ -0.020833333' i. V- D. |2 K6 \% a

    ) D+ ~2 w0 R' c( o  _$ Z2 B相加净重分类指数 = case组净重分类指数 + control组净重分类指数 = 2/88 - 3/144 ≈ 0.000315657# A- @0 N5 H6 X5 c6 S4 J

    ) y8 g5 X4 C/ D' w8 l% R# g% d再往下是不做bootstrap时得到的估计值,其中NRI就是绝对净重分类指数,NRI+是case组的净重分类指数,NRI-是control组的净重分类指数(和我们计算的一样哦),最后是做了500次bootstrap后得到的估计值,并且有标准误和可信区间。! ~# c5 Q( q+ U

    2 m+ U- a: p# R$ o, P/ Q( r最后还会得到一张图:4 @4 U1 p! ^4 q' s! {
    ! T  s) @) X, ]! O1 G& @# [
    这张图中的虚线对应的坐标,就是我们在cut中设置的阈值,这张图对应的是上面结果中的第一个混淆矩阵,反应的是总体的情况,case是结果为1的组,也就是发生结局的组,control是结果为0的组,也就是未发生结局的组。% J3 O* P: F4 j" F3 j# j
    $ x% d$ v  a4 b3 V; {4 \/ l
    P值没有直接给出,但是可以自己计算。
    0 w5 p' v& ^5 c9 i0 |: X, Q. @$ @
    $ A8 I0 f: Z  q' \# 计算P值
    ! u$ ^+ ]0 V. M0 m  x2 qz <- abs(0.001893939/0.027816095)
    1 P* d  f# x* n* h. ?# j5 bp <- (1 - pnorm(z))*2
    & b. l. f+ @# E7 Gp2 I' E. h6 }, F9 j
    1. s8 f7 A/ U. X
    ## [1] 0.9457157
    ; Q7 B! X5 M7 `) ?) J1
    6 b+ }% l; \+ a4 a/ N3 hPredictABEL包
    2 Y) ~; B: n  v8 x. a! c#install.packages("PredictABEL") #安装R包
    # F" n4 n8 q2 E- rlibrary(PredictABEL)  / Q, `0 h4 c5 W0 ]) }, D8 t
    % n3 j! v" _7 U. ?5 c( c% J5 M
    # 取出模型预测概率,这个包只能用预测概率计算3 \( X2 b3 t. _; s& \8 z/ Q
    p.std = mstd$fitted.values$ P2 o! j3 L8 F: x( _
    p.new = mnew$fitted.values . Y# a% {5 C- h( i/ ^! u: m
    1" O; u3 \2 a, w: w5 T
    然后就是计算NRI:4 D2 i0 i2 t; C3 R
    $ b" r. ?7 m& ?; ]8 M
    dat$event <- event# Q% P9 s  ^9 @! x7 E
    , q  X! W- c4 T2 [6 [
    reclassification(data = dat,
    ) Q' _" |2 B# K                 cOutcome = 21, # 结果变量在哪一列3 v! N, i3 N: j. E1 c, {: J. _3 H
                     predrisk1 = p.std,, h* o& E5 V1 g$ ~, \6 f
                     predrisk2 = p.new,- V1 J. ^3 k5 G- `8 j$ x* P* R' F
                     cutoff = c(0,0.3,0.7,1)
    ; |8 [) W' F# k& ?( N6 r                 )+ m5 h$ G& T  o3 j9 z! s
    1
    9 N. M" B: U* ^4 N$ _: A) a##  _________________________________________
      t/ B% _2 G# W( W) A$ M##  
    : b8 j  S) u9 D6 _  |  ^* R##      Reclassification table   
    : F4 o! L- _0 `) ?( j: P##  _________________________________________+ ?& W9 D2 j6 S8 {7 h1 t( z
    ##
    1 \, V4 y8 s3 k' j##  Outcome: absent 6 l* T: Z% x3 Y, y$ w+ k. ~
    ##   - e) a. O  g6 t1 t: W
    ##              Updated Model
    , ?, v. T3 P: E+ v## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified& s; l9 m: u. N
    ##     [0,0.3)       121         4       0               3
    " p1 q0 e1 c( i4 R##     [0.3,0.7)       1        13       1              13' r, h" n) F, Z
    ##     [0.7,1]         0         1       3              253 l; t) Z$ D& _! ?9 i! ]
    ##
    2 Q7 ~/ Y" [$ T##  ! B2 j' ^) a  c& D$ ?6 f
    ##  Outcome: present
    4 K) V: u- x' p, h3 y' x9 c##   3 I# b  C- }2 q" k) M
    ##              Updated Model, i) u; x& x9 U% J( q
    ## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
    6 q1 z" F) h  u##     [0,0.3)        14         0       0               0
    8 M& k( d, B* j3 R. q##     [0.3,0.7)       0        18       3              14! B$ u! M, @, {# x
    ##     [0.7,1]         0         1      52               2* r' x4 P; A; B/ p, p. ^
    ## # C3 e  ~: p3 d  O) T. S6 y
    ##  
    % z5 ^: t4 ~: Y. T/ i* a* ?# d##  Combined Data
    ; Z/ O$ P  u6 W, W5 O. Z7 [- ~##   7 O$ o0 W! B" l
    ##              Updated Model
    7 P1 F3 j9 v8 W0 T4 {  H## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified) a& W) @3 Q# A$ C" s+ \* f) i
    ##     [0,0.3)       135         4       0               3& c! F% C9 i1 x
    ##     [0.3,0.7)       1        31       4              14$ |4 B2 E: w( e# s
    ##     [0.7,1]         0         2      55               49 Y! {- Z0 W# V; N. ]0 b# y- _
    ##  _________________________________________2 V- L# R# H! _: _3 M0 q
    ## ( V6 u; `* a$ m) ?( s) |5 l" G
    ##  NRI(Categorical) [95% CI]: 0.0019 [ -0.0551 - 0.0589 ] ; p-value: 0.94806
    " N# n2 Q" f# f) G( g0 U" n( I##  NRI(Continuous) [95% CI]: 0.0391 [ -0.2238 - 0.3021 ] ; p-value: 0.77048 ' z5 ~) Z/ i. J' O' a1 S5 g' R2 s
    ##  IDI [95% CI]: 0.0044 [ -0.0037 - 0.0126 ] ; p-value: 0.28396
    , A1 k7 E6 W/ ^6 k% I5 b, t
    * f, h8 Z  f: p* @1
    3 f9 ~+ `2 n% q" S/ T6 A& Z0 ]% @结果得到的是相加净重分类指数,还给出了IDI和P值。两个包算是各有优劣吧,大家可以自由选择。
    ' M8 a, X9 u7 _
    , G7 @0 e$ p! z; w8 L生存分析的NRI
    9 n( b% g0 `" R2 I$ U还是使用survival包中的pbc数据集用于演示,这次要构建cox回归模型,因此我们要使用time这一列了。
    8 f5 f* d: L7 `( ]8 J+ R/ B& C0 I' V  D* `5 Z/ {' O6 w) E
    nricens包* P# i- x; K, z( J
    library(nricens)7 I; a+ P$ N! y/ t  n
    library(survival)
    + I8 s3 O; `: X/ E- n" j8 F9 R- _& h/ X  z6 Y' M8 p; |
    dat <- pbc[1:312,]$ o$ E* c4 F/ w; n6 [5 [- o
    dat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡( O+ Z* r8 m0 ^% d* x
    1' t$ s3 p& Z: N  K  j
    然后准备所需参数:
    , i9 J/ {; M( t6 _- F
    2 ?& d3 i0 P$ v2 X% n' N9 E& h# 两个只由预测变量组成的矩阵
    % I* ~4 }6 y0 B( J7 qz.std = as.matrix(subset(dat, select = c(age, bili, albumin)))
    + o5 d6 P( E) H  Oz.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))
    0 S- A0 f3 S% A4 {5 F3 s5 `6 A) A) ?1 ^2 X% T
    # 建立2个cox模型  D7 h% m; l. R. m! b2 P: n
    mstd <- coxph(Surv(time,status) ~ age + bili + albumin, data = dat, x=TRUE)
    5 Q2 L; J2 }- e+ R+ t0 {( imnew <- coxph(Surv(time,status) ~ age + bili + albumin + protime, data = dat, x=TRUE)
    & T9 E* F/ A1 P! |$ B  J. [" ?, F9 ^* y. M1 u& ~
    # 计算在2000天的模型预测概率,这一步不要也行,看你使用哪些参数4 L4 W2 v! Z3 d
    p.std <- get.risk.coxph(mstd, t0=2000), [% D4 a. K3 L- p
    p.new <- get.risk.coxph(mnew, t0=2000)
    # v. z1 u: I1 u4 Z# J1
    / P0 \4 A% Q2 s计算NRI:
    % R  y* K. z9 c' M/ Z1 c5 X' _* a0 R* i( ^  G) t0 b
    nricens(mdl.std= mstd, mdl.new = mnew,
    . X: r5 w) V( k; a7 k        t0 = 2000,
    " A+ p& r2 Q. x# l9 g        cut = c(0.3, 0.7),% ~! ?) {9 [) l5 N# B  G! G* W
            niter = 1000,
    8 [/ L4 c4 }* D3 j4 F        updown = 'category')3 g8 }$ `+ z0 m

    5 F. O- M% G; h+ _% E+ NUP and DOWN calculation:6 d- Q4 a/ D5 X, a
      #of total, case, and control subjects at t0:  312 88 1441 `, i+ J: Z3 I, k

    ) |& j6 z# i" f, H# [  Reclassification Table for all subjects:
    & @& X0 j5 s) m. w8 D- i! n$ b' F        New
    , y& B3 j7 @% t' j" RStandard < 0.3 < 0.7 >= 0.7, U7 f% |# @- b4 q, b% U, N0 D
      < 0.3    202     7      0
    , w' V& K: y& c* j  < 0.7     13    53      6! c5 b, }2 _) I
      >= 0.7     0     0     313 b) a0 d% J6 D0 ~. m$ U0 D! f
    8 h1 t1 n  S# r# m( f0 ?/ X
      Reclassification Table for case:
    ) I1 Q) w8 F, m/ I( |) u        New
    3 r. b$ p/ S# F) Z, k* L/ ?! I0 v7 aStandard < 0.3 < 0.7 >= 0.7* j* \4 {  i' k$ k9 J
      < 0.3     19     3      06 \, y% T2 W/ L% `  U
      < 0.7      3    32      4
    * |0 R; _% G# H/ Z: p  R  >= 0.7     0     0     27( D3 Z, V9 f! [. d- L: Y

    9 i6 a! j3 g4 U: @  Reclassification Table for control:
    - Q, \# I5 _+ ~1 T; \/ e, r        New
    : G8 y4 c3 m1 \% C8 z3 p& i% hStandard < 0.3 < 0.7 >= 0.7+ f+ h: P5 \4 U
      < 0.3    126     3      0: Z& C, S, n! b) ~, C) x$ _: o
      < 0.7      5     7      2
    / c. Y. Y8 u* W  ]" y' V, ^9 D  >= 0.7     0     0      19 {+ m) ?- p1 W( e
    & a1 \6 \+ |; p! ~, E
    NRI estimation by KM estimator:
    : n) i" ]+ [& C4 A% ~! f  b
    3 a5 C7 i; T0 _) X* t* Q' t6 a: GPoint estimates:# ?- |1 H5 h6 e4 U  V' u
                    Estimate+ ~, H/ L2 b& y/ p3 F" X! T
    NRI           0.05377635
    2 ?0 M2 o- y) I1 ^# FNRI+          0.03748660/ F6 m% O  x3 f. L* O/ d
    NRI-          0.01628974
    0 i# v7 b* l3 z" A# S! RPr(Up|Case)   0.07708938% w' s/ h( D* [
    Pr(Down|Case) 0.03960278) J% t- M' P2 y" Y
    Pr(Down|Ctrl) 0.04256352; q0 L2 N/ q1 C1 r0 e& U$ _- E  {
    Pr(Up|Ctrl)   0.02627378) B9 }+ E0 C) A- @+ a5 I2 _$ T
    # \) A7 w7 P+ h( u; v  n0 F3 Y8 Y
    Now in bootstrap..
    " ~: r$ Q; K; N/ M  {! `0 f; q5 b4 _# f
    Point & Interval estimates:
    1 n* U8 h* \- s% o- x8 t                Estimate        Lower      Upper5 \$ l& d' J* z
    NRI           0.05377635 -0.082230381 0.16058172; Z) H7 W2 d( O1 ?' v) T! B4 H: j
    NRI+          0.03748660 -0.084245197 0.13231776) [3 [3 T' F/ k% k. n: T2 M" j
    NRI-          0.01628974 -0.030861213 0.06753616- d0 v. j. ]2 s$ |
    Pr(Up|Case)   0.07708938  0.000000000 0.19102291
    + `* G. c  t6 \& v8 F/ QPr(Down|Case) 0.03960278  0.000000000 0.15236016" G  y1 f) D( {8 V
    Pr(Down|Ctrl) 0.04256352  0.004671535 0.09863170
    4 ]9 I2 X+ A) C3 OPr(Up|Ctrl)   0.02627378  0.006400463 0.05998424
    & C& J/ U& g2 t5 J3 N  H0 f% k+ m1 d' Z9 e8 M" y$ v
    1- T; O* }* o/ a% C% j% `) E# H

    ( y0 x% N4 F2 E; @Snipaste_2022-05-20_21-49-38' j3 @1 U( |8 I1 H! q" q* t
    结果的解读和logistic的一模一样。! a9 j4 O+ Q/ `: g3 w

    2 X) v7 n& w2 Y5 GsurvNRI包. }- u( M) Y3 ]/ W, i- `) Q  O) e! o4 H3 B
    # 安装R包
    ) m5 ]- v7 ?# u# Udevtools::install_github("mdbrown/survNRI")
    " X7 L- |' x* M( m% Z17 m  U$ n/ f  `; Z: [& k# F
    加载R包并使用,还是用上面的pbc数据集。
    6 _8 a5 p9 B- H9 n; |9 f: Z7 _9 D2 X/ ]. F( ~3 b
    library(survNRI)& y* l& t8 {" J1 g0 W1 b: r
    1
    8 k# q4 b: c6 W! Y& Q. t  o## Loading required package: MASS
    3 r0 W4 M& i4 N! c. \1* _4 A/ t# k2 F) H, o& Q
    library(survival)4 _7 ]& d: ?6 l- z( X' v0 e. n
    . R2 F: d( b: z  @' h9 p: f
    # 使用部分数据( o! k  V' h3 H4 Q* `4 Z7 D6 A
    dat <- pbc[1:312,]
    ! T; h. ^" T# V: g$ odat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡
    # q) Z7 [1 Y+ [7 ^8 k* F5 s" g1 Y2 ]. N; E: ?
    res <- survNRI(time  = "time", event = "status",
    6 D3 M; n* |0 p0 ^0 u( B+ }        model1 = c("age", "bili", "albumin"), # 模型1的自变量( y1 S/ J# v. v
            model2 = c("age", "bili", "albumin", "protime"), # 模型2的自变量  }3 e% F3 Y$ }. i
            data = dat,
    ( m1 |( y( [. n        predict.time = 2000, # 预测的时间点
    0 G9 F' e" W9 o+ D8 I  R1 r. p        method = "all", ( A% X0 N. [  U6 E1 W8 N
            bootMethod = "normal",  
    " Z. ^# h! |( d+ Y- j9 O2 F8 i        bootstraps = 500, / ^7 t9 y3 i' s2 \
            alpha = .05)
    1 ?% e1 A8 R! T3 }1 m. L0 }: n
    / C& r6 F" n' ~- l/ l9 C! e1
    - `$ {8 n6 K- ~2 H" K3 o3 y* e查看结果,$estimates给出了不同组的NRI以及总的NRI,包括了使用不同方法(KM/IPW/SmoothIPW/SEM/Combined)得到的结果;$CI给出了可信区间。
    ! \, s1 o& M6 ^. |7 \
    9 I! W- [' M4 e* Q$ yres0 m( d) v* p) D; H" i& M
    1
    ( G7 V+ I9 M2 W6 R7 L## $estimates" G7 K" }1 O- J; G, `( j* |
    ##            NRI.event NRI.nonevent       NRI
    * b3 t9 J: V/ s  R8 E, a5 ~/ `## KM        0.20445422    0.3187408 0.5231951
    - n! c. d: w" ~  `+ ]## IPW       0.22424434    0.3273544 0.5515987
    # e. J; q, D# Q## SmoothIPW 0.19645006    0.3144263 0.5108763
    5 `$ [, g* b6 Z( J) c## SEM       0.07478611    0.2632127 0.3379988. a2 f& ?9 A7 I1 b# r2 j, w
    ## Combined  0.19633867    0.3143794 0.5107181# z2 }) M: g" i+ Y! L4 e8 a
    ##
    / m5 x7 f& b1 d3 }## $CI) Y7 D. i: u0 H* S1 a1 @/ D% l
    ## $CI$NRI.event8 x' j' h+ L, \4 w4 }% D8 Q
    ##                     KM         IPW   SmoothIPW        SEM   Combined" k, b% j1 z+ D" f9 |7 `
    ## lowerbound -0.03915924 -0.02185068 -0.04724202 -0.1162587 -0.0473723. z; ?5 ]3 Z4 F# Z* ]  }  p
    ## upperbound  0.44806768  0.47033936  0.44014214  0.2658309  0.4400496
    8 o8 K$ ~5 ?% p0 h" y##
    3 A$ x* \0 [# Z$ Q, Z+ A## $CI$NRI.nonevent
    & Y4 E+ Q6 C7 r0 ?% s6 y8 e0 g+ u4 \##                   KM       IPW SmoothIPW        SEM  Combined6 T9 `& |: ~8 ^
    ## lowerbound 0.1317108 0.1396315 0.1286685 0.08638933 0.12864268 j% u0 i; y4 }7 _1 v5 d* M4 S7 t
    ## upperbound 0.7102251 0.7393216 0.6966341 0.51482212 0.6964549- w. B: i  i3 A9 w$ [
    ## ; S6 j, J- `% R, J  @) c( _  c
    ## $CI$NRI
    4 w. o. l2 ]5 \1 [1 Q; m. @##                     KM         IPW   SmoothIPW         SEM    Combined
    0 R! X8 U& z8 N# e( |4 r# `" D## lowerbound -0.05112533 -0.04569046 -0.05439863 -0.04132364 -0.05443409
    $ |  N2 c/ k7 j4 O4 q- B## upperbound  0.89306122  0.92464359  0.87970125  0.64253510  0.87953153
    2 J3 G$ f: t  \##
    ) ?  b1 m) a9 \( e  H! u##
    & p& T1 j! L/ k2 P- S, O## $bootMethod/ G, s4 [: D9 J2 K) W
    ## [1] "normal"
    ! t2 X, m0 _+ m) f% [- a( A$ y## / P, }" S! h0 M" |. O1 U/ i) P
    ## $predict.time
    , X$ k2 I" {3 A, F7 e$ C3 E$ q7 |## [1] 20003 @) h+ L% h+ V$ i
    ## 0 T+ R# e* s" Q! Y8 P6 v
    ## $alpha& A% T; A' R9 g3 |( r
    ## [1] 0.05( m* N. u, \$ T* S, ?; g
    ## # U. M4 w9 J# f
    ## attr(,"class")5 G0 R, R/ s( r2 X- w
    ## [1] "survNRI"* C( M- M% W* y# i5 h

    , Q1 f' K" Z7 q* ?& {. v0 U, K$ I1  Z% _: N0 `. {' R
    OK,这就是NRI的计算,除此之外,随机森林、决策树、lasso回归、SVM等,这些模型,都是可以计算的NRI的,后面会继续介绍。大家如果有问题欢迎在评论区留言。
      N' Y/ d# H, T+ N" b
    0 \; [! X0 d$ d2 H- s7 h本文首发于公众号:医学和生信笔记
    . T: }! P6 w! ~' J) q
    : b6 C# \3 j! t5 H! p4 |“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。8 V" Z- K7 @1 I3 h
    本文由 mdnice 多平台发布9 n; F: C: i$ g6 t  L4 O" y6 T
    ————————————————
    ) [1 _. R& `& m6 s; D+ h版权声明:本文为CSDN博主「阿越就是我」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。. x. a( L; Z- p, I$ n3 f, M
    原文链接:https://blog.csdn.net/Ayue0616/article/details/126768006& k7 z& M1 ?$ v6 f( R3 q

    " u& m5 S  B9 v$ \
      N0 r6 g# O" E7 M/ ^( E0 M
    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-4-13 10:06 , Processed in 0.418368 second(s), 51 queries .

    回顶部