QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3019|回复: 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
    3 n1 H* c% M) H
    净重新分类指数NRI的计算
    # m- w# Y. x/ d& d8 ?- F5 O% q9 V5 a“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。) G0 M  A7 F. f
    NRI,net reclassification index,净重新分类指数,是用来比较模型准确度的,这个概念有点难理解,但是非常重要,在临床研究中非常常见,是评价模型的一大利器!1 w* B$ l6 z! X) U! v3 q0 t& V1 M0 c
    1 ^; p/ z/ @7 P+ t# ]' o* F+ u: W
    在R语言中有很多包可以计算NRI,但是能同时计算logistic回归和cox回归的只有nricens包,PredictABEL可以计算logistic模型的净重分类指数,survNRI可以计算cox模型的净重分类指数。
    * w6 N' V9 u' t" b
    ! I. X/ U" b; U/ W, {8 F, slogistic的NRI9 Y& u/ a, j3 r( s
    nricens包
    , E6 S; y7 b! r) [5 aPredictABEL包2 R  r2 }- P# W' h4 `+ c+ B" [0 Z* a
    生存分析的NRI" E/ \/ J; E2 w
    nricens包; J" P; l9 E& j1 L2 P. L8 R8 r( D
    survNRI包
    4 K7 U3 ~+ Y# v" l0 l4 O: T, t& blogistic的NRI" h7 v* t0 V3 P" O
    nricens包
    ( S5 l3 B, k1 L+ u0 R$ T/ L, x#install.packages("nricens") # 安装R包
    7 l+ l, l2 }# e$ j/ @library(nricens)
    % @: g! o4 c! `) g4 B1) m/ g+ n2 P# |/ B3 D( Z; A, P
    ## Loading required package: survival
      C* R' G# r3 y+ d$ Q) ]0 i  J7 U6 A1
    , \3 b& n8 r* h8 d% }- m+ x使用survival包中的pbc数据集用于演示,这是一份关于原发性硬化性胆管炎的数据,其实是一份用于生存分析的数据,是有时间变量的,但是这里我们用于演示logistic回归,只要不使用time这一列就可以了。! C6 s, d! {& _2 e
    ! Y9 q5 F9 c- v5 Q; E- T
    library(survival)
    ; ?9 {; C; a. v9 S( p: M/ [0 f9 D. m; o, C/ {3 D
    # 只使用部分数据
    2 L4 E" Y" w1 T% H: H- ]  qdat = pbc[1:312,] : U# S0 @/ h9 F- T/ l) s6 k: o
    dat = dat[ dat$time > 2000 | (dat$time < 2000 & dat$status == 2), ]3 Q# k; ^% K5 K% O4 J) H! E" z7 R

    1 e/ `  s1 a- j( |str(dat) # 数据长这样
    . |3 k2 ]$ r% _" s- f% w( g1 v1* A5 z# T' j" a, w& u$ h$ S+ O. o9 y5 a
    ## 'data.frame': 232 obs. of  20 variables:
    ( v1 ]3 T8 L) |# ~; h/ }" \##  $ id      : int  1 2 3 4 6 8 9 10 11 12 ...7 O7 S3 Y) z5 Q/ C
    ##  $ time    : int  400 4500 1012 1925 2503 2466 2400 51 3762 304 ...
    9 r7 ]/ B3 M# ~8 H##  $ status  : int  2 0 2 2 2 2 2 2 2 2 ...3 v# O  Q/ J# H) f' f8 R/ g
    ##  $ trt     : int  1 1 1 1 2 2 1 2 2 2 ...& L% X# u2 u' H$ ]
    ##  $ age     : num  58.8 56.4 70.1 54.7 66.3 ...
    ) n" ]2 q" i6 Q2 y  M##  $ sex     : Factor w/ 2 levels "m","f": 2 2 1 2 2 2 2 2 2 2 ...3 G& [( G7 v7 n5 P( K: D8 [
    ##  $ ascites : int  1 0 0 0 0 0 0 1 0 0 ...2 u, g6 O% H0 A' @
    ##  $ hepato  : int  1 1 0 1 1 0 0 0 1 0 ...
    9 e1 A1 N, k9 W6 @, ~/ W, X+ s! z0 _##  $ spiders : int  1 1 0 1 0 0 1 1 1 1 ...
    " U6 N7 c( R3 C( f1 I9 d' x##  $ edema   : num  1 0 0.5 0.5 0 0 0 1 0 0 ...
    2 N) Y% i2 [9 x7 c##  $ bili    : num  14.5 1.1 1.4 1.8 0.8 0.3 3.2 12.6 1.4 3.6 ...
    . t/ l- s5 R( v& Q##  $ chol    : int  261 302 176 244 248 280 562 200 259 236 ...( E/ g  g( F9 w
    ##  $ albumin : num  2.6 4.14 3.48 2.54 3.98 4 3.08 2.74 4.16 3.52 ...
    / ^. z! e3 i: C' E# |##  $ copper  : int  156 54 210 64 50 52 79 140 46 94 ...5 A: R# e# A7 @5 y' p* h
    ##  $ alk.phos: num  1718 7395 516 6122 944 ...& Z0 C# o& e* H
    ##  $ ast     : num  137.9 113.5 96.1 60.6 93 ...
    + {# Q" x( [8 S* ~% |, |: k##  $ trig    : int  172 88 55 92 63 189 88 143 79 95 ...
    # e- \# a" U$ m1 y: ~. s##  $ platelet: int  190 221 151 183 NA 373 251 302 258 71 ...
    5 t# Y4 ~' j6 w##  $ protime : num  12.2 10.6 12 10.3 11 11 11 11.5 12 13.6 ...$ i) Y- F2 u3 E. ]- m4 x( i# G
    ##  $ stage   : int  4 3 4 4 3 3 2 4 4 4 ...
    + \/ Q# q! P+ t( N! U
    5 g: T) X6 m/ R+ S2 B1: N& l; q9 M7 _) t8 J
    dim(dat) # 232 209 R6 u  \" A1 b" P& U) Q: ^+ q
    1
    & h8 |+ W# Z7 t0 b4 q## [1] 232  202 K+ o6 C. A! ~' b1 O" @1 h
    1
    + @$ A" d, u/ c8 R$ q0 l然后就是准备计算NRI所需要的各个参数。! I& D1 e0 D! [' `' \7 J
    ' Y' P9 `3 i7 W& ~
    # 定义结局事件,0是存活,1是死亡
    . }) K; I5 ~5 Pevent = ifelse(dat$time < 2000 & dat$status == 2, 1, 0)
    " M3 v; E7 P0 B1 y
    $ h' L& f7 k6 C# 两个只由预测变量组成的矩阵4 {7 A- C8 r8 {/ E* J9 n
    z.std = as.matrix(subset(dat, select = c(age, bili, albumin)))
    / T/ O/ k& Q7 Y% gz.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))
    + C2 c( |6 `1 w+ E3 E
    : `. \. P1 z! k2 t# f, j# 建立2个模型
    3 \# l6 B0 g3 E+ t0 z# w* Hmstd = glm(event ~ age + bili + albumin, family = binomial(), data = dat, x=TRUE)
    , n9 b( l1 F( l6 L5 [4 pmnew = glm(event ~ age + bili + albumin + protime, family = binomial(), data = dat, x=TRUE)
    , j* f+ y. y. K! ^2 r# j. n, G0 ~
    2 E/ a# N; Z: m% k; O7 ^7 }# 取出模型预测概率% k/ A/ i& ]" w2 Y- R9 @7 A' Y1 }
    p.std = mstd$fitted.values
    3 G* |( a: q8 o; ?" Tp.new = mnew$fitted.values
    " @9 O* G' i# x9 \/ K! e5 Q
    5 }. N) Q$ F/ ?+ `& F1$ D! X/ o- X+ I0 F/ Q( Q+ t( d
    然后就是计算NRI,对于二分类变量,使用nribin()函数,这个函数提供了3种参数使用组合,任选一种都可以计算出来(结果一样),以下3组参数任选1组即可。 mdl.std, mdl.new 或者 event, z.std, z.new 或者 event, p.std, p.new。" M8 }2 k" s4 s/ E

    * `, G  C9 k+ @6 t7 j6 `; `$ g# 这3种方法算出来都是一样的结果
    % Z0 T  R3 d) Y' O3 [5 c* r6 @1 |3 J* Y8 i9 M5 |
    # 两个模型
    . d% J* W2 t5 ?- t2 vnribin(mdl.std = mstd, mdl.new = mnew,
    : @6 {8 [( d9 L       cut = c(0.3,0.7),
    / Q3 e& _; {8 Q: b( k+ G. A       niter = 500,
    8 C( t+ _4 `6 \       updown = 'category')
    0 I, e. q8 @- _* e7 @, x/ g& h- b" r+ ~
    # 结果变量 + 两个只有预测变量的矩阵; _* s$ v- d6 ^! z; R
    nribin(event = event, z.std = z.std, z.new = z.new,
    & W0 V7 }. M; `; y1 D+ v       cut = c(0.3,0.7),
    8 R" f( U: O' w$ Q6 I       niter = 500,
    ! y2 p2 W/ Z/ S! l3 T/ z       updown = 'category')
    + a' i1 t+ H# I5 w7 B% V
    8 O2 L2 |" A3 Y- o3 R; G## 结果变量 + 两个模型得到的预测概率% [6 x" J) Y% N0 F! z
    nribin(event = event, p.std = p.std, p.new = p.new,
    : q/ e, M8 R" K: G1 b       cut = c(0.3,0.7), $ [) r9 f  N1 a* Q
           niter = 500, 0 |+ X4 J: Y+ B( I6 ^9 K, |) ]
           updown = 'category')
    & D& r- z- O" Z5 o; S' A1 P  ^$ v1 _" {
    1
    9 b+ s% A4 {. w' W4 ^/ g  {3 ~% U其中,cut是判断风险高低的阈值,我们使用了0.3,0.7,代表0-0.3是低风险,0.3-0.7是中风险,0.7-1是高风险,这个阈值是自己设置的,大家根据经验或者文献设置即可。
    & l, d  G! ~% H9 A
    - K+ ]3 `. a6 [9 _4 x8 C% {niter是使用bootstrap法进行重抽样的次数,默认是1000,大家可以自己设置。8 z& g" |& B# t

    0 }/ q& K' t9 Q+ o7 Y3 y5 d0 Eupdown参数,当设置为category时,表示低、中、高风险这种方式;当设置为diff时,此时cut的取值只能设置1个,比如设置0.2,即表示当新模型预测的风险和旧模型相差20%时,认为是重新分类。
    , b7 d, G2 Q  j8 Q, c4 g  N; U3 }: e! ]2 p  M
    上面的代码运行后结果是这样的:) K( o7 V  G: z1 |
    ! r4 W# J( p/ r
    UP and DOWN calculation:
    2 Y2 M# l2 a9 E4 o" P/ M! r! e  #of total, case, and control subjects at t0:  232 88 144& ]. v% e, C) @! i4 D; Q

    3 h9 V5 B3 N- W, |% P) b% i  Reclassification Table for all subjects:
    ( v# A* a% F7 I0 ~        New
    : W3 R; I- Q! Q3 q0 r9 ?- @! t! _Standard < 0.3 < 0.7 >= 0.7. n% i: W8 S5 b2 ~2 I6 j
      < 0.3    135     4      0
    6 [: E- T  a# F8 |  < 0.7      1    31      4
    ; N: ], \% t+ \) t9 I# P  >= 0.7     0     2     55
    4 S( X; A3 m' m$ x' _
    - s- d3 w/ `; @4 B' z) a' J  Reclassification Table for case:& A& V' k* m* V! n! ]: u7 ?% k8 c
            New( N) r! o( G) {' e1 p
    Standard < 0.3 < 0.7 >= 0.7
    - Z* Y/ d8 O7 S8 z6 H  < 0.3     14     0      0- j. f( @5 B* T* I0 U" L9 H4 A) f
      < 0.7      0    18      3; Q( T2 J# e: H, H* B0 `0 ~
      >= 0.7     0     1     52
    , g, y1 H# z% l  z
    " ^4 [! q  K! n/ ^  Reclassification Table for control:# [5 h( c  ^( e4 ~/ R) W9 y$ ~
            New
    / n" V/ z; c% Q* k. k; kStandard < 0.3 < 0.7 >= 0.7
    ; T* [/ o3 @, G  < 0.3    121     4      0
    ( O( D( ]$ B$ P$ U0 z: _  < 0.7      1    13      1  R( r% w+ `, T
      >= 0.7     0     1      3
    4 u2 ?/ M; u  R; A' ~+ ~" [3 i6 ^
    NRI estimation:/ v  w; d9 B# y% |4 C, {, l
    Point estimates:
    * p9 J4 b& f0 r, X                  Estimate& w; v) Y+ Q  _  m
    NRI            0.001893939
    % R4 u2 q- U" D) k, m% u3 \. uNRI+           0.022727273( X) \% P3 c2 f6 C1 ?! T  ~
    NRI-          -0.0208333337 J) B. c' V' @' H" C5 c
    Pr(Up|Case)    0.0340909096 v7 Q+ w4 G; b$ v% ~
    Pr(Down|Case)  0.0113636367 Q, ~* `# e/ ~
    Pr(Down|Ctrl)  0.013888889
    1 g) Q& l* E3 ]3 ?5 {Pr(Up|Ctrl)    0.0347222222 d1 l8 T8 L2 V; ^0 r) b
    5 e) E; l( R( w# |; A& C8 W. p- h
    Now in bootstrap..
    0 Z- I# U: D2 X2 O! L( \
    ' J. _! E& I6 i- C; O+ PPoint & Interval estimates:
    ' z4 Q  y0 h! c+ Y. ]5 _! L5 n. T                  Estimate   Std.Error        Lower       Upper, U/ }7 N% u) ~7 D1 s% R+ Z! U
    NRI            0.001893939 0.027816095 -0.053995513 0.055354449
    ) s  w3 r: |- _0 ANRI+           0.022727273 0.021564394 -0.019801980 0.065789474& M; r) P# l6 x6 d: u6 L# z, n# O9 m
    NRI-          -0.020833333 0.017312438 -0.058823529 0.007518797
    , P* ^/ i" n$ ?  t: \Pr(Up|Case)    0.034090909 0.019007629  0.000000000 0.072164948
    1 z9 l+ l. n% W( G4 c' QPr(Down|Case)  0.011363636 0.010924271  0.000000000 0.039603960  W0 o7 ]/ t/ K7 F) |4 W. f9 g
    Pr(Down|Ctrl)  0.013888889 0.009334685  0.000000000 0.035211268# c: h6 ?: x1 d# `. f/ W& Y
    Pr(Up|Ctrl)    0.034722222 0.014716046  0.006993007 0.0661764717 X4 e7 M( j' m

    3 E: T, G# F  q1; L- G# L; ~* V) I. o4 H9 K/ F
    首先是3个混淆矩阵,第一个是全体的,第2个是case(结局为1)组的,第3个是control(结局为2)组的,有了这3个矩阵,我们可以自己计算净重分类指数。4 [: c3 J+ _! X. H2 B& E

    9 @  b! {" X$ t2 |. z看case组:& G( {0 n4 S6 |% q8 \7 S- H

    4 c) k& a! i, R5 }净重分类指数 = ((0+3)-(0+1)) / 88 ≈ 0.022727273
    1 X0 C; P' O% a0 Z* R1 ~0 ^1 R# U
    再看control组:  u1 j7 p1 t. l! `
    3 F# R/ z7 v6 k
    净重分类指数 = ((1+1)-(4+1)) / 144 ≈ -0.020833333' C- @( W7 m, x7 E" Q7 e7 q

    0 @' R6 ?4 F$ a相加净重分类指数 = case组净重分类指数 + control组净重分类指数 = 2/88 - 3/144 ≈ 0.0003156576 _' K) m: k% f% n* C" a0 |5 r- J

    " p, Y- k1 t+ ]! E0 h4 J6 I0 Q9 N2 L. y再往下是不做bootstrap时得到的估计值,其中NRI就是绝对净重分类指数,NRI+是case组的净重分类指数,NRI-是control组的净重分类指数(和我们计算的一样哦),最后是做了500次bootstrap后得到的估计值,并且有标准误和可信区间。) r0 q! O& W6 b/ q4 [$ o
    : K9 m4 d" {4 i
    最后还会得到一张图:, p" t% O. |- e+ E& h- _
    9 M1 t% ~4 _( M7 p" b. @
    这张图中的虚线对应的坐标,就是我们在cut中设置的阈值,这张图对应的是上面结果中的第一个混淆矩阵,反应的是总体的情况,case是结果为1的组,也就是发生结局的组,control是结果为0的组,也就是未发生结局的组。
    . a# R+ m4 `' l* X7 {/ J, s2 Y' ~  ^; h. l2 [
    P值没有直接给出,但是可以自己计算。  \. H6 w3 {) d/ O$ q5 C0 D- T

    / z! j/ T: [, e3 ~9 F% P* _  F# 计算P值3 y, y0 G0 o/ S9 U, J
    z <- abs(0.001893939/0.027816095)
    ' o  ^; l" i, K# b5 G% `" up <- (1 - pnorm(z))*2
    " {% C# ]" Y( \  z  Z$ F. Cp$ L, N, H' x: X
    1
    ( K" E: u; R5 K! ~' D+ b## [1] 0.9457157
    ' k" E- Q, j8 @- y7 ~9 U2 ]0 z1/ T4 I3 m5 A; O3 P: Z5 J/ `
    PredictABEL包
    / {) d/ d/ b0 O2 ~8 E#install.packages("PredictABEL") #安装R包9 U" v2 ?4 I# [. C- U. W. _2 x2 R5 n
    library(PredictABEL)  
    + R0 c# z3 n4 ?: Z$ M" ~
    5 I- i, x6 r) K# f4 }* `0 g# 取出模型预测概率,这个包只能用预测概率计算5 a% I6 ?2 @1 H5 S
    p.std = mstd$fitted.values
    6 r  B4 L+ V/ C/ w+ Fp.new = mnew$fitted.values % I" B+ z8 Z3 g( B8 d8 g( }6 g9 t
    1
    1 |' [2 Y9 ]: A% K+ t: j  d$ \然后就是计算NRI:
    * g1 A9 e' J: p) N  u
    " R" u% {( T0 j7 A6 v) m% U+ Edat$event <- event& E$ C" f  ?# j: Y! T% i. L5 `

    ) T6 i$ u! n  b0 q8 t9 Jreclassification(data = dat,( p3 [+ a4 N# i4 m- ~: ~* k
                     cOutcome = 21, # 结果变量在哪一列
    # E, Z% }* ]. f1 P                 predrisk1 = p.std,1 \' m  |; X1 e$ d( s$ W" u# a/ a4 i
                     predrisk2 = p.new,& D' ~( X* N, Y, T. n' N1 q' L! W
                     cutoff = c(0,0.3,0.7,1)
    1 y# w1 [+ q" |9 v$ D5 n) ~) v                 )
    . O3 f0 I" F7 b# c' `4 m1
    # W, b0 T7 R1 N# T- R. f##  _________________________________________
    ) `* r! B2 ~9 R2 B##  
    : m" S% B4 a1 M2 b0 d1 Z% G##      Reclassification table   
    ( n) s% K3 i& ^: g##  _________________________________________# a& I( L% O  v7 A9 h
    ##
    . }0 O7 l% D) U##  Outcome: absent
    6 H9 }9 y- m8 F/ `7 V0 k2 x##   # q6 T! d; A( N+ }% X3 {
    ##              Updated Model
    : A! q# ^" l( X- E; R## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified4 p" x6 ^2 {% ~' F# Y: M1 B
    ##     [0,0.3)       121         4       0               3% f. G4 {8 P/ U' A/ k3 _
    ##     [0.3,0.7)       1        13       1              13) m& o" T2 x4 ~+ b
    ##     [0.7,1]         0         1       3              25. H! t5 L4 z" K3 d2 V
    ## - r# l( n& u: C" z
    ##  - c0 j- G) P* U3 w1 h# Y. p
    ##  Outcome: present - G; n1 d" z# T9 `6 l6 N/ }
    ##   0 j' O* {: y3 b5 q# N
    ##              Updated Model! U6 C8 p+ L. i8 O: S" M9 M
    ## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified" J6 A( Y) T0 `9 A) W" g4 d
    ##     [0,0.3)        14         0       0               0. _: O: m) x$ g  u9 u
    ##     [0.3,0.7)       0        18       3              14; E; A5 Z  H. e
    ##     [0.7,1]         0         1      52               2
    . f, @4 Y  d# N7 K7 d3 v##
    . o8 i/ {4 W3 z8 ^8 m##  2 S& I3 U" g0 g7 S; G1 i0 `, x7 H( ^
    ##  Combined Data ) c& J( K3 x. u/ }2 _
    ##   
    " U: X  H7 C7 l2 O- Y* \/ {##              Updated Model
    * d" `: N" d: Q. X) M& K## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified: M0 Z7 ]. Y8 M, i. I
    ##     [0,0.3)       135         4       0               3
    ; x% K' w7 R. t/ n0 s, w: i/ x##     [0.3,0.7)       1        31       4              143 l. a# [7 C# E1 a! s* V2 b
    ##     [0.7,1]         0         2      55               4
    ! C1 w+ H. i$ X+ A! P##  _________________________________________0 u! I  c: Z, x  ^9 U5 C
    ##
    3 E. R, j; P- p1 ]% X* |! k##  NRI(Categorical) [95% CI]: 0.0019 [ -0.0551 - 0.0589 ] ; p-value: 0.94806
    0 x4 f; Y. Q$ Z, t1 u& u7 l9 h% y##  NRI(Continuous) [95% CI]: 0.0391 [ -0.2238 - 0.3021 ] ; p-value: 0.77048
    1 k) j: e) }/ E9 @( ]; N, W- x##  IDI [95% CI]: 0.0044 [ -0.0037 - 0.0126 ] ; p-value: 0.283961 ?3 Z6 H( v9 Z! e3 B) ], ]
    4 I$ T+ w' R6 E& Z
    1. B1 t! D; K$ Z* @0 R) f
    结果得到的是相加净重分类指数,还给出了IDI和P值。两个包算是各有优劣吧,大家可以自由选择。/ S9 _8 X. L( {$ m

    . ]( w+ u& W) o: H' n生存分析的NRI
    % |' ]/ @# ~# ^0 p! V$ q& `还是使用survival包中的pbc数据集用于演示,这次要构建cox回归模型,因此我们要使用time这一列了。
    ) V( J5 N8 I' O/ j7 l
    ( P, a( x: `6 y/ Q) Unricens包& w8 |0 m1 U4 i8 A" g
    library(nricens)3 ^% T. q2 K# W: O8 z4 K
    library(survival)  ]2 g, x5 q, b: w2 T! P

      R9 f% h& ?6 e3 B  P5 edat <- pbc[1:312,]8 m% |* v0 r' \
    dat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡. H; N0 U, t5 q% Q% }
    1
    ' n. {  G4 A% l: j4 i" I( x! }; a然后准备所需参数:" P& i1 s' P6 Y& h9 W7 x; ?6 u
    ! y4 r2 G( I5 J& A" P/ F
    # 两个只由预测变量组成的矩阵
    6 ^) K8 T: o' n( ?& Z! @8 o7 o2 Dz.std = as.matrix(subset(dat, select = c(age, bili, albumin)))9 `  j; |1 P( L0 J# d
    z.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))
    2 P5 A8 b3 Y( d( G1 ?7 @3 E4 v. E* ~4 `& ~: x" H
    # 建立2个cox模型
    " |% G3 r9 x, E; ^. Z& \9 umstd <- coxph(Surv(time,status) ~ age + bili + albumin, data = dat, x=TRUE)
    % o- S1 `# W- H  j3 B+ M- u' ]mnew <- coxph(Surv(time,status) ~ age + bili + albumin + protime, data = dat, x=TRUE)6 Z) a( i. q5 V: c# u7 h

    : Z) N( c1 y9 }/ `. V" ]# 计算在2000天的模型预测概率,这一步不要也行,看你使用哪些参数' P4 `- B& k1 Z1 \
    p.std <- get.risk.coxph(mstd, t0=2000)
    4 I5 Q  X) p1 yp.new <- get.risk.coxph(mnew, t0=2000)
    . k& R+ a& ^' }. B1/ W, O  n5 a) o
    计算NRI:
    8 C( }$ h9 Q8 R0 k3 }7 t
    ! F, ]) o9 f8 |, Q, r. b% L/ mnricens(mdl.std= mstd, mdl.new = mnew, 6 D1 W8 o$ p) `1 L, J- E9 j
            t0 = 2000,
    , i5 v" B  k. w8 v+ W2 [2 I& F        cut = c(0.3, 0.7),0 F4 d2 j; G9 _+ ^5 _
            niter = 1000,
    2 T" m# j9 \" F5 U2 h        updown = 'category')
    ; h0 r, q' x; K4 q8 {, N1 X6 E2 ^' j9 X% I% X9 o
    UP and DOWN calculation:% r% }: F& Q$ {; n  t
      #of total, case, and control subjects at t0:  312 88 144
    + U! X2 d% \4 V7 j* d6 ~- P# T/ S+ O: H
      Reclassification Table for all subjects:) N1 D6 I6 E1 q( x. C* \
            New  m! H8 P2 `2 _5 u6 A
    Standard < 0.3 < 0.7 >= 0.7% ?' q$ k( T! F9 P, X
      < 0.3    202     7      0
    ( P* M& h5 k7 ~0 w  < 0.7     13    53      6
    ) C. w9 Z; ], H4 O  >= 0.7     0     0     31
    ; C8 z% E# A" }& `# X
    / d; p: l2 w2 i- K( j. h: k  Reclassification Table for case:. h! c: T. ]/ [! V1 B" f
            New
    9 y8 x! P" [1 mStandard < 0.3 < 0.7 >= 0.76 G/ }: @' u' Q( V
      < 0.3     19     3      09 s' b7 F# R- w+ o1 g7 t) }4 _
      < 0.7      3    32      4
    8 f, m* T1 g$ e& G9 ?( T  >= 0.7     0     0     27  T7 y1 C# C( j1 Y5 l

    # L/ K# U4 K4 {$ ~9 P  Reclassification Table for control:. r& J7 U' T* k  f; N% V- Y
            New
    , I$ \4 v( a% F& t0 Q& y/ EStandard < 0.3 < 0.7 >= 0.7
    / ^- i1 q, _& z) |% X- k* g% e2 E  < 0.3    126     3      0
    ; a4 Q8 U" E  C+ I1 c, c  < 0.7      5     7      21 f) |# _& V0 W& p
      >= 0.7     0     0      16 C# y2 |) ~3 R/ H

    7 m. n+ p( u8 G( o; xNRI estimation by KM estimator:
    ' Z/ @* v) n6 \. Z4 ~9 }" b) Y
    Point estimates:$ f1 [5 c# }$ ]
                    Estimate/ {  n% f  j- V7 ]. V
    NRI           0.05377635$ d' Q. i5 X- a" W( v9 {* Y
    NRI+          0.03748660
    ; _% I" l! ]7 g! e- Q) b) ?NRI-          0.01628974
    1 o1 d6 b/ ^. N/ Y0 ~! _Pr(Up|Case)   0.07708938$ z0 Q! q- K& R/ ~0 j. c
    Pr(Down|Case) 0.039602786 ?. G  S! O, r% u( W- `. e
    Pr(Down|Ctrl) 0.04256352
    6 Y0 C1 A# ^$ `1 X1 \: z- PPr(Up|Ctrl)   0.026273782 d  W/ A: |# I: `( o' k
    ( y0 q, g9 S& Q0 U
    Now in bootstrap..
    ) a& [: e) \3 T8 L' [  Y3 r
    ) Q' _( L7 L* k0 F5 s* }: YPoint & Interval estimates:0 e2 k/ J" M4 h7 H9 X9 u4 s
                    Estimate        Lower      Upper3 [8 @& i6 B1 `  o7 ^" Q: N( k7 L
    NRI           0.05377635 -0.082230381 0.16058172
    $ `. q) k  h$ y4 f7 c/ ?NRI+          0.03748660 -0.084245197 0.13231776
    # Z. r: G/ N. ENRI-          0.01628974 -0.030861213 0.06753616
    0 L: |0 _# F/ r9 D* hPr(Up|Case)   0.07708938  0.000000000 0.19102291
    1 [8 N0 h! |+ E9 mPr(Down|Case) 0.03960278  0.000000000 0.15236016; B- [1 c, t3 r4 e
    Pr(Down|Ctrl) 0.04256352  0.004671535 0.09863170
    # i" j' N2 u$ d4 f* `. B2 L/ ?: SPr(Up|Ctrl)   0.02627378  0.006400463 0.05998424( B+ x- M8 M/ u* R& x+ V
    7 K5 E9 E+ W: p4 |4 E2 J
    1  t. J3 d2 g: T9 z

    $ h  b2 J5 X( R7 Y7 {9 h8 |) DSnipaste_2022-05-20_21-49-38# e- D) O0 c. c. S7 ^5 ]
    结果的解读和logistic的一模一样。
    7 K( i$ R; U9 g: R/ B/ U8 o& p# K+ h
    survNRI包1 o1 ]- z& t8 d) X' T
    # 安装R包
    , \5 k; k* L* u8 ]. S& Cdevtools::install_github("mdbrown/survNRI")) k, g) a) t: m
    16 q  o  N3 ]* S9 Z
    加载R包并使用,还是用上面的pbc数据集。
    ) h- D6 R' J4 A9 D' a& g" Q& z& W4 }' S& s; A! ?7 `: x9 B& z
    library(survNRI)
    * j  v. M7 Q* @: v1
    2 d* e6 q. b1 J* Y2 p# @+ P' A## Loading required package: MASS
    $ ^7 @9 A8 M( R1
    * f' ]1 [% R- Blibrary(survival)2 L! W2 ~3 ~# J# [
    - `' ~2 m2 g9 ]6 O" q
    # 使用部分数据" O0 |3 h* G7 y3 R4 H
    dat <- pbc[1:312,]& {3 ]9 ], F4 H0 }  p" o+ _
    dat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡4 O, V3 a; W" `4 b7 K4 ~, a

    % }) W: J: a# A0 Vres <- survNRI(time  = "time", event = "status",
    5 D* w# [0 N9 s3 @$ T        model1 = c("age", "bili", "albumin"), # 模型1的自变量8 |9 s& w8 w* D7 s& V. M. g5 P2 r
            model2 = c("age", "bili", "albumin", "protime"), # 模型2的自变量$ I4 Y9 A% E2 R+ ~# u
            data = dat, * B, i! i7 ]2 s& K
            predict.time = 2000, # 预测的时间点, w  p/ X* i$ B. A! Z7 G
            method = "all",
    ' ~8 U6 l- t0 V        bootMethod = "normal",  
    8 [6 T- x/ g8 J3 m% W; I( g        bootstraps = 500, ) }- J( A& k( w; I8 p
            alpha = .05). h' j$ h: r8 X, v* A- b

    , J" x3 h7 L; m' q1
    * r, O" |5 D6 n, ^- }" f查看结果,$estimates给出了不同组的NRI以及总的NRI,包括了使用不同方法(KM/IPW/SmoothIPW/SEM/Combined)得到的结果;$CI给出了可信区间。
    * G" t# b# {% o- Z  E7 t: c
    * N8 {' i- ]6 `, V$ P; O/ Y# Dres
    ) K4 b! p9 y" p1 w7 z% x: t; B, c2 s1: k9 F. o4 e3 @$ G, A: U
    ## $estimates: L& h/ H, C/ g% m1 a
    ##            NRI.event NRI.nonevent       NRI! Z8 h) f+ x; B$ k1 m0 u
    ## KM        0.20445422    0.3187408 0.5231951
    4 e- J( H( v: H$ v" _: `## IPW       0.22424434    0.3273544 0.5515987
    : d' G" Z( k3 z## SmoothIPW 0.19645006    0.3144263 0.5108763, B) `3 |, e3 I3 `1 \
    ## SEM       0.07478611    0.2632127 0.33799887 k7 D. h& V. e2 `
    ## Combined  0.19633867    0.3143794 0.5107181! w& ], j4 P, X' C' u
    ##
    " q) C$ M! S; ~, R) t## $CI2 j* F) a: k1 d& Z. p2 h# `( V
    ## $CI$NRI.event1 ]- f+ O& ]6 S8 p8 X" e
    ##                     KM         IPW   SmoothIPW        SEM   Combined6 a' U! [6 A' s2 K
    ## lowerbound -0.03915924 -0.02185068 -0.04724202 -0.1162587 -0.04737235 M6 E% k* @6 m/ @5 y  p
    ## upperbound  0.44806768  0.47033936  0.44014214  0.2658309  0.4400496
    ; u1 E. N& A, ]$ y## 4 g# Q3 @1 c2 C2 P3 T5 {% W9 y
    ## $CI$NRI.nonevent* |1 r0 O) h" e" k
    ##                   KM       IPW SmoothIPW        SEM  Combined
    4 d- s2 z: {8 h- E2 Y4 k## lowerbound 0.1317108 0.1396315 0.1286685 0.08638933 0.1286426- ], h  n/ J8 Y
    ## upperbound 0.7102251 0.7393216 0.6966341 0.51482212 0.6964549
    ( Z4 W0 _/ I- V3 z##
    & A' h7 n. r' E& D7 f+ Y## $CI$NRI
    & A$ v  B1 p0 c9 ]##                     KM         IPW   SmoothIPW         SEM    Combined
    : z2 s2 o7 |5 l* y) p6 D! H## lowerbound -0.05112533 -0.04569046 -0.05439863 -0.04132364 -0.05443409
    , u: w0 o: s" }! ^0 u/ @' Z6 E## upperbound  0.89306122  0.92464359  0.87970125  0.64253510  0.879531535 `1 f/ p. b% i1 x. f$ l0 R+ _* M
    ## 7 E8 e' l' x6 K% _2 N
    ## : W3 D0 F: k, a6 g3 |' A4 b& e" M
    ## $bootMethod
    + A: J- b- E  J, w) b## [1] "normal". j" U+ P, A- K! N4 l# p
    ##
    # _* g* n# c1 X* z% X4 [## $predict.time
    ( k0 h; d1 y: k8 \5 |2 B## [1] 2000
    ' u. M5 f1 x) g7 J$ E+ E/ j##
    . Z. `. |, G3 x% K9 G## $alpha7 e8 ]( }4 n$ x# U& E+ k
    ## [1] 0.05
    . X" h! Q* u( N) m8 O% K$ K! e; m8 K##
    4 A+ @3 }# u0 r- \## attr(,"class")
    5 U6 V/ y' c) X2 o3 b  x( x## [1] "survNRI"- |# r1 b! V( ]) H7 H! c  i. j
    $ \1 j& C# n$ y
    1
    ( g$ U9 t% [, @4 e6 J7 }OK,这就是NRI的计算,除此之外,随机森林、决策树、lasso回归、SVM等,这些模型,都是可以计算的NRI的,后面会继续介绍。大家如果有问题欢迎在评论区留言。3 t: o: N; Y: U) s3 N! _6 W( e" l

    - Q( y, _# |' p本文首发于公众号:医学和生信笔记
    6 S  A5 q% N! G, r3 G% h2 O- i
    * p2 ~4 D& ]: l  h“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。
    1 ]1 M2 N, I% s: V- }本文由 mdnice 多平台发布0 M1 E; x4 L+ d$ @( `
    ————————————————
    * c  }' O  \' B3 I5 q+ g6 l版权声明:本文为CSDN博主「阿越就是我」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。8 J8 N1 ~" K3 M' H% A( w  y3 r
    原文链接:https://blog.csdn.net/Ayue0616/article/details/126768006
    4 D/ p  |: e0 n! B2 A0 [9 t! B9 @& X7 @& @4 {$ Q, Y, k8 c+ y
    4 e0 p/ w6 j3 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-4-10 08:55 , Processed in 0.455302 second(s), 51 queries .

    回顶部