QQ登录

只需要一步,快速开始

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

    1 g# _5 F  O2 K  t净重新分类指数NRI的计算( x7 m/ {- D* ~
    “ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。) p* y2 g  j, G
    NRI,net reclassification index,净重新分类指数,是用来比较模型准确度的,这个概念有点难理解,但是非常重要,在临床研究中非常常见,是评价模型的一大利器!
    8 v- [+ ~  u, r0 k- G
    3 d5 t: y3 d3 U5 U在R语言中有很多包可以计算NRI,但是能同时计算logistic回归和cox回归的只有nricens包,PredictABEL可以计算logistic模型的净重分类指数,survNRI可以计算cox模型的净重分类指数。# e  G# L, i2 W
    3 I1 a9 W  H6 ]; d& F
    logistic的NRI
    + l3 G7 U& T9 jnricens包- Z  L3 G+ O5 i& r% I. }3 {
    PredictABEL包. A6 Z8 k  `" s
    生存分析的NRI
    ' ?/ O9 t7 V4 c) ^* J( Znricens包
      j( @" w( t7 C6 ?survNRI包. O, F9 v; E0 f
    logistic的NRI3 P  [5 g; D4 m5 E( C
    nricens包
    . C, X2 q0 O& k# _6 I- B3 ~1 o#install.packages("nricens") # 安装R包  w" A8 u2 ?  B' S+ N( b
    library(nricens)" j! X; O. D. K0 o0 Y
    16 D" B3 j: E4 W) S7 a6 V. f
    ## Loading required package: survival
    ! s4 G) A! b5 n* {1. d5 G) s9 d* P& ^6 E/ @
    使用survival包中的pbc数据集用于演示,这是一份关于原发性硬化性胆管炎的数据,其实是一份用于生存分析的数据,是有时间变量的,但是这里我们用于演示logistic回归,只要不使用time这一列就可以了。: T' q- d& W, o2 K; ~" [

    1 H5 J. C, a0 _5 o' }; b: e$ d. R4 Z! K6 flibrary(survival)$ z  S# t& _, ]5 _
    - Y1 R% w" n6 d# }$ R$ v5 ?
    # 只使用部分数据! C4 T. d: j9 q7 H
    dat = pbc[1:312,]
    $ n; f" E8 d2 l8 tdat = dat[ dat$time > 2000 | (dat$time < 2000 & dat$status == 2), ]( A6 X6 P$ [. \9 x1 q2 K% [

      n% v# z! w- a! qstr(dat) # 数据长这样
    4 u& ?* Z! B% \+ C1: r$ W6 L! L1 J3 Z- S; N
    ## 'data.frame': 232 obs. of  20 variables:4 C' {8 C: l, c
    ##  $ id      : int  1 2 3 4 6 8 9 10 11 12 ...* Z8 \6 b9 r5 ^" Q+ c
    ##  $ time    : int  400 4500 1012 1925 2503 2466 2400 51 3762 304 ...
    2 H8 P6 {( e% c& n* @##  $ status  : int  2 0 2 2 2 2 2 2 2 2 ...2 V9 n4 O$ t; r# Q
    ##  $ trt     : int  1 1 1 1 2 2 1 2 2 2 ...7 L% W) M- J, B. X: C
    ##  $ age     : num  58.8 56.4 70.1 54.7 66.3 ...
    2 z4 H9 H# J% H* T" `##  $ sex     : Factor w/ 2 levels "m","f": 2 2 1 2 2 2 2 2 2 2 ...
    2 n& b: o- F! h7 B5 e##  $ ascites : int  1 0 0 0 0 0 0 1 0 0 ...
    9 H$ n/ l) D8 D( F& `+ J) t##  $ hepato  : int  1 1 0 1 1 0 0 0 1 0 ...; o+ r0 C  l8 L% C) M9 e
    ##  $ spiders : int  1 1 0 1 0 0 1 1 1 1 ...
    8 T- Z: l- W2 E##  $ edema   : num  1 0 0.5 0.5 0 0 0 1 0 0 ...- V( p( p$ W# R! i2 j$ F7 c
    ##  $ bili    : num  14.5 1.1 1.4 1.8 0.8 0.3 3.2 12.6 1.4 3.6 ...2 Q7 }/ l( t6 l5 T( `# w% V
    ##  $ chol    : int  261 302 176 244 248 280 562 200 259 236 ...
    3 W, E+ C1 G5 A/ P6 C* J5 S##  $ albumin : num  2.6 4.14 3.48 2.54 3.98 4 3.08 2.74 4.16 3.52 ...
    ) [% h' ?( y( J2 ^2 h7 A9 o##  $ copper  : int  156 54 210 64 50 52 79 140 46 94 ...# L* ]) e3 F* O7 _, j# ?
    ##  $ alk.phos: num  1718 7395 516 6122 944 .... E* S$ e5 c6 G
    ##  $ ast     : num  137.9 113.5 96.1 60.6 93 ...
    6 t. j: Z4 \# n# K3 d2 x8 W$ s+ O##  $ trig    : int  172 88 55 92 63 189 88 143 79 95 ...
    0 N  ^! {7 }5 {$ I# i##  $ platelet: int  190 221 151 183 NA 373 251 302 258 71 ...
    " m1 H; y) ?7 P, q##  $ protime : num  12.2 10.6 12 10.3 11 11 11 11.5 12 13.6 ...
    3 j: U+ D! Q: T4 N- V7 I. s##  $ stage   : int  4 3 4 4 3 3 2 4 4 4 ...
    5 K! M% E' b, E) `, j
    $ l  f/ D' O: K' s16 S) L8 D" I( y: l1 a# a
    dim(dat) # 232 20, w) d2 X! u/ E: v
    1
    # J; X! K8 |. h% T## [1] 232  20
    ! e+ c5 }' B4 t2 q; h6 o) `# Q1
    + B% _, D. P1 D# ?' v& Z. ^然后就是准备计算NRI所需要的各个参数。
    9 m4 l; b3 \9 q$ k& ~  n$ _1 A4 O
    1 [- z5 f; ]5 P7 y3 g# |7 Z  g# 定义结局事件,0是存活,1是死亡
    2 m* O  D9 ]! Oevent = ifelse(dat$time < 2000 & dat$status == 2, 1, 0)  v1 f  o6 N4 e% A5 p) X
    - w4 u; p. r9 J/ ]* J9 ^
    # 两个只由预测变量组成的矩阵
    # R# D2 V  i6 e5 j8 d3 d! Sz.std = as.matrix(subset(dat, select = c(age, bili, albumin)))
    % ]& ]5 v) m7 F* iz.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))# C6 C+ y( n9 y  E& R# H8 r9 H
    ' W# v& E" S0 ?4 R4 t, W
    # 建立2个模型6 a' Y/ A6 }8 a3 w
    mstd = glm(event ~ age + bili + albumin, family = binomial(), data = dat, x=TRUE)
    5 H3 D9 X. x% n# K8 cmnew = glm(event ~ age + bili + albumin + protime, family = binomial(), data = dat, x=TRUE)
    . W9 ]0 L3 q' Q7 J9 A# w# P6 [: h5 J/ N, v; k, _5 k
    # 取出模型预测概率' V$ B$ K% g2 G- y1 u9 b8 b
    p.std = mstd$fitted.values
    4 C! D/ }, n1 i" U! Cp.new = mnew$fitted.values
    # M. n6 c! m- M; p3 q" V
    5 h2 q1 i, a" I! j* n1 n; H1
    3 |" ~5 p! u4 Q" v/ c& B然后就是计算NRI,对于二分类变量,使用nribin()函数,这个函数提供了3种参数使用组合,任选一种都可以计算出来(结果一样),以下3组参数任选1组即可。 mdl.std, mdl.new 或者 event, z.std, z.new 或者 event, p.std, p.new。
    6 ?- l' w% q2 w. z/ f5 q0 k6 @) D
    3 J, t, L& ?  U9 N2 |, a# 这3种方法算出来都是一样的结果7 l' X: C! D& i% ~6 y9 G

    6 a6 m/ k2 i4 x. A  D. b& ]# 两个模型" P$ W2 m, y" ]
    nribin(mdl.std = mstd, mdl.new = mnew, % R' _. O+ \( ^- P  }* {/ L6 {, Q! j
           cut = c(0.3,0.7),
    ' a) Z+ q; s6 V1 c6 d, N       niter = 500,
    3 g  l. d2 f% q$ V0 U3 a( X6 h       updown = 'category')
    # o$ L8 z% j' F: a. a- U
    7 b/ v+ |$ i9 g# 结果变量 + 两个只有预测变量的矩阵
    0 u) T) V5 E+ k& ]3 K5 L. fnribin(event = event, z.std = z.std, z.new = z.new, * `0 D' k" d, ]: G8 G  \& I
           cut = c(0.3,0.7),
    2 Q: r# N! E; z! B1 |( G* g       niter = 500,
    , x) A* ^5 D: E% }3 m" \       updown = 'category')
    2 S6 k& o6 j* S
    3 z7 T+ R* I  j7 Y; Y+ F7 L* G5 k## 结果变量 + 两个模型得到的预测概率( w2 }# ~4 r8 Z8 W, U, ~7 b- D1 o
    nribin(event = event, p.std = p.std, p.new = p.new, , i  i/ f) k. L$ U1 L) B! _
           cut = c(0.3,0.7),
    7 U) C0 s: O+ I1 N8 ^       niter = 500, 1 l* ?6 d8 r/ C$ ?- z6 E. O
           updown = 'category')
    ; y/ W& E7 v8 ]' i, m/ c2 K5 k/ L
    * {: R/ l- V! _! A, H1
    ) c$ l! o8 ]4 G: g2 l: F. |其中,cut是判断风险高低的阈值,我们使用了0.3,0.7,代表0-0.3是低风险,0.3-0.7是中风险,0.7-1是高风险,这个阈值是自己设置的,大家根据经验或者文献设置即可。
      W; c# H6 L5 i% e
    & @" L6 D! K! W3 F# \) Zniter是使用bootstrap法进行重抽样的次数,默认是1000,大家可以自己设置。
    / z) f" J) I# R' z2 z" q$ L" L& w4 q) ?* f6 ]- ^  O# P  l; J8 G
    updown参数,当设置为category时,表示低、中、高风险这种方式;当设置为diff时,此时cut的取值只能设置1个,比如设置0.2,即表示当新模型预测的风险和旧模型相差20%时,认为是重新分类。
    9 u  F: a& w/ q/ |4 ~
    2 h3 t7 E: K6 ^+ ~上面的代码运行后结果是这样的:
    ) d/ B: E4 Y& u$ w( R
    + y9 r5 `) T+ XUP and DOWN calculation:
    & k4 e: t4 l5 _  #of total, case, and control subjects at t0:  232 88 144) L  W9 R; d4 x: Y) X* I

    * f' J+ Z4 ?9 c' R5 Q. x  Reclassification Table for all subjects:
    ) g- m& c( V! _3 F        New
    $ k0 u: }6 p" A% K. o- |9 YStandard < 0.3 < 0.7 >= 0.77 ~: Q( x2 T; K2 l  T! n3 z3 o
      < 0.3    135     4      0& p* D  M. b. Y6 P8 q4 X/ V" h
      < 0.7      1    31      4
    " u9 j, j3 V* n# L& J# q  >= 0.7     0     2     55
      j  d+ n2 r# f. I6 R8 I9 H$ |& Y
      Reclassification Table for case:
    2 {2 a8 z  f5 `6 \: ?        New9 k: j" B' K9 D' V& u
    Standard < 0.3 < 0.7 >= 0.7
    $ q( R- m$ Y4 r2 G  < 0.3     14     0      0
    & v; i/ O1 y% x4 {: N1 n. r1 h  < 0.7      0    18      3+ k! k' n3 w  Y- u$ H3 h
      >= 0.7     0     1     52
    % ^( v  D; i* M) |: y
    & C2 P/ Q' G( I$ `) A5 w: E3 @( M  Reclassification Table for control:
    3 S8 A* k9 @8 {& b        New* i+ w5 R2 q6 W* y, T6 O' k' t
    Standard < 0.3 < 0.7 >= 0.7
    - B- k$ y7 q5 C4 V, T. ^. s4 ^% b  < 0.3    121     4      07 j% w7 E% u9 Y/ ]
      < 0.7      1    13      18 ?3 q5 l& N7 L, S7 I7 r" M
      >= 0.7     0     1      3
    1 Q0 q2 o' |1 e! G# Q' q4 p. T+ L! ^: E
    NRI estimation:3 `3 e) M& `& a9 q1 v3 N! U
    Point estimates:
    1 G; w* X8 Z2 K. s7 m1 C                  Estimate- G5 g. O0 n0 i5 E# j
    NRI            0.001893939
    ( L& H. \  k- h0 a1 {) CNRI+           0.022727273
    & b' Y9 D+ C: X% c; M; u: WNRI-          -0.020833333
    - x7 _2 ], d+ }3 j5 f6 D. EPr(Up|Case)    0.034090909
    6 u0 ~! S2 n& N4 p( e- gPr(Down|Case)  0.011363636+ s' {- `4 }0 N  U1 |
    Pr(Down|Ctrl)  0.013888889
    ' p% s% a' b7 `4 f; o! yPr(Up|Ctrl)    0.0347222224 Z- b: O3 G& a0 U. g

    ( _0 f  @$ K2 n0 `- _3 mNow in bootstrap..; Y# J; G7 p1 |3 C8 b( j/ m( i! B

    ( m) n% B" i7 b* xPoint & Interval estimates:% ^% @/ A/ R. N) r0 f( S# g2 o
                      Estimate   Std.Error        Lower       Upper
    ; G& v3 B0 @' a; p: t9 P0 y) [NRI            0.001893939 0.027816095 -0.053995513 0.055354449
    5 w1 ^" X. I! V+ dNRI+           0.022727273 0.021564394 -0.019801980 0.0657894744 V2 ^0 ~  p1 n5 n! d; G8 [; l, ]
    NRI-          -0.020833333 0.017312438 -0.058823529 0.007518797
    # \# }- o5 c" C& I1 P# [Pr(Up|Case)    0.034090909 0.019007629  0.000000000 0.072164948
    6 s8 Z/ t5 u6 {& yPr(Down|Case)  0.011363636 0.010924271  0.000000000 0.0396039600 U& \4 C* S/ H8 Y, @3 U" a
    Pr(Down|Ctrl)  0.013888889 0.009334685  0.000000000 0.035211268
    " C& U. v# w4 |; VPr(Up|Ctrl)    0.034722222 0.014716046  0.006993007 0.066176471
      j, i! |) x' @
    + ]- v6 h4 B) t% Y+ G' p1% }/ L# ]' j4 ]- L+ D/ b2 e7 v
    首先是3个混淆矩阵,第一个是全体的,第2个是case(结局为1)组的,第3个是control(结局为2)组的,有了这3个矩阵,我们可以自己计算净重分类指数。; z* N+ C! o  `; w

    # i% a) w* i/ r9 a8 T: t' ^  }, n( Z看case组:
    4 `  D2 L% b: j! d+ Q2 b9 B8 K  A; z# ~' ^# e+ `' W
    净重分类指数 = ((0+3)-(0+1)) / 88 ≈ 0.022727273
    . R" A9 R4 a5 C; a
    ' b* m# L2 ~5 t. W6 ^% N再看control组:- L1 ]) e2 \7 [. M8 W4 H& w4 ]5 M7 B$ h' e

    ! T, E4 W7 t- F& l$ u+ N净重分类指数 = ((1+1)-(4+1)) / 144 ≈ -0.020833333! C6 w- p# G5 D9 G
    % E8 d0 B( O# L) g" g, u
    相加净重分类指数 = case组净重分类指数 + control组净重分类指数 = 2/88 - 3/144 ≈ 0.000315657: v6 \$ w# B& _7 I6 x6 Z

    ; ?; |* N! g8 J  z再往下是不做bootstrap时得到的估计值,其中NRI就是绝对净重分类指数,NRI+是case组的净重分类指数,NRI-是control组的净重分类指数(和我们计算的一样哦),最后是做了500次bootstrap后得到的估计值,并且有标准误和可信区间。7 ^- b3 u" _9 g! v2 C) G, E  ?  a
    5 ~' X5 K7 {. N  ]8 ]3 |
    最后还会得到一张图:
    : U5 e5 f9 [# P# l2 o$ n6 `+ X. ^
    . ~5 p% s1 ~9 g' o2 a  ~这张图中的虚线对应的坐标,就是我们在cut中设置的阈值,这张图对应的是上面结果中的第一个混淆矩阵,反应的是总体的情况,case是结果为1的组,也就是发生结局的组,control是结果为0的组,也就是未发生结局的组。
    & B( ?' }- y  b" u
    # E- s$ t$ |" N3 U6 r& sP值没有直接给出,但是可以自己计算。1 p0 J% y6 |* }; c' V( [  l
    1 N$ }$ D0 w( u
    # 计算P值+ N* O$ j8 B# F( ~
    z <- abs(0.001893939/0.027816095)
    % h# V; i  c4 _p <- (1 - pnorm(z))*23 r4 R$ V) ~3 g! N6 M5 R
    p
    . n2 _. O4 }; w4 `; @1
    5 n  c& ~3 T" C2 }7 t## [1] 0.94571578 k% o9 r# z) V5 K0 y( O; @3 K2 p
    1
    ! X& {7 v7 d# lPredictABEL包
    : N$ b! T4 m# Y4 e$ L9 e( b#install.packages("PredictABEL") #安装R包
    6 v; t" r2 _5 ~, Qlibrary(PredictABEL)  " f/ F$ T/ w3 U. ~6 d

    6 `& R$ L) o; f8 A( I9 x# 取出模型预测概率,这个包只能用预测概率计算
    $ S: A3 I* U8 g: q* O' H' dp.std = mstd$fitted.values
    . q' N: h$ ]1 H1 g/ P0 |  Np.new = mnew$fitted.values
    " S# Q7 v& W# _9 f. f* ?( ^1
    " ]0 }4 T( U) V& y6 Q* m0 t( d然后就是计算NRI:( P5 e! }6 @" w0 ]

    8 q8 a0 u, A& {dat$event <- event
    + q7 ?- ~( o" v: g: r" P
    ' O8 P1 A0 n1 G  n- N4 treclassification(data = dat,# P: M/ e0 K; M- D* X; K7 }
                     cOutcome = 21, # 结果变量在哪一列: U) l$ O- b7 C3 {3 `% k
                     predrisk1 = p.std,
    & G5 Z; c! X  |: v, q9 a7 r1 w                 predrisk2 = p.new,
    9 Z8 B7 O& Q' S6 v                 cutoff = c(0,0.3,0.7,1)
    - j: u9 m# A. S                 )
    ) b/ |1 @! S% q. U1
    1 y- `( O! ]) R" q& N+ H9 I##  _________________________________________
    " ^# }% ^# t& J##  2 F+ F! H6 F9 r# `$ p
    ##      Reclassification table   
    & j; T/ ^% z9 G9 R/ M##  _________________________________________
    $ W3 C# }4 \* i! Q1 T9 ?, R## , D7 [* ~6 A/ @* N% n  g2 i+ d
    ##  Outcome: absent % ^% w" h& n$ l. v
    ##   ( i) \1 ]8 t, t# m7 w8 `9 ^
    ##              Updated Model$ K: a3 A& K" `8 P
    ## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
    & ]7 \8 T6 i9 u4 E! e: ]6 K! @##     [0,0.3)       121         4       0               3. I3 r& P5 m% a  D( s
    ##     [0.3,0.7)       1        13       1              13
    " q% l" S, |6 ]: Z& _5 \1 k3 p##     [0.7,1]         0         1       3              25
    ( C8 V  u( W) e2 i## 3 y- B4 h7 S- p  }
    ##  : m* S- Q, D. A
    ##  Outcome: present
    " V; G% ?% w9 g# b% z##   
    7 g/ O7 L% Q  e2 _. F& m6 t##              Updated Model
      r7 Y& d1 }% I## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified& |! V$ J5 }5 g; _
    ##     [0,0.3)        14         0       0               09 D0 E& C' h! `; s. u$ w" o) O
    ##     [0.3,0.7)       0        18       3              14/ P; X" O! d. n6 b1 [+ Z' I
    ##     [0.7,1]         0         1      52               2, R; E2 Y1 f5 W- m
    ## 7 G  ^- p( g8 c: F3 Y. Z) \
    ##  / B  h9 u/ Q0 C. T, q2 V- n" T
    ##  Combined Data
    1 ?0 S" C% t  R1 T& L. E. U##   6 J: U) A2 Z; C2 `
    ##              Updated Model2 w4 }! N; e9 z. k2 p5 d8 a
    ## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
    / {* U0 \6 U6 O+ G9 |- c9 J! W##     [0,0.3)       135         4       0               3
    " z  c4 {0 X' E) F" L% }/ A##     [0.3,0.7)       1        31       4              14
    1 F7 K+ b$ f! j& |5 t##     [0.7,1]         0         2      55               4
    7 H3 _" s% {) V( j* z: R##  _________________________________________5 _8 L1 `# I! F5 Y
    ## / K: @& A0 w! n) n9 B: Z% l: e' j: t
    ##  NRI(Categorical) [95% CI]: 0.0019 [ -0.0551 - 0.0589 ] ; p-value: 0.94806 4 k" P* [2 c4 z
    ##  NRI(Continuous) [95% CI]: 0.0391 [ -0.2238 - 0.3021 ] ; p-value: 0.77048 6 n; T. O5 f' D2 V# r* \
    ##  IDI [95% CI]: 0.0044 [ -0.0037 - 0.0126 ] ; p-value: 0.28396: d0 ]' |' R+ {. B$ y- A9 |

    & b+ S9 M2 z+ }0 P1 D1 ]1
    & h3 F" n6 i0 W; n0 ^( Y结果得到的是相加净重分类指数,还给出了IDI和P值。两个包算是各有优劣吧,大家可以自由选择。
    ' _+ ?  N% J! Y9 H! M$ M7 z
    & Z* ?, F! O- z生存分析的NRI
    # {; y  v7 ]. b: w  N* Y4 f还是使用survival包中的pbc数据集用于演示,这次要构建cox回归模型,因此我们要使用time这一列了。
    ( X, y0 e+ b2 p6 E( d3 J* e& C' y! Y  Q- p2 @/ n3 X
    nricens包
    2 {( f) p2 ?; k9 c* G+ t1 ]' O  Glibrary(nricens); V. `' y/ e4 T
    library(survival)
    ! N4 G& V. D( H+ K0 m4 o3 G# O- j  r. [  c  c0 y. l
    dat <- pbc[1:312,]& P# n. H5 H" X- N# P1 x0 F; `
    dat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡* w' J& P: J7 c  p6 @( [
    1
    : Q6 |0 M& f" {* }6 X# v# W& F3 p然后准备所需参数:
    ' U/ ^2 J! ], U! k! w7 A0 i. G/ Z( u% L6 K; b
    # 两个只由预测变量组成的矩阵; O6 h1 F& D6 U' q" ^$ E; m, ~
    z.std = as.matrix(subset(dat, select = c(age, bili, albumin)))
    5 ~) E, ?$ g- Az.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))% J7 _7 u( i8 F0 U4 h1 t

    $ b  \& z0 ~, B; v1 K+ ^0 M7 [# 建立2个cox模型
    ; ]0 R- |# D6 w! _4 T3 K; `mstd <- coxph(Surv(time,status) ~ age + bili + albumin, data = dat, x=TRUE)3 f3 `' U9 i  E6 W/ v9 ?
    mnew <- coxph(Surv(time,status) ~ age + bili + albumin + protime, data = dat, x=TRUE)
    - j) i: ?+ g6 H. m5 U6 Z  n6 n. v
    $ ^8 f7 H$ W% ^0 E# 计算在2000天的模型预测概率,这一步不要也行,看你使用哪些参数
    0 A  o2 j- N' w! y: S! Up.std <- get.risk.coxph(mstd, t0=2000)
    5 g: ^1 V8 a8 Y1 Z* Mp.new <- get.risk.coxph(mnew, t0=2000): P- {. U) F4 T2 y% d* [' S, B
    19 Z7 }3 d' U( d
    计算NRI:
    " m% n8 Z7 h* q& O* P
    ' z- \/ X6 R" V; @3 Mnricens(mdl.std= mstd, mdl.new = mnew,
    : o' ~! z- ]% P# t. b        t0 = 2000, 4 o8 c: w& G! }5 z7 I
            cut = c(0.3, 0.7)," A; j3 l3 i9 J; D8 R7 F9 {
            niter = 1000,
    2 F; r% X" f" c9 R! P        updown = 'category')
    , X1 S  q2 Q5 _) D. ~6 n5 o
    1 ^5 w/ P; _% b0 kUP and DOWN calculation:
    . S5 `6 @  N. L: A! O$ ]7 p  #of total, case, and control subjects at t0:  312 88 1447 ~* f! I/ D8 S1 Y0 S* F
    - D7 q8 b! p1 Q
      Reclassification Table for all subjects:
    8 |" K$ r* X( W        New; _/ |) D# x3 x4 z0 [, a- c
    Standard < 0.3 < 0.7 >= 0.7
    4 a4 F( O6 ^% g( Q9 F5 G  < 0.3    202     7      0
    5 X* S5 n; Y% M1 n+ i3 s  < 0.7     13    53      6. e7 q" l, C1 \* _
      >= 0.7     0     0     31
    : ]* `8 h5 f  L$ Q7 a( g& s# u/ O. w: a, }$ V
      Reclassification Table for case:
    ' ^5 f& B$ J. E* w8 t        New
    + a9 W1 t8 W0 `2 Q% [* J) vStandard < 0.3 < 0.7 >= 0.7
    / \' i' Y* E" _  < 0.3     19     3      0
    / `: m* o/ X' W  < 0.7      3    32      4) b5 m. r8 i2 d. ?3 q7 L8 [% N( O
      >= 0.7     0     0     27& D$ K2 f' o8 h% k$ N
    : G3 w3 [2 r# W$ M/ p0 L. g
      Reclassification Table for control:8 Q* X0 E, ?3 P; K- l
            New
    + a' }6 ]+ G, s$ uStandard < 0.3 < 0.7 >= 0.7
    " t2 L0 d+ b9 ~6 O8 T  < 0.3    126     3      0
      _- b$ G) s# n; H: Y$ |9 s, ^  < 0.7      5     7      2
    - Y9 \1 D4 Y8 l2 n; L; n* T" ]  >= 0.7     0     0      1
    ( b! h# C+ ~- u6 i& y! p, C; W" S! T: k6 `$ Z
    NRI estimation by KM estimator:! _5 `, q" i& g4 L7 j- {
    5 v5 @) l: ^" c# E' Y2 Z
    Point estimates:
    0 ]4 h' H& m7 e/ ^                Estimate
      ^) L& x5 D) [% T, |8 }; {; ANRI           0.05377635) s# U. ], f/ L6 V, u
    NRI+          0.03748660
    . x4 P1 H% Y/ \' S. w2 X& F$ kNRI-          0.01628974
    ! m6 Q/ ]5 x2 \2 HPr(Up|Case)   0.07708938  y# {3 z. _' ]/ J
    Pr(Down|Case) 0.03960278
    ; `8 ~  v( ?8 E8 K9 b- YPr(Down|Ctrl) 0.042563523 k( o/ H, a4 [! {  @- i
    Pr(Up|Ctrl)   0.02627378# I/ n) K' z+ \' Z3 z( _; H+ y

    ; Z/ d' ?. x( V3 S0 w6 n) g3 m( _Now in bootstrap..
    ' k# G) [2 f  C: T' j6 ^. W9 k- d1 N6 w4 E1 d4 ?: l5 G
    Point & Interval estimates:
    2 q$ Q& |" v& d0 n% x6 X# F$ w                Estimate        Lower      Upper
    * d& R2 u2 Y* T( x" ]$ B1 PNRI           0.05377635 -0.082230381 0.16058172
    8 h* l- M# n' s- S9 WNRI+          0.03748660 -0.084245197 0.13231776
    * t+ y/ y+ @# V. WNRI-          0.01628974 -0.030861213 0.06753616( J, `* N( Z5 t) F) Q% V
    Pr(Up|Case)   0.07708938  0.000000000 0.19102291+ U8 |3 m( D7 W4 f& v" h
    Pr(Down|Case) 0.03960278  0.000000000 0.15236016+ u5 A* d0 K4 i$ F" n9 g; K8 \5 c
    Pr(Down|Ctrl) 0.04256352  0.004671535 0.09863170# Z6 q' w6 j1 p4 r# _3 v
    Pr(Up|Ctrl)   0.02627378  0.006400463 0.05998424
    * J/ q/ S5 u" ?# e: z
    ( x& L8 q7 |! g0 T7 A- R1- l- b4 a$ M# }
    % _! Q! q/ r' Y" G9 J% B4 h/ @5 l
    Snipaste_2022-05-20_21-49-38
    7 ?9 D* l+ Q1 K: J4 I- g结果的解读和logistic的一模一样。
    3 U( b) _) G0 @
    7 R) Z9 _* c4 b4 g8 BsurvNRI包
    4 v# G% E+ q9 t* I7 s# 安装R包
    ' s/ l! p8 L* Bdevtools::install_github("mdbrown/survNRI")7 t$ W! F8 V0 `7 T4 h: O- v
    15 B3 w! m$ j: J) i! q4 Z5 o
    加载R包并使用,还是用上面的pbc数据集。1 a7 x& u1 G  D3 R( U8 T) [  F

    ) F5 v; o! c9 |! i2 c4 wlibrary(survNRI)- ~3 q$ {4 @( j) y7 ~
    1; i& X# k- r0 K; l& C% K
    ## Loading required package: MASS
    3 M6 \# X  N5 U1
    3 p9 l: V9 _0 O! X8 jlibrary(survival)
    + w) ]2 X4 b7 E7 O$ J% H% n7 A0 {2 L$ R1 B2 D
    # 使用部分数据6 v: j+ L3 r2 ]2 F/ T) c
    dat <- pbc[1:312,]- N( @$ r! N) [! `1 I' y
    dat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡
    + J+ f* q& i6 J8 s. Z5 @' u5 F; H% a) l  D
    res <- survNRI(time  = "time", event = "status",   Y' I1 J" X& T
            model1 = c("age", "bili", "albumin"), # 模型1的自变量
    * O+ T0 b5 r( ]) c2 e        model2 = c("age", "bili", "albumin", "protime"), # 模型2的自变量
    8 j3 J9 K2 U; y+ a- r3 H( Y        data = dat, * K: U9 h! r5 f0 ^. g: B
            predict.time = 2000, # 预测的时间点! ~5 Z" _+ U" U+ h* U
            method = "all",
    " t$ v7 j1 I1 Q2 H; W( d9 v8 w. S        bootMethod = "normal",  
      F6 M. ]6 R( a' w        bootstraps = 500, 9 {' m& U2 E- _
            alpha = .05)
    - m+ s( r, C# r( A- S/ c; S: l6 b# g. o" j
    1
    & Q) j0 r. [7 r( k9 u& L4 G# J" h查看结果,$estimates给出了不同组的NRI以及总的NRI,包括了使用不同方法(KM/IPW/SmoothIPW/SEM/Combined)得到的结果;$CI给出了可信区间。
    4 W% N8 o  B  U
    ' ]) }! @" ]: L+ p. Nres9 V- v/ o' n0 H. ~3 z
    1$ t- d& z* ?5 p  [# Z- e
    ## $estimates$ a6 m; r! b' d: k
    ##            NRI.event NRI.nonevent       NRI
    0 r$ n- o) Z& }9 q3 H4 l## KM        0.20445422    0.3187408 0.5231951
    + {. R6 n3 {: u/ U, }5 H## IPW       0.22424434    0.3273544 0.5515987
    % a9 Q8 `2 E7 o& e5 J; c  T/ v0 p8 @3 B## SmoothIPW 0.19645006    0.3144263 0.5108763
    7 v) ~$ n) g, ^2 f* H* Y! R## SEM       0.07478611    0.2632127 0.33799885 n# I7 R+ @: C- `/ J! Y
    ## Combined  0.19633867    0.3143794 0.5107181/ [' }: [. ^) d% d0 _- L# Y) L
    ##
    6 b0 _9 F3 d2 r/ A( c! R0 M: s8 @## $CI" {$ Y+ ~7 _& O- Y& {. |
    ## $CI$NRI.event
    ) W" [  c1 w; y8 v5 o+ p##                     KM         IPW   SmoothIPW        SEM   Combined
    2 P( D& q7 @- z. ~# \## lowerbound -0.03915924 -0.02185068 -0.04724202 -0.1162587 -0.04737232 p) f) N' @* ?2 b& x+ ?
    ## upperbound  0.44806768  0.47033936  0.44014214  0.2658309  0.4400496( H5 ]- L: @1 p2 A& ~
    ## - S- I- C1 S0 G
    ## $CI$NRI.nonevent8 \7 H3 i+ s" k# V( {9 c) X6 w! Y+ W
    ##                   KM       IPW SmoothIPW        SEM  Combined" V9 Y7 V/ R$ _0 T0 ~
    ## lowerbound 0.1317108 0.1396315 0.1286685 0.08638933 0.1286426
    4 b8 ^. Z( L0 [( G3 z## upperbound 0.7102251 0.7393216 0.6966341 0.51482212 0.69645499 n3 Z$ C0 p8 [5 x
    ## / f1 P- b# _+ M1 }) p3 d& V
    ## $CI$NRI
    4 l- D! u) A; D! q1 V##                     KM         IPW   SmoothIPW         SEM    Combined! @% O! r5 G1 |0 ?- F( a6 F5 Y5 O9 @
    ## lowerbound -0.05112533 -0.04569046 -0.05439863 -0.04132364 -0.05443409
    ' l/ N5 D# ~" I## upperbound  0.89306122  0.92464359  0.87970125  0.64253510  0.87953153
      T) }$ T  X+ ]. E) m) f## # b) T1 v6 Y+ a! p' z# f  I- y. A) ^
    ##
    ' o0 E. _; U5 k" h## $bootMethod5 {# T/ G2 V( j  N: n" A. B
    ## [1] "normal"
    ! c" z' h8 n; T7 U5 [$ x6 Z& V## # ^  l' ^! s7 N
    ## $predict.time
      V9 P+ L- ~9 p& f, t5 O% C## [1] 2000
    $ A8 E, @2 V& g6 J. U## " `, D7 f! K8 h; N, y
    ## $alpha
    & m( O% T* G9 ~3 W/ [8 M7 t9 E# e8 C## [1] 0.05
    & k2 A) U) p( J2 w8 N## 7 [4 v6 l6 z  p/ D* D' G& h- y& b4 M
    ## attr(,"class")& ?' @8 x, s; f
    ## [1] "survNRI"" h( R9 P/ `  [% w: M6 G. Z9 |

    0 E- K' q' ?1 l2 q/ H8 p, F1
    # ], e1 J# \( e6 u9 t4 y4 c$ pOK,这就是NRI的计算,除此之外,随机森林、决策树、lasso回归、SVM等,这些模型,都是可以计算的NRI的,后面会继续介绍。大家如果有问题欢迎在评论区留言。3 s7 l8 k; i0 E  H5 b8 l
    * ^- P* u. l: u7 o$ I
    本文首发于公众号:医学和生信笔记
    % u2 ~# s8 P$ _( B& C
    . h0 W8 X8 _' N' c- ~7 ~: a6 s“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。  i# n) Z0 h; V( y) \
    本文由 mdnice 多平台发布. P- f6 k/ C+ ~% x* e8 a
    ————————————————
    1 `9 f; J# |. }  s版权声明:本文为CSDN博主「阿越就是我」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。( z4 d4 O  D: m
    原文链接:https://blog.csdn.net/Ayue0616/article/details/1267680063 U& ?9 B! G! [7 e! Z% K$ V# T- g; C, H8 ]1 }
    3 s/ H3 F( W/ J6 |. f) t* O

    : }) S6 d' m, A9 Q8 D
    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-6-12 21:23 , Processed in 0.467829 second(s), 51 queries .

    回顶部