QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3182|回复: 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

    ' O" U# t4 t  h. G1 x, z. s净重新分类指数NRI的计算
    3 [$ i5 D/ Z- T7 M“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。
    $ ~! T$ g/ \; HNRI,net reclassification index,净重新分类指数,是用来比较模型准确度的,这个概念有点难理解,但是非常重要,在临床研究中非常常见,是评价模型的一大利器!
    - L. d8 w4 ^6 ]8 s4 Y$ ~9 ^  _! j! `# a; h
    在R语言中有很多包可以计算NRI,但是能同时计算logistic回归和cox回归的只有nricens包,PredictABEL可以计算logistic模型的净重分类指数,survNRI可以计算cox模型的净重分类指数。
    8 f% U1 I! p. m4 A7 e. M% ]4 P+ Z5 f
    logistic的NRI
    2 f% d  Y" D3 f0 |nricens包
    3 z1 W6 }+ l* ~2 i! V! m8 ]PredictABEL包- w4 @$ r1 m: ~% b4 X" k
    生存分析的NRI1 y: j( v( z  s7 x) F
    nricens包
    ) I1 Z% z' _6 o8 N; SsurvNRI包
    ( g  Y% ?7 V4 K! Dlogistic的NRI
    2 Q- T( d, N' x' Tnricens包
    7 ]0 y$ P5 U" J: `#install.packages("nricens") # 安装R包
    " q; @' n5 [( [" e& q; klibrary(nricens)
    # w4 G6 T+ T) b- F9 g! _  V6 K1
    0 V- U$ {9 p# {## Loading required package: survival
    . |6 s5 L: y: K7 U8 t/ `0 u1$ ^" W' s5 `  d0 |" Q( O, d
    使用survival包中的pbc数据集用于演示,这是一份关于原发性硬化性胆管炎的数据,其实是一份用于生存分析的数据,是有时间变量的,但是这里我们用于演示logistic回归,只要不使用time这一列就可以了。
    ' j& q+ D) L( {/ x: [* X. b( i8 o6 |3 V9 {5 u2 A+ I0 Q
    library(survival), x/ ]9 Y! v- e
    # _/ r1 U9 d2 _4 F5 g4 ?
    # 只使用部分数据: g2 u% `2 G  ]7 ~
    dat = pbc[1:312,]
    , k; W/ u6 c+ r+ i& @0 ^6 D* Xdat = dat[ dat$time > 2000 | (dat$time < 2000 & dat$status == 2), ]2 d( {. C3 N  {  s

    , }  j- R( d, Q* J$ ~str(dat) # 数据长这样. ~3 |. H# d* o8 D/ n
    1
    0 g& B7 L; @9 M) U, s## 'data.frame': 232 obs. of  20 variables:3 X5 |- ?, u- T. D5 ^4 T. o
    ##  $ id      : int  1 2 3 4 6 8 9 10 11 12 ...* f$ a' z3 x" Q/ o& V0 e4 }
    ##  $ time    : int  400 4500 1012 1925 2503 2466 2400 51 3762 304 ...
    ; t/ t% H1 h* v1 [. L+ E$ B##  $ status  : int  2 0 2 2 2 2 2 2 2 2 ...$ a  H2 h" \5 l9 T- V3 v1 x
    ##  $ trt     : int  1 1 1 1 2 2 1 2 2 2 ...
    8 S2 S+ q; `5 I/ N##  $ age     : num  58.8 56.4 70.1 54.7 66.3 ...
      E. a+ h7 L" f9 A##  $ sex     : Factor w/ 2 levels "m","f": 2 2 1 2 2 2 2 2 2 2 ...
    9 r; L8 f% X1 e; K  F##  $ ascites : int  1 0 0 0 0 0 0 1 0 0 ...
    8 q$ Q% N' K$ @+ `7 X##  $ hepato  : int  1 1 0 1 1 0 0 0 1 0 ...
    3 C: |/ v9 e/ y" I5 k) Y5 C##  $ spiders : int  1 1 0 1 0 0 1 1 1 1 ...! V9 x. S/ a7 N! R% r
    ##  $ edema   : num  1 0 0.5 0.5 0 0 0 1 0 0 ...( s2 v" h% p# U1 Q1 J
    ##  $ bili    : num  14.5 1.1 1.4 1.8 0.8 0.3 3.2 12.6 1.4 3.6 ..., u4 A8 F; n3 Q% E4 t2 R7 t
    ##  $ chol    : int  261 302 176 244 248 280 562 200 259 236 ...8 {. m! f! x4 `1 M4 |. U; J1 }
    ##  $ albumin : num  2.6 4.14 3.48 2.54 3.98 4 3.08 2.74 4.16 3.52 ...- {* j" W" ?$ ^( T" z
    ##  $ copper  : int  156 54 210 64 50 52 79 140 46 94 ...1 d) D5 U/ U+ U! m! z
    ##  $ alk.phos: num  1718 7395 516 6122 944 ...5 ^: z# t3 P( ?! G1 q5 u# m  a
    ##  $ ast     : num  137.9 113.5 96.1 60.6 93 ...2 m. O* H! Q) [2 k! O" H
    ##  $ trig    : int  172 88 55 92 63 189 88 143 79 95 ...- U, f# w: r* k
    ##  $ platelet: int  190 221 151 183 NA 373 251 302 258 71 ...
    " U; W# N: P3 B! k  w, Y: A: h##  $ protime : num  12.2 10.6 12 10.3 11 11 11 11.5 12 13.6 ...+ G6 M" A& `: X; |( \4 f7 O
    ##  $ stage   : int  4 3 4 4 3 3 2 4 4 4 ...; N9 G3 z. M4 C
    * j- U5 u+ h8 q* j4 V3 F' }6 M1 o
    1
    + ~/ F6 K- G5 \( u0 _5 ?9 n/ ^$ H6 w" ~dim(dat) # 232 20, Z% ]7 t# N/ v6 a1 Y
    1
    % }0 l; ^& H, D, e## [1] 232  20
    : ^) d1 z+ ]$ l) T15 s0 M/ C" U! ^) ^3 s+ _
    然后就是准备计算NRI所需要的各个参数。
    + s5 k+ H$ R1 k& _4 K3 }( m
    2 n1 }- Q6 A$ D4 r1 x) v# 定义结局事件,0是存活,1是死亡
    # `" X0 o" q: B" l2 t6 h  Z% z, mevent = ifelse(dat$time < 2000 & dat$status == 2, 1, 0)
    5 Z: q* a7 C# C: U1 H0 d7 y# X  z4 }! G6 u" W3 B
    # 两个只由预测变量组成的矩阵
    - `4 {" Q) E& c. T; t1 [9 iz.std = as.matrix(subset(dat, select = c(age, bili, albumin)))) Z3 g: ]: M% E1 n+ e
    z.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime))). E0 X  r6 M- F; S. l/ h! n

    1 P* ~2 ~3 p- v# {# 建立2个模型7 M, o; E6 C3 R
    mstd = glm(event ~ age + bili + albumin, family = binomial(), data = dat, x=TRUE)7 [5 Z( h- d3 W3 Q; U  V
    mnew = glm(event ~ age + bili + albumin + protime, family = binomial(), data = dat, x=TRUE)
    9 ~4 d9 j7 [$ I& ]4 j
    2 ?7 X3 [+ I! \: w/ K( E5 _# 取出模型预测概率
    7 D0 x2 p7 Z* }  E0 dp.std = mstd$fitted.values
    / n6 b: r7 k$ ?3 D8 Fp.new = mnew$fitted.values
    6 v# j) Y$ Q* s6 n! ^8 i' e$ R3 h; H9 I0 C
    1. d( Y. E0 i* h
    然后就是计算NRI,对于二分类变量,使用nribin()函数,这个函数提供了3种参数使用组合,任选一种都可以计算出来(结果一样),以下3组参数任选1组即可。 mdl.std, mdl.new 或者 event, z.std, z.new 或者 event, p.std, p.new。- O. N4 t- j5 `( B4 S2 f

    0 `, B% Y. h) G& S. z2 o# 这3种方法算出来都是一样的结果
    : Z! I- d. k: p; Q8 R4 a
    1 y+ C& b" S2 G( ?" K, v0 G0 N# 两个模型
    9 Z0 G; @; @) e5 qnribin(mdl.std = mstd, mdl.new = mnew,
    ) ~2 X2 \( a; d) k7 h0 h/ y; n       cut = c(0.3,0.7),
    3 D8 I( o+ ^  C+ d$ s       niter = 500,
    % s4 S+ V1 K3 |       updown = 'category')
    7 k% C4 o- S" }( G* g
    3 {2 J. h3 l3 g, h- q, M# 结果变量 + 两个只有预测变量的矩阵$ |2 a: |6 B; _& C+ b3 @
    nribin(event = event, z.std = z.std, z.new = z.new,
    . `) o+ P8 _4 |1 Y) V% ?       cut = c(0.3,0.7),
    8 }  T- j; U  O8 B8 ]8 b       niter = 500,
    2 w. s- b! C/ E$ v1 {  u& P9 c& Z' Z# h       updown = 'category')
      \; h) ~7 s" `  u. w% V& a4 g+ x8 _. V- Q
    ## 结果变量 + 两个模型得到的预测概率% D4 J. `6 J6 l. O, s
    nribin(event = event, p.std = p.std, p.new = p.new,
      L8 P# T% T; y: i9 P8 q       cut = c(0.3,0.7),
    5 b; K/ q6 s* K* o) J       niter = 500, 3 g# z1 c7 d2 ?
           updown = 'category')0 q9 Q( d5 p* |4 t0 n+ q; ?; R
      f" U; ?$ f) p# i# t$ u3 i
    1" `# |# [% c) w5 r( _  [' S
    其中,cut是判断风险高低的阈值,我们使用了0.3,0.7,代表0-0.3是低风险,0.3-0.7是中风险,0.7-1是高风险,这个阈值是自己设置的,大家根据经验或者文献设置即可。# ^/ N6 N/ O3 F4 }- ^
    $ u7 v  a* Q* g5 X3 F% p
    niter是使用bootstrap法进行重抽样的次数,默认是1000,大家可以自己设置。
    2 e3 ~# \0 M7 N# H% T1 g& q% ^- T% y) i  S
    updown参数,当设置为category时,表示低、中、高风险这种方式;当设置为diff时,此时cut的取值只能设置1个,比如设置0.2,即表示当新模型预测的风险和旧模型相差20%时,认为是重新分类。' q1 i4 N4 }$ _' H5 _
    & p6 `# B6 N* o, j% R8 F
    上面的代码运行后结果是这样的:
    5 x0 l8 p% V: J' f9 Q; b9 _) _& A  c7 v$ K0 _5 e+ C
    UP and DOWN calculation:5 e  N5 v  D/ Q6 M' s$ @0 f
      #of total, case, and control subjects at t0:  232 88 144
    $ v2 k$ ]1 X: Q" I* \1 v) e4 R9 w7 D4 ?6 @0 s$ [- a$ M
      Reclassification Table for all subjects:; }) y/ w, h! F# c8 q# M! F
            New; a2 M" X! z) d" T
    Standard < 0.3 < 0.7 >= 0.71 i! f3 o  J) p
      < 0.3    135     4      0
    1 u. \$ z# p8 y/ a# U  < 0.7      1    31      4
    , l% _" W1 e* |. x- f# L  >= 0.7     0     2     55
    6 c% k% c4 L0 h5 Y: r- j- _  p* n3 S+ a& {4 s9 X
      Reclassification Table for case:3 L+ j7 o+ J+ a; s5 c0 s$ {
            New4 p1 |$ s+ V. H& W  J& L% M
    Standard < 0.3 < 0.7 >= 0.7+ a) b& i# d  X4 H4 ~/ S% ~# H
      < 0.3     14     0      09 L% H& A2 e% U: d5 u& J0 y9 D
      < 0.7      0    18      3
    $ J) z. d$ A/ j" G5 P; S& W% W  >= 0.7     0     1     52
    6 f" Z4 l- E% z# _/ y2 M0 X1 Y0 |  `7 e! `! G7 |% |
      Reclassification Table for control:8 y4 W5 E2 M2 x: Y7 @
            New8 _( L$ m" l, ~. O3 E4 X& ^
    Standard < 0.3 < 0.7 >= 0.7
    $ j, T, _$ z; }/ _* M  < 0.3    121     4      0
    : A+ f2 d; C+ ~+ |- h6 ^1 |4 G  < 0.7      1    13      1
    9 Q7 p( c& J) n% x5 [  >= 0.7     0     1      3
    6 O; z" U/ O4 E) H* }: V) D
    7 ~) q3 n) `( GNRI estimation:
    : H! _/ V$ K% W- r5 XPoint estimates:
    7 @0 c7 _0 p" ?4 R$ @                  Estimate
    # q" j4 K; V7 cNRI            0.0018939394 {6 y$ n4 p5 [1 }2 D
    NRI+           0.0227272734 R$ W% W3 p6 o
    NRI-          -0.0208333331 ]0 U7 T8 t/ y: U) E" I( N
    Pr(Up|Case)    0.034090909: |. Y2 |8 w" d7 X
    Pr(Down|Case)  0.011363636: B! I! }- ^; m$ U  o! n9 ^2 i7 K) P9 Z* Q
    Pr(Down|Ctrl)  0.013888889' c. |  N" D+ h. J. _
    Pr(Up|Ctrl)    0.034722222
    0 T  V) a  E+ K
    $ B! t/ ]" C8 j9 Y! F9 ?Now in bootstrap..
    3 R6 @& C. W; d, I. \+ n
    5 q4 g, D/ r+ C! d; aPoint & Interval estimates:
    ! b: S% ]( x3 y( J                  Estimate   Std.Error        Lower       Upper
    + N+ ^8 r% d  `8 w- F1 _+ Q5 CNRI            0.001893939 0.027816095 -0.053995513 0.0553544496 E/ Q0 q7 h$ c% V! F$ y$ w
    NRI+           0.022727273 0.021564394 -0.019801980 0.065789474: z# v( ]9 g2 }% s
    NRI-          -0.020833333 0.017312438 -0.058823529 0.007518797+ H8 ]# D7 W- A, G
    Pr(Up|Case)    0.034090909 0.019007629  0.000000000 0.072164948( N  c6 O2 N' S, d6 Q; r$ h/ X
    Pr(Down|Case)  0.011363636 0.010924271  0.000000000 0.039603960
    3 I' m4 b+ s$ d6 R3 Y2 a8 c" JPr(Down|Ctrl)  0.013888889 0.009334685  0.000000000 0.0352112684 F2 {- D% J5 ?1 X
    Pr(Up|Ctrl)    0.034722222 0.014716046  0.006993007 0.066176471
    ( |9 V8 Y$ c: j0 v
    . m% E% ^2 g2 w6 u: q9 @1 s5 D1
    " j# V, F0 T: E5 J- \: K首先是3个混淆矩阵,第一个是全体的,第2个是case(结局为1)组的,第3个是control(结局为2)组的,有了这3个矩阵,我们可以自己计算净重分类指数。$ o; @8 k) _3 r0 [% z0 E7 r( M3 Z* \+ Q
    2 f' l- ~: `3 q) f0 j( [, x
    看case组:- f2 G3 ?2 c& P4 R

    4 V  R5 B- y6 z8 d3 V; X净重分类指数 = ((0+3)-(0+1)) / 88 ≈ 0.022727273
    1 Q4 K& X& o. j
    + `; o: J0 E5 h" r: g' q# Z# Y再看control组:
    ' h2 g  I: ?( z; w: `% B5 a( ^% O: u0 \3 o0 x/ j$ C. ?
    净重分类指数 = ((1+1)-(4+1)) / 144 ≈ -0.020833333
    8 `# Z/ o2 z- v& S* u9 {/ k
    $ a6 D# G2 ]2 S& X1 ]- E1 o相加净重分类指数 = case组净重分类指数 + control组净重分类指数 = 2/88 - 3/144 ≈ 0.000315657% N+ S% J5 q! P: ]
    8 }0 Z( u! T( I; X/ O. u
    再往下是不做bootstrap时得到的估计值,其中NRI就是绝对净重分类指数,NRI+是case组的净重分类指数,NRI-是control组的净重分类指数(和我们计算的一样哦),最后是做了500次bootstrap后得到的估计值,并且有标准误和可信区间。2 \2 H9 q% G: c+ }9 ^' _9 w7 Z

    : a6 @" S. r" ]3 U: c( I$ m& u" @+ u最后还会得到一张图:
    ( b# u7 Z- _* t9 A' K) Y/ C0 c3 i+ @0 b' ~( [2 u- u2 f
    这张图中的虚线对应的坐标,就是我们在cut中设置的阈值,这张图对应的是上面结果中的第一个混淆矩阵,反应的是总体的情况,case是结果为1的组,也就是发生结局的组,control是结果为0的组,也就是未发生结局的组。
    / d1 ]3 s' _# i/ ]+ ~
    4 R/ @0 ^$ U. k9 u8 i. g" uP值没有直接给出,但是可以自己计算。. |( C: S; j3 w0 L/ v
    8 r7 o/ Z4 d5 w$ C$ _% U% ~6 Q
    # 计算P值
    6 h. N) F1 D/ z& ?/ kz <- abs(0.001893939/0.027816095)5 h2 Q1 ]; T$ w' u3 l) \% G
    p <- (1 - pnorm(z))*2
    5 k$ e: w  a* ap! D$ |- z4 l& u- v0 s$ _- e* x
    1( x( X+ H3 |5 X* x1 t- o. K
    ## [1] 0.94571574 v! B* p% |! n& H4 d
    1
    ) P2 c. y* H8 K6 y8 h  Q* k4 gPredictABEL包, m/ C* F7 e' }+ A" [
    #install.packages("PredictABEL") #安装R包3 p( N2 k! x* h# Q& |' a
    library(PredictABEL)  ! B1 W* c/ Z% D
    ( I4 h' J9 X5 B
    # 取出模型预测概率,这个包只能用预测概率计算
    # m! e7 ^! l5 B9 R; e7 @p.std = mstd$fitted.values
    ' ]( L, w* Z+ n7 z* up.new = mnew$fitted.values
    1 X4 f3 W! A: R1
    8 F7 Y9 I/ s7 o3 w% @然后就是计算NRI:) W/ k# z" y1 k7 z5 V5 e
    6 ?* R5 u- e9 M
    dat$event <- event
    9 u% g; N5 a' t4 d* ?! @& [7 m7 i6 u& L8 d% N0 y% {
    reclassification(data = dat,
    ) {+ H2 {1 K4 j" g                 cOutcome = 21, # 结果变量在哪一列
    ! A# m0 C) l0 }$ f  ]& F                 predrisk1 = p.std,* u; Z+ R# I) u7 d+ E- W" ]7 ?
                     predrisk2 = p.new,4 w, i3 l9 S0 L; z8 _+ `: g8 r
                     cutoff = c(0,0.3,0.7,1)" E- d) \  n3 X, p6 e2 P
                     )6 @. q* p* J3 \: Z
    1
    7 i: H7 ~2 N6 p  y: g##  _________________________________________
    & p' B3 ^0 A6 X: A##  9 i: }4 u8 L) u* |; y7 e
    ##      Reclassification table   
    # H+ `+ f6 m, m1 q##  _________________________________________) b0 N" j: c, N$ p9 j, \
    ##
    / B- q: v0 \& w* J, F8 a##  Outcome: absent + J3 s4 G& y( ]2 _& F; j
    ##   ) T# e7 ]$ d% P; l
    ##              Updated Model) U" D& j2 j: D; d
    ## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
    / M% b. m) D# P##     [0,0.3)       121         4       0               3
    1 \; |2 F8 Y% W& h7 b0 P7 J* v; i##     [0.3,0.7)       1        13       1              138 s6 P6 S* p+ K7 E' E1 m
    ##     [0.7,1]         0         1       3              25  N4 n( k, a# Q9 B6 `4 P, i2 x' x! S' y
    ## * S3 \3 a+ v, ~& A* I. W
    ##  ( }. U7 B; H( S0 C2 U
    ##  Outcome: present
    5 R0 Z  l  N9 T% p+ O6 r##   
    ! K# u9 A6 ?" r/ X' ]  g' F##              Updated Model% o0 j; p/ m; X% S# w
    ## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified* I. E& u+ l# r5 w1 Q( d4 v
    ##     [0,0.3)        14         0       0               0+ n2 X# _4 A/ }" K$ q
    ##     [0.3,0.7)       0        18       3              14
    2 C6 i: h" R7 t4 o. G##     [0.7,1]         0         1      52               2& H1 L9 q" }, c
    ## * k& }4 {- L+ Q4 x, K4 B& P
    ##  ( Y8 F0 L% A: A
    ##  Combined Data
    9 y1 _0 x# @4 w. i, D! G* w7 D1 \##   
    ; s7 K' ?( a+ g4 L% C/ n##              Updated Model
    ! v$ W' v/ D3 O" n/ W: ^## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified4 S! Y3 L4 M0 U, p; K" l
    ##     [0,0.3)       135         4       0               36 M/ c( z3 s6 |3 ?% A& p, |) q+ \/ U8 g
    ##     [0.3,0.7)       1        31       4              14
    & n7 E: J" d! S1 A. u##     [0.7,1]         0         2      55               4. \% b8 m6 u0 i3 ]" b  H
    ##  _________________________________________
    + Z. z& u& j! G( h& _## " ]. k% n9 N% }( p9 G* S0 I
    ##  NRI(Categorical) [95% CI]: 0.0019 [ -0.0551 - 0.0589 ] ; p-value: 0.94806 5 t9 J& L1 A9 T$ O: R
    ##  NRI(Continuous) [95% CI]: 0.0391 [ -0.2238 - 0.3021 ] ; p-value: 0.77048 % A& x7 W* S; q: @. ~
    ##  IDI [95% CI]: 0.0044 [ -0.0037 - 0.0126 ] ; p-value: 0.28396: v9 ~: P0 ]/ v/ u' n* @% b$ {" S
    7 N* l" ?) Y1 m6 K% b
    14 T2 }8 U" X2 L' V8 E. H0 H
    结果得到的是相加净重分类指数,还给出了IDI和P值。两个包算是各有优劣吧,大家可以自由选择。/ Z' V) ~+ A2 ?( S& `

    , m: A! ^$ U$ N( B: U生存分析的NRI# u9 A/ `; t' S1 p- Y# J
    还是使用survival包中的pbc数据集用于演示,这次要构建cox回归模型,因此我们要使用time这一列了。
    ! y8 h5 z* n3 Q/ b6 v" S) x
    0 M! d2 M2 `- K: {- m( s' unricens包! [; [' C+ v0 E$ c7 w
    library(nricens)2 X, \/ s3 t) |; ?, c# F5 b& N% K$ u
    library(survival)6 `3 U( \; Q) _% G& \
    0 x6 h6 C( O8 g% P( y, f
    dat <- pbc[1:312,]
    ; y2 i- d! e, Q5 K* p9 e9 I7 Xdat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡( k5 w+ t1 l; v
    1
    : G% z# Y7 t0 g& B: S然后准备所需参数:
    6 y- @0 a; ?, F( B+ v
    7 `+ U9 u& |. A( ?2 b! |# 两个只由预测变量组成的矩阵
    0 J2 _/ l$ P! Fz.std = as.matrix(subset(dat, select = c(age, bili, albumin)))
    1 |; H  ], `$ z- W6 iz.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))
    6 S. t0 X9 \1 ~- |- n" ^
    + _" z* o& X+ j, H# 建立2个cox模型1 h5 K( j" Y/ m' x( q% V$ K2 _
    mstd <- coxph(Surv(time,status) ~ age + bili + albumin, data = dat, x=TRUE). U! W' ?8 B- S4 k3 W+ J7 z* s) x
    mnew <- coxph(Surv(time,status) ~ age + bili + albumin + protime, data = dat, x=TRUE)/ \$ b+ w% O# |) Q7 J

    8 x% u2 b- j! @  `6 H# 计算在2000天的模型预测概率,这一步不要也行,看你使用哪些参数
    # S9 w9 h% r1 w6 E- jp.std <- get.risk.coxph(mstd, t0=2000)/ K/ T$ Q( J) g( O( ]
    p.new <- get.risk.coxph(mnew, t0=2000)
    5 `8 |& B' q' I5 ?9 `+ p5 S18 W# Q5 c! U1 o9 n- q+ _
    计算NRI:  e0 Q: k$ Z( f* k- D

    . u. A+ ]  Y* n4 g, ?" @nricens(mdl.std= mstd, mdl.new = mnew, * @( p; Q' L% H. W
            t0 = 2000, 3 i3 s, d# ^: k7 {& F; X& M, \0 g1 _" Z
            cut = c(0.3, 0.7),
    4 d; b0 M& n, l+ `, p# c        niter = 1000, 3 f* i4 j2 z5 y- [6 n
            updown = 'category')1 }6 H# d0 L) g6 J" v# v+ K
    " |4 O; i8 g+ j2 h
    UP and DOWN calculation:8 d+ P3 f* Q/ h: y
      #of total, case, and control subjects at t0:  312 88 144
    0 V5 I: U8 ^5 N5 [7 k2 I3 I# ?9 w6 D0 C, c7 h  d
      Reclassification Table for all subjects:' P) O  r2 ]3 O. p/ Z1 [
            New* e& x% W7 D, l4 S1 O# Q6 ^
    Standard < 0.3 < 0.7 >= 0.7
    / }* ?8 L9 A0 l1 i& Y4 O  < 0.3    202     7      0) B+ c  l. `4 ]- R
      < 0.7     13    53      6
    ' w6 s/ H# L( m. z6 z& O8 x- L  >= 0.7     0     0     31
    5 m1 ]6 ~" h# P2 @$ n( l! u
    : v' q, H6 l& Y, y! R  Reclassification Table for case:. a3 l  V. K' u, \
            New
    8 W3 g$ o' ], Z5 cStandard < 0.3 < 0.7 >= 0.7  \3 E3 G  A0 i
      < 0.3     19     3      0
    ) @* ^5 c, ~2 V: A  < 0.7      3    32      4
    * H, x7 P* Z6 ~2 {- ]  >= 0.7     0     0     27
    ' q5 i9 P# ^% A8 N. |& r& }2 F8 C' o9 r5 D# k$ |
      Reclassification Table for control:/ e) [- n1 f! j8 k+ u( d! a1 Q5 k
            New
    , `- Y" {- {0 g) \7 c$ I9 Z* mStandard < 0.3 < 0.7 >= 0.7
    / p8 t( I2 T8 ^( y  < 0.3    126     3      0
    ) b; [7 H9 w" U) r  < 0.7      5     7      2
    : q" V( T* u# `; B$ b  >= 0.7     0     0      15 l5 o; f% W& \: U$ `$ l
    5 R0 ^6 C% c4 v' U
    NRI estimation by KM estimator:; [' G. Z; F: P$ y' z" E! T  [! x

    - d' o' g3 P1 J6 ~Point estimates:
    7 f3 Y: T. I" \8 p* m                Estimate
    5 m  z+ g7 c3 _3 eNRI           0.05377635
    9 p/ F* E5 n. {NRI+          0.037486602 X( g7 c6 R# z6 d! R) Z. x- M
    NRI-          0.01628974# Z, [/ \5 i: a! T* v
    Pr(Up|Case)   0.07708938
    1 u2 h8 E- {1 E  q9 c2 PPr(Down|Case) 0.039602787 ]6 }8 B6 {; Q: a$ f
    Pr(Down|Ctrl) 0.04256352. q0 G) H, e0 R+ @( p
    Pr(Up|Ctrl)   0.02627378
    2 ?+ ?, l  o0 n! w- ^4 ~* l# {9 M4 T7 k2 a) y8 C( _& z5 m
    Now in bootstrap..
    1 p* C4 L" f" b/ }4 G& G- y8 Y2 m- P4 e. ^+ Q  h
    Point & Interval estimates:+ ~# C. M, H9 K. ]: N4 i# S
                    Estimate        Lower      Upper' ~6 E' O. Z  y
    NRI           0.05377635 -0.082230381 0.16058172
    . V* d5 {6 y# W1 B3 g4 y. c* C' d5 iNRI+          0.03748660 -0.084245197 0.13231776
    ! b( E  T# V1 D( g* u, K8 v. y6 hNRI-          0.01628974 -0.030861213 0.067536162 A2 s8 {: `5 v* `& l* l
    Pr(Up|Case)   0.07708938  0.000000000 0.19102291
    5 Z, C+ P6 J3 q  M$ V/ q4 ePr(Down|Case) 0.03960278  0.000000000 0.15236016
    1 H# I; M( x- }$ E$ FPr(Down|Ctrl) 0.04256352  0.004671535 0.09863170  N8 @$ C) q; k
    Pr(Up|Ctrl)   0.02627378  0.006400463 0.05998424
    , Y0 o! {8 Y9 o0 U$ H( B; ?
    5 T  {, @4 l6 t3 d2 R: V3 X1# ]8 H4 |8 ]/ h  y
    # }+ e9 Y4 F  ^; O
    Snipaste_2022-05-20_21-49-38
    % v  k! Z4 K6 R4 R结果的解读和logistic的一模一样。  o( ]1 v9 K! ?# K* P
    4 @0 h0 Z# O# I; Y- @3 n8 g
    survNRI包; c; n, y# v7 X$ @6 k7 [% X( @
    # 安装R包! N, ~  A; j0 M, K9 Y& O
    devtools::install_github("mdbrown/survNRI")
    9 v7 o, @2 j+ G7 }9 L/ r- ~1
    ) V. E1 c. D, Y* [2 _' Q加载R包并使用,还是用上面的pbc数据集。! z( e( ]+ F- H  U) E7 y
    3 R# ?% `& S9 E5 t7 {3 b
    library(survNRI)  u1 |3 U' q% D7 R$ o
    11 \$ S; ~  ?8 d
    ## Loading required package: MASS
    / E1 ]+ u' J' V3 c( K6 r7 ]1# C) @* v  Q9 t" C# o9 ^( g
    library(survival)
    / G( v. P" r8 a4 W: m2 V; P6 d- ?
    , e* O0 A5 b& a) z) X# 使用部分数据. n3 A8 c! ~4 i9 Q+ F
    dat <- pbc[1:312,], N  Q+ |7 a% n$ {
    dat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡
    2 P" l8 s( ~! s" k! d
    0 s) c" l2 M3 Bres <- survNRI(time  = "time", event = "status", / W: S' k( h( g/ O
            model1 = c("age", "bili", "albumin"), # 模型1的自变量/ [* [0 P7 J& L; X5 O
            model2 = c("age", "bili", "albumin", "protime"), # 模型2的自变量8 |  S1 A& j( U7 X' N6 O% p2 g$ M! I7 l
            data = dat,
    ( g5 c. d' Z( M8 J5 A        predict.time = 2000, # 预测的时间点' C' F5 p6 e/ Y/ U: x+ _
            method = "all", ! b1 V% b. o6 g! [. d" P- r
            bootMethod = "normal",  1 Q5 `) e7 z2 N4 e# b
            bootstraps = 500,
    + E& w) C; Q4 u7 N; e' q        alpha = .05)3 I4 P7 e( f+ g5 g8 q3 G* L# c3 }  v8 d

    * c/ U0 R. j) y  Q; P1" S9 C! M( z  f+ f. G; x4 `
    查看结果,$estimates给出了不同组的NRI以及总的NRI,包括了使用不同方法(KM/IPW/SmoothIPW/SEM/Combined)得到的结果;$CI给出了可信区间。: ?+ M( o3 W. P/ ]
    . Z, k' _: `2 r$ W
    res" W# h  A) C2 k0 h! o
    1
    / F& T& C. O' \## $estimates
    , ^- S( l8 A3 r9 f% I1 v##            NRI.event NRI.nonevent       NRI( J( U+ ^7 Y2 n
    ## KM        0.20445422    0.3187408 0.52319516 y( I% O1 a, r% _$ w5 b- E
    ## IPW       0.22424434    0.3273544 0.55159877 ~- |  i8 g  n! u. f
    ## SmoothIPW 0.19645006    0.3144263 0.5108763
    # g' t7 W6 o7 n## SEM       0.07478611    0.2632127 0.33799884 m1 P' r+ v7 {7 ?
    ## Combined  0.19633867    0.3143794 0.5107181
    ) E; d. F, U9 r& K, L## + N9 d9 p% q$ C' p4 g' F
    ## $CI4 s; }# e& I' [# `+ X2 F$ U, j: ~) h7 ]" ?
    ## $CI$NRI.event
    $ t% q; s- {( I% U' p5 j##                     KM         IPW   SmoothIPW        SEM   Combined
    5 F3 d' e' X6 Z8 \7 o" x' G## lowerbound -0.03915924 -0.02185068 -0.04724202 -0.1162587 -0.0473723
    ) L+ Z5 ]) {$ a4 }' {## upperbound  0.44806768  0.47033936  0.44014214  0.2658309  0.4400496% k& j/ K1 p# j+ E  V7 {/ l- ]
    ## + P1 n- m" h4 s2 ?0 _& h! {* o
    ## $CI$NRI.nonevent
    & k. h8 t3 }0 l" P##                   KM       IPW SmoothIPW        SEM  Combined! d* u+ C# c" C0 E; v3 K% H! b# t  m
    ## lowerbound 0.1317108 0.1396315 0.1286685 0.08638933 0.1286426
    " u! ]; u$ o; ]2 {" \5 c0 A## upperbound 0.7102251 0.7393216 0.6966341 0.51482212 0.6964549( q% w: N0 q( `3 k* b0 D; J
    ## 2 v0 c! i; N3 ?0 N% ~" J$ ^! X
    ## $CI$NRI
    6 r7 q2 @/ \6 A5 a) N1 N$ X1 U##                     KM         IPW   SmoothIPW         SEM    Combined9 W6 U+ X; C4 k! O3 f
    ## lowerbound -0.05112533 -0.04569046 -0.05439863 -0.04132364 -0.05443409
    * T0 e6 u( o: C2 o. p. @## upperbound  0.89306122  0.92464359  0.87970125  0.64253510  0.87953153
    8 u% A; a  M5 l$ ]##
    7 B$ m. N, J  L) v3 S## ! \/ i9 G1 v5 W$ Y- _7 b
    ## $bootMethod' V8 ~3 F4 m: W' D3 e" Y. g
    ## [1] "normal"9 ^2 ^3 Z& c& _2 b% e% s1 a% j* r& x8 S
    ##
    & J5 Q8 O" \. O2 k( K## $predict.time: K+ o6 A% o" u. s
    ## [1] 2000' Z' ], ?# G3 f
    ##
    $ n7 ~, |6 y$ H1 P' w2 b5 Q## $alpha
    2 n( w* u+ Y2 e! z8 ]## [1] 0.05
    . Q6 f* q& Q0 n( e+ I% J## 1 y9 ~# i" }$ k1 ~0 y# i) D; i
    ## attr(,"class")& J  U* m! A- a
    ## [1] "survNRI"
    6 j6 r. U( X. _* X
    6 ?+ p: ~) H, n, I* v1 l0 |" p1
    $ m! s- j1 O% c" [% bOK,这就是NRI的计算,除此之外,随机森林、决策树、lasso回归、SVM等,这些模型,都是可以计算的NRI的,后面会继续介绍。大家如果有问题欢迎在评论区留言。
    - g+ d0 T, o$ y
    5 [% g3 P) _" V本文首发于公众号:医学和生信笔记" r/ r8 v# H5 x$ \

    ! @) b1 ^$ V/ P1 j0 k0 b" o; u“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。0 s0 D" r0 V% ^* y& V+ Y% U
    本文由 mdnice 多平台发布. m3 e- l1 h$ _! E
    ————————————————
    ( B; P% K8 w) K; y1 ?版权声明:本文为CSDN博主「阿越就是我」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。& s/ [; {% p# _/ m
    原文链接:https://blog.csdn.net/Ayue0616/article/details/126768006$ r/ z  K2 T$ @) p  p" F
    7 Z! {& i( k$ _; }
    0 |9 H6 U# C+ Q) T
    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-9 03:20 , Processed in 0.582088 second(s), 50 queries .

    回顶部