QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3041|回复: 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
    4 f, j! U& X) U5 U, c7 ]+ W
    净重新分类指数NRI的计算' f3 @4 I% t7 u  x. G
    “ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。
    1 o; S( }3 ]9 Z0 hNRI,net reclassification index,净重新分类指数,是用来比较模型准确度的,这个概念有点难理解,但是非常重要,在临床研究中非常常见,是评价模型的一大利器!1 b) d- b7 q9 Y) }/ ?& y# O
    0 F, l( X7 H$ x) z
    在R语言中有很多包可以计算NRI,但是能同时计算logistic回归和cox回归的只有nricens包,PredictABEL可以计算logistic模型的净重分类指数,survNRI可以计算cox模型的净重分类指数。# P1 \  b/ |1 t) d3 F
    1 X. n# d7 s! o  m' e5 ]
    logistic的NRI
    2 e4 x) w1 j" z* }5 H' f& {* l( dnricens包
    5 D; h( {& i4 O0 l7 j8 NPredictABEL包6 k: c7 y9 w9 X/ E
    生存分析的NRI; M1 }# j: G" d5 ?3 m
    nricens包' `$ j+ k8 I& x# f  a' ?
    survNRI包9 g, I) O8 m7 M& a& f7 Z+ q
    logistic的NRI
    0 ]6 M3 m- [1 l6 S% L9 gnricens包# [% I9 Y- ]) q" c
    #install.packages("nricens") # 安装R包  y, B. D) I3 I" r0 M
    library(nricens)
    7 ]9 n! W, G0 N" V% {% j9 C1; S, Q0 b6 D6 e# ^
    ## Loading required package: survival: R9 a/ ?, j9 s) L
    1
    + F! T: Q' ~* P- J: a9 ]( ]使用survival包中的pbc数据集用于演示,这是一份关于原发性硬化性胆管炎的数据,其实是一份用于生存分析的数据,是有时间变量的,但是这里我们用于演示logistic回归,只要不使用time这一列就可以了。
    . {3 |0 `5 U1 m1 f
      A% q' s/ K! i" L$ elibrary(survival)6 b' a: G6 m5 \) p# I) G. q1 V2 j; W

    - G. |! `+ s: d# G# 只使用部分数据8 v+ U) _% a" M/ M, @# c) {" `
    dat = pbc[1:312,] 2 A+ }4 B$ f9 C
    dat = dat[ dat$time > 2000 | (dat$time < 2000 & dat$status == 2), ]8 W- Z6 e7 }$ x; ~" k" }9 B( m
    * b3 H9 `: K2 c" K3 v, P; f
    str(dat) # 数据长这样2 ?, f* p' ]- ]3 B: G
    16 v4 e2 ^' p$ c% y0 X, i
    ## 'data.frame': 232 obs. of  20 variables:
    / u9 U0 b1 F0 O. J, f. t##  $ id      : int  1 2 3 4 6 8 9 10 11 12 ...
    7 Q! t2 t' E6 t" v) e##  $ time    : int  400 4500 1012 1925 2503 2466 2400 51 3762 304 ..., b# U. N: |- w
    ##  $ status  : int  2 0 2 2 2 2 2 2 2 2 ...
    ; _* F# d+ E$ M##  $ trt     : int  1 1 1 1 2 2 1 2 2 2 ...
    & R$ b' {8 g$ K% T$ ?3 F: I##  $ age     : num  58.8 56.4 70.1 54.7 66.3 ...
    : e8 A5 M; d; L. H1 u5 n##  $ sex     : Factor w/ 2 levels "m","f": 2 2 1 2 2 2 2 2 2 2 ...: O  v$ q3 p" s$ x& s  L4 e
    ##  $ ascites : int  1 0 0 0 0 0 0 1 0 0 ...9 [$ c4 B5 I2 G$ L
    ##  $ hepato  : int  1 1 0 1 1 0 0 0 1 0 ...0 ?; Y) s$ ^/ f& {% p9 S, n9 m
    ##  $ spiders : int  1 1 0 1 0 0 1 1 1 1 ...) O6 w  V' q% }, b
    ##  $ edema   : num  1 0 0.5 0.5 0 0 0 1 0 0 ...* p) w9 _. q8 y" \1 f; f2 A
    ##  $ bili    : num  14.5 1.1 1.4 1.8 0.8 0.3 3.2 12.6 1.4 3.6 ...# Z" `- g) o- C" y, P  f
    ##  $ chol    : int  261 302 176 244 248 280 562 200 259 236 ...  U" P* R2 {) b& s! j4 ?
    ##  $ albumin : num  2.6 4.14 3.48 2.54 3.98 4 3.08 2.74 4.16 3.52 ...
    ! l  [2 m$ ^( v; L! T##  $ copper  : int  156 54 210 64 50 52 79 140 46 94 ...
    0 n0 C; h' }3 E7 W! K  }* @7 e##  $ alk.phos: num  1718 7395 516 6122 944 ...
    ; K9 w- O  `, }  E2 y##  $ ast     : num  137.9 113.5 96.1 60.6 93 ...' |) A* W* [) i
    ##  $ trig    : int  172 88 55 92 63 189 88 143 79 95 ...  ?* L) x& ^* N0 P1 a  o
    ##  $ platelet: int  190 221 151 183 NA 373 251 302 258 71 ...
    * b& B4 s, V8 `0 U$ G' s##  $ protime : num  12.2 10.6 12 10.3 11 11 11 11.5 12 13.6 ...
    - z& E, v$ v) N4 P* y##  $ stage   : int  4 3 4 4 3 3 2 4 4 4 ...
    8 Z: ?9 y( J" Z* k/ i% W4 b, O, M  p8 V  t
    19 |; z4 S" Z" N6 z
    dim(dat) # 232 20( O: F% x4 K' X- m/ s. V
    1
    3 _& [4 M, w$ Z2 [## [1] 232  20' ]( d2 w2 ?# a
    1
    $ }' D: F0 S6 ^9 z: m1 j! _: k7 Y然后就是准备计算NRI所需要的各个参数。% t: r0 M: B" j3 h9 j
    3 Y7 ~# j* T3 j5 K8 Y
    # 定义结局事件,0是存活,1是死亡
    + x! a# z+ o( k* xevent = ifelse(dat$time < 2000 & dat$status == 2, 1, 0)
    2 E: U. l  ~9 \7 Y- H' W% `; L, ]7 S3 A
    # 两个只由预测变量组成的矩阵+ c8 e  ?# D# S; @+ S, D
    z.std = as.matrix(subset(dat, select = c(age, bili, albumin)))
    ) C# t! [; ?8 k0 v2 S( Gz.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))# [' S$ |' P1 f  i% D) T* u
    ' Y+ s% f$ C; w! v4 ]' K0 @
    # 建立2个模型
    - Z: M! F" C9 O  X" n8 R$ E7 mmstd = glm(event ~ age + bili + albumin, family = binomial(), data = dat, x=TRUE)
    ' P" K9 h' w3 f; I, wmnew = glm(event ~ age + bili + albumin + protime, family = binomial(), data = dat, x=TRUE)0 P9 O7 o$ o% L/ e( `( P

    . h' {# g& z8 P  J# 取出模型预测概率; l) h2 H+ w. P$ e- g6 _
    p.std = mstd$fitted.values
    , h- i, N6 s3 H8 p8 ^p.new = mnew$fitted.values( [& [, c( C! x, n9 k% m8 J
    & z3 F5 r: d# f) m" c: c, v
    1
    & D* [9 Q* `* i* {* o: B然后就是计算NRI,对于二分类变量,使用nribin()函数,这个函数提供了3种参数使用组合,任选一种都可以计算出来(结果一样),以下3组参数任选1组即可。 mdl.std, mdl.new 或者 event, z.std, z.new 或者 event, p.std, p.new。, ~" r, K" U( n% a( u* }* D
    $ ?. n: j: ~2 d- r( P8 v6 n
    # 这3种方法算出来都是一样的结果+ F1 m6 A1 C8 v7 O! _
    ( H, o$ O9 Y+ n8 f# j2 [0 {
    # 两个模型
    $ x% N! x" i2 q2 r6 {nribin(mdl.std = mstd, mdl.new = mnew, / q$ [1 `3 m; @5 X8 v4 f
           cut = c(0.3,0.7),
    0 n5 v/ A! f# w5 ?- Q       niter = 500,
    * e0 r  L$ f& W0 q) T       updown = 'category')
    : C0 U9 Q& t+ u$ k4 h' I7 H5 x0 G' \
      a! S" v; C4 C. ]. e5 ]9 \# 结果变量 + 两个只有预测变量的矩阵4 Z" X- _1 m6 z. P) f
    nribin(event = event, z.std = z.std, z.new = z.new,
    - z" s9 z# m1 x  P3 c$ ^       cut = c(0.3,0.7),
    ( m- n# K, g" Z5 I9 H       niter = 500, 6 B9 N, Y( E! X8 {  P. ]2 A" _
           updown = 'category')
    % h# I7 A2 V# d
      Y5 a6 }. {9 K$ Y) {7 f## 结果变量 + 两个模型得到的预测概率) U% x1 j: r' [( t& ]
    nribin(event = event, p.std = p.std, p.new = p.new,
    & _- W; Q4 I0 O: O9 _       cut = c(0.3,0.7),
    , |. S$ F# _, p2 j       niter = 500, 2 y4 r! F. D7 i2 [
           updown = 'category')7 s: Q. d8 M- {, A$ ^# c$ e
    ' E; @+ A* Y; R9 m  o0 r2 [
    14 D1 l# i8 F- q" j0 b4 a% t( W
    其中,cut是判断风险高低的阈值,我们使用了0.3,0.7,代表0-0.3是低风险,0.3-0.7是中风险,0.7-1是高风险,这个阈值是自己设置的,大家根据经验或者文献设置即可。
    ) [% N% i, R( e
    8 V0 E. n" e7 D0 gniter是使用bootstrap法进行重抽样的次数,默认是1000,大家可以自己设置。
    / \' K4 Q& V( E2 B* X9 v# h  l( p1 m, L. i- n
    updown参数,当设置为category时,表示低、中、高风险这种方式;当设置为diff时,此时cut的取值只能设置1个,比如设置0.2,即表示当新模型预测的风险和旧模型相差20%时,认为是重新分类。6 E  n9 \3 q8 R1 d+ P

    , h5 _0 |2 k9 K$ i" ^: ^上面的代码运行后结果是这样的:
    4 X& B0 N. _: _" l# s- p9 c/ q* L( H+ R4 Q+ P9 V- G
    UP and DOWN calculation:
    " [8 j! t1 n+ W  #of total, case, and control subjects at t0:  232 88 144
    9 e8 x7 ]9 q* y$ W' c6 V' y% X) z% N5 p" K* A( d) }( ]
      Reclassification Table for all subjects:
    : ~3 H+ [# l! g& D  {        New
    7 M' \. T* K" G+ V2 fStandard < 0.3 < 0.7 >= 0.7# F4 }3 R: H: ]9 [3 a3 Q# Q/ l" v2 W
      < 0.3    135     4      0
    $ _- F! O3 _+ O# D  < 0.7      1    31      4
    3 f. r! `; c. p' R- e  >= 0.7     0     2     55
    8 w% m) u5 ?$ r- i) X) H8 d6 P* b' f& U+ p1 a3 D+ a5 O
      Reclassification Table for case:8 I$ l/ \5 T) l4 C" x# G; a6 \: c
            New
    5 a  [9 y& v" J9 K* AStandard < 0.3 < 0.7 >= 0.7
    % f0 O, \  t& g* ~1 ^8 K% E  < 0.3     14     0      0; e8 q& m: a# |8 L9 C: c6 n
      < 0.7      0    18      3
    3 _; _& E, {7 N# m  >= 0.7     0     1     52
    4 Z; D2 j/ k9 o: s0 F% J- E) f, h" Y. ^- W( n
      Reclassification Table for control:* u2 ^' x" {8 v) l6 @0 }0 h- @6 J1 _
            New
    ; H7 p# _- W" P6 Y" HStandard < 0.3 < 0.7 >= 0.7
    # }0 P2 c5 h9 p! ^  < 0.3    121     4      0
    " v8 O' q& b2 Z/ Y& P. Q& m  < 0.7      1    13      1
    3 ?% J* f' h* l$ s, Z) H  >= 0.7     0     1      35 r& o: d0 K& y' D6 o4 y" G4 d
    1 U$ q- k) K3 ^8 T2 \; @
    NRI estimation:4 D" o% T( @4 O5 N7 X
    Point estimates:! E/ y: C+ ?1 k: G4 @) b
                      Estimate8 j  z1 s" Q. f% o; [2 v
    NRI            0.0018939390 d7 T# }! ?5 w9 `" f1 R
    NRI+           0.022727273  L1 |3 P; I( m4 x4 p& l1 O
    NRI-          -0.0208333333 [) a9 H3 Y9 b5 Q/ M* u
    Pr(Up|Case)    0.034090909
    $ Z- P5 w5 y. l% mPr(Down|Case)  0.011363636- i8 W5 v: {! R# ]
    Pr(Down|Ctrl)  0.013888889( z4 M4 }4 x1 o! |7 h8 H! C
    Pr(Up|Ctrl)    0.034722222
    + z7 x0 A( t  n+ _' B1 T, |% \* v5 }* `: W& E7 x8 h2 S" p
    Now in bootstrap..7 G+ ~9 s( E1 D2 [
    # y8 j* L% X0 }6 a
    Point & Interval estimates:+ F, Y  |# [* o+ k4 H4 r
                      Estimate   Std.Error        Lower       Upper5 U+ B  ]: u. A* k" o
    NRI            0.001893939 0.027816095 -0.053995513 0.055354449
    * T- y3 w4 T7 G: h4 e) n* c$ {0 ZNRI+           0.022727273 0.021564394 -0.019801980 0.065789474# r- r2 u9 `( y/ h
    NRI-          -0.020833333 0.017312438 -0.058823529 0.007518797
    7 G4 @8 o+ b3 A) pPr(Up|Case)    0.034090909 0.019007629  0.000000000 0.0721649482 U. b- E2 O9 C4 O9 B
    Pr(Down|Case)  0.011363636 0.010924271  0.000000000 0.039603960
    0 k/ r6 O$ Q  R+ M3 QPr(Down|Ctrl)  0.013888889 0.009334685  0.000000000 0.035211268' D0 R  z* I/ o0 o8 Y8 S+ k9 y8 @
    Pr(Up|Ctrl)    0.034722222 0.014716046  0.006993007 0.066176471
    : X! i7 j: V2 W4 e# W( _
    ; U+ E; j# E, R" K. ]. W1# l+ @; c- s9 b8 n( w( t! n! \
    首先是3个混淆矩阵,第一个是全体的,第2个是case(结局为1)组的,第3个是control(结局为2)组的,有了这3个矩阵,我们可以自己计算净重分类指数。; Q* e) ^- E8 i# \
    4 v. D* m; N, K% p9 I7 y
    看case组:; g8 B1 d7 s' n- H. n
    , G. H4 V4 u! R/ m  X7 M' T3 F
    净重分类指数 = ((0+3)-(0+1)) / 88 ≈ 0.022727273
    5 n. j' t" j" w0 F
    ) |' y3 r$ Y& D" g5 O( x& ^再看control组:
    6 d3 q. F( d* p
    . j, _! T4 G* d" n; g; P; Z; N净重分类指数 = ((1+1)-(4+1)) / 144 ≈ -0.0208333333 o. ~* b3 ~6 l! F* B6 ^0 v2 O3 C

    1 R6 Y  \- g( K/ W1 B$ t6 F" Q相加净重分类指数 = case组净重分类指数 + control组净重分类指数 = 2/88 - 3/144 ≈ 0.0003156577 ?; e/ l9 x! c1 F* ^$ f9 H( y

    / f) |5 U' S# B% j( B1 L6 M; Z再往下是不做bootstrap时得到的估计值,其中NRI就是绝对净重分类指数,NRI+是case组的净重分类指数,NRI-是control组的净重分类指数(和我们计算的一样哦),最后是做了500次bootstrap后得到的估计值,并且有标准误和可信区间。+ [" [3 c9 B2 r# m# b0 [3 f" _4 c  [

    ' n) e) L$ I9 r' K2 ]1 W最后还会得到一张图:
    / c# P1 A% Y) y* n1 _) s( t! r
    1 _3 p2 ^2 w7 F. n; ^: p* _8 a4 B4 _这张图中的虚线对应的坐标,就是我们在cut中设置的阈值,这张图对应的是上面结果中的第一个混淆矩阵,反应的是总体的情况,case是结果为1的组,也就是发生结局的组,control是结果为0的组,也就是未发生结局的组。
    * e  I& F, O; t5 i" m2 i. ?% I9 t4 Z; W. ^2 j/ l. o0 r
    P值没有直接给出,但是可以自己计算。9 B, a8 M; b8 ^

    ; |5 g% o" S" j6 C/ R/ ]7 z# 计算P值5 r0 M7 j( C5 J. l2 M
    z <- abs(0.001893939/0.027816095). m6 H) l; w  E2 ^3 c6 I
    p <- (1 - pnorm(z))*2
    5 i! F/ j1 x2 ]5 t) M7 \p
    4 p8 w( ~$ V. I0 g( W( b1" v4 e% ?# i) K3 r4 c. ^& s
    ## [1] 0.9457157' ?, M5 m3 K8 R
    1
    " M# I8 `0 Y' y5 {# F% UPredictABEL包
    ' R; n* O0 ^' a/ F* k* y7 Q#install.packages("PredictABEL") #安装R包8 S5 k7 t% P  c1 t
    library(PredictABEL)  0 u4 [% u+ M/ @

    : P8 r  Z; f5 x4 K$ K0 z: i7 c: ?: y# 取出模型预测概率,这个包只能用预测概率计算
    / B3 x2 k5 E' O' [p.std = mstd$fitted.values
    ) @4 U1 Z9 Z* x* w: S% Pp.new = mnew$fitted.values # g' A& `. s$ t: l! m0 r+ ?
    10 U9 N9 D( b8 G! R  n
    然后就是计算NRI:
    ; H$ {8 M( C0 x# F- e% q2 a1 z  M- W
    dat$event <- event
    $ Y9 C4 m& P* F$ `& C$ m0 ~* Y. T' m! Q' L" S0 w. g
    reclassification(data = dat,
    , L/ I$ Y# U* F. @- H                 cOutcome = 21, # 结果变量在哪一列/ ?; J% H' r: k+ B6 y0 x4 f1 v
                     predrisk1 = p.std,
    8 Y% ~% e2 k5 H4 W                 predrisk2 = p.new,
    6 ^" t* ]% `) L) w: w  ]  r1 e                 cutoff = c(0,0.3,0.7,1)# ~$ e  t& y# ]# V4 L
                     )
    ( n- F( U, L9 }$ o7 j1: B0 I' D: `. J' r0 X9 A
    ##  _________________________________________
    ( @  H$ G/ G+ J& X6 Q) L' ]##  . E  Z/ g9 U! I4 b* k4 t
    ##      Reclassification table    2 a7 O2 |9 E" T
    ##  _________________________________________8 }  N- N# O) m/ P, i
    ##
    ( E, ^( |% ~: O% E" y##  Outcome: absent ' @8 @9 _5 f* ]
    ##     E$ G0 k2 _* Z0 s* I
    ##              Updated Model2 s$ x# ]& }. I- w
    ## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified  W( n7 O4 S9 g; {
    ##     [0,0.3)       121         4       0               3
    ; B4 G6 F, j7 L9 f( \  N7 x: w: W##     [0.3,0.7)       1        13       1              13
    : M! a+ ?% X" b) h- L2 _##     [0.7,1]         0         1       3              25) t: F' ?$ w5 U" ^
    ## 1 |4 y$ N$ ~& _; g& ^
    ##  
    # Z8 ^4 h# ^( o9 Q% ^4 f##  Outcome: present
    + w0 Y* m& v6 C( s##   : l- m% C& e0 n! L2 |# k" @
    ##              Updated Model/ J: a# F: v. t8 f' `
    ## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified  F( d3 G. }3 G! d( ]; a
    ##     [0,0.3)        14         0       0               0; Y6 b9 Q+ C+ K
    ##     [0.3,0.7)       0        18       3              14/ M' e; n' ~8 S9 C/ z. F4 O3 l
    ##     [0.7,1]         0         1      52               2
    * ~# y4 U% o" Z6 x' ]5 K( U* O##
    * l4 f( m9 t+ e, z! f##  
    : ^& V# s! f% N' z+ a# K# e##  Combined Data
    . Z# }7 `/ n' U##   + y7 h  x% ^' L7 U
    ##              Updated Model& m- p/ K+ n% T6 J% h, E3 s
    ## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
    6 X" R  I) R  D##     [0,0.3)       135         4       0               3
    / m4 M5 {  p4 l/ u) s8 i##     [0.3,0.7)       1        31       4              14
    7 S: m' O( z; |0 K# G##     [0.7,1]         0         2      55               4+ L/ u4 H  k1 k2 v! d2 W4 N
    ##  _________________________________________
    $ x4 r* `$ C# P8 h$ }; O- r% K## + L8 ~5 W! L* c8 G
    ##  NRI(Categorical) [95% CI]: 0.0019 [ -0.0551 - 0.0589 ] ; p-value: 0.94806
    + b) X9 i8 k7 `##  NRI(Continuous) [95% CI]: 0.0391 [ -0.2238 - 0.3021 ] ; p-value: 0.77048
    7 s8 \! n# E3 E5 l##  IDI [95% CI]: 0.0044 [ -0.0037 - 0.0126 ] ; p-value: 0.28396' {* c0 N1 H- T- \

    5 m' q$ g! [3 F' M. n1' e+ F5 h1 O+ G, }* x
    结果得到的是相加净重分类指数,还给出了IDI和P值。两个包算是各有优劣吧,大家可以自由选择。; r4 ~. R8 T, h# O5 L' a# ?

    , s0 T% J# v7 X9 U  y: N8 W生存分析的NRI; W+ F  m5 O* p6 q) i) K# n
    还是使用survival包中的pbc数据集用于演示,这次要构建cox回归模型,因此我们要使用time这一列了。
    7 a1 ]  v5 X4 y, h9 _$ z5 u1 k2 ~! ^+ X' ]
    nricens包& C3 ]3 e# j; Z$ j
    library(nricens)$ ]2 l' h7 U! p
    library(survival)
    3 E" D, r4 d& X& [  b, A3 I' s- n! W# i8 x; A  b: q
    dat <- pbc[1:312,]2 G2 [. b. R& A
    dat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡
    : R: Y! F& W: ^- K$ o8 F' Q* Z1& I" C9 d% a* v6 @
    然后准备所需参数:
    5 @, j+ N) h* ]4 E/ `. n" V' n, L4 w, c( L7 D( S
    # 两个只由预测变量组成的矩阵; k: V" m$ j* t8 }' A
    z.std = as.matrix(subset(dat, select = c(age, bili, albumin)))
    3 b1 I; _, M$ i! Ez.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))7 q  h5 U& c  W

    / @0 |7 k5 R' Q9 l/ U* \1 ]2 l# 建立2个cox模型) |* w0 F) I% r( z" ~
    mstd <- coxph(Surv(time,status) ~ age + bili + albumin, data = dat, x=TRUE)3 O2 `' v  Z) q; E
    mnew <- coxph(Surv(time,status) ~ age + bili + albumin + protime, data = dat, x=TRUE)7 F; u+ E) y2 f

      g1 [! N& ~- _) L" T1 Y* ^# 计算在2000天的模型预测概率,这一步不要也行,看你使用哪些参数
    3 F+ y% C, I- ?! X- e0 @p.std <- get.risk.coxph(mstd, t0=2000)8 W" N% M1 C4 f9 o$ Y
    p.new <- get.risk.coxph(mnew, t0=2000)* z- o4 l$ ?7 G  ]
    1, ~/ j% }4 a( E, _, [
    计算NRI:
    7 I! R, F- u  o( A( Y+ N
    # [: m% i" E7 r' |. f" ~nricens(mdl.std= mstd, mdl.new = mnew, ! z7 T# ~, R7 c/ S/ ?5 S
            t0 = 2000, " B) G& V9 B* i- f' \
            cut = c(0.3, 0.7),
      N1 U& C& W8 f' u        niter = 1000,
    , }$ b1 ~- V) X        updown = 'category')- _. i8 a& v9 s/ n' m/ a
    % {* g* M0 L, g' k9 n: d/ y
    UP and DOWN calculation:
    + n5 S, ]/ K- s+ j+ E5 E6 g" S  #of total, case, and control subjects at t0:  312 88 144. R' {0 ^5 ]7 a% e* g
    # s5 ~5 E4 W4 W! H$ \# u
      Reclassification Table for all subjects:- Z9 ?" \& C: ]8 n: \0 V" R
            New  ^2 Z! t4 i% g6 p6 g- U
    Standard < 0.3 < 0.7 >= 0.7
    5 N) C( S$ T8 D% @  < 0.3    202     7      0
    0 h5 n; Q9 g: D9 K  k9 _  M  < 0.7     13    53      6, N; y: ]$ K9 }$ f
      >= 0.7     0     0     319 W" \8 {) B: F8 D) T, D9 }4 s$ N- k  w
    $ e' J1 w, E/ P; ^( \
      Reclassification Table for case:
    5 G% t/ z5 i1 s* O% Z  D        New
    ; [4 ^+ l5 p2 @  qStandard < 0.3 < 0.7 >= 0.7/ p/ k; e( E0 _: @; j" I. U- s
      < 0.3     19     3      0' M) |6 K! ~  h) i  Y
      < 0.7      3    32      45 M3 X6 g' ^, X
      >= 0.7     0     0     27. Y6 n, n" x* K7 @7 s4 o

    5 A" y2 e( f+ @, e) y$ b  Reclassification Table for control:
    4 \! d5 }2 K1 A, @3 S) \- `9 W0 s        New; I& N1 b3 Z3 f7 t3 u+ T" ^# B7 |
    Standard < 0.3 < 0.7 >= 0.7
    + j4 K  p3 c$ Z, L3 i  < 0.3    126     3      04 `# c. l! y$ ]4 s7 E
      < 0.7      5     7      2
    & z( t( g. F' L  >= 0.7     0     0      1- D* [0 R6 }. w! J; G

    ' x: i0 x6 {# T1 D2 [NRI estimation by KM estimator:
    7 k+ E% Y' C, F: i0 A* B* r3 j. v6 h4 v( I" m6 U5 J, ~+ l
    Point estimates:
    , {. K! q0 }) o& O' s$ F9 ^                Estimate7 w4 F4 r  _' O  Z# [2 `6 I
    NRI           0.05377635
    ! M, W( v' w: @NRI+          0.03748660
    0 @9 F. x0 Q' w- `2 KNRI-          0.01628974
    # S/ h( D7 E! zPr(Up|Case)   0.077089380 L2 o3 Y  `$ g
    Pr(Down|Case) 0.03960278. w+ Y) r7 t/ S7 n* v6 U; u
    Pr(Down|Ctrl) 0.042563526 J, r. B; K# R1 G$ q2 i, m
    Pr(Up|Ctrl)   0.02627378
    6 w6 `: B) A; Z
    $ q! k" s9 r4 i; ~- P& t2 Q) p' J6 `8 U9 bNow in bootstrap..& T& B0 V6 N, I  _7 H# w# w

    1 A  p4 e* K5 X* b6 |Point & Interval estimates:0 Q1 @4 p4 O1 Y8 ~1 }3 J
                    Estimate        Lower      Upper6 b. k, {1 t1 W# s
    NRI           0.05377635 -0.082230381 0.16058172
    0 @- l- n7 o. {) j$ RNRI+          0.03748660 -0.084245197 0.132317761 D4 K! E& ]6 O
    NRI-          0.01628974 -0.030861213 0.06753616
    - E$ r+ y1 y! d- Z: }Pr(Up|Case)   0.07708938  0.000000000 0.19102291
    * g+ L+ O/ R: p( F7 u" j( A  KPr(Down|Case) 0.03960278  0.000000000 0.15236016/ E5 P8 _0 q7 D# j# x1 T6 u  B
    Pr(Down|Ctrl) 0.04256352  0.004671535 0.09863170
    5 I. U& `9 Q6 Y* b! PPr(Up|Ctrl)   0.02627378  0.006400463 0.05998424  {( z# d2 e0 f$ B
    ; e0 h7 t; }" L  p, G) K
    1
    ! J* r& t) B9 B# u4 K' c! ?
    6 t. T+ y7 D4 y5 Q7 h# O! C, K- z7 cSnipaste_2022-05-20_21-49-386 t; O6 v6 m7 _: R! }! s! T
    结果的解读和logistic的一模一样。- s3 t2 H3 A6 l
    : A0 A& E5 A6 J! i8 {; E- L
    survNRI包
    : h/ @$ b+ e  Y9 ~6 Z& ^0 {1 w# 安装R包
    / s  e9 D* a; M# t3 S8 \6 vdevtools::install_github("mdbrown/survNRI")
    5 Y4 O8 P6 @) O9 p1
    9 D5 ?6 L4 K$ F( h0 {; P; _, j6 e加载R包并使用,还是用上面的pbc数据集。
    : h% U2 {+ n& b9 ?* K- A5 C( I! H% l. J- A% @0 U8 \
    library(survNRI)
    - d+ J6 u+ ~9 T% i1( @4 n- X$ q, o4 m% r  _
    ## Loading required package: MASS
    ) H% I' E9 S7 @: x1* D; n- I( ^$ b  h
    library(survival)) |- @' j; ]2 k+ c. l1 j: _

    - N3 y- J& N1 b. c# 使用部分数据
    / x0 L! K* i6 s) `; jdat <- pbc[1:312,]
    # L; K! w% P2 w  Y, r. k6 rdat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡6 @8 M8 y" Z4 G# Q) I0 `0 ?) K* p4 z/ ?

    9 l0 i  d. e0 r9 @( Cres <- survNRI(time  = "time", event = "status",
    6 T6 s( z% O1 j: i5 O5 m6 P! a        model1 = c("age", "bili", "albumin"), # 模型1的自变量
    & a- x$ x7 b; R: g5 L        model2 = c("age", "bili", "albumin", "protime"), # 模型2的自变量
    & ?6 x( v' o2 i* O  W0 k" v        data = dat,
    0 u. {) _2 ]' F' d0 |( s) o        predict.time = 2000, # 预测的时间点
    ( `' t* `: y+ n7 [, }* @- Q        method = "all",
    " ?) g6 Z- B- N' {0 c        bootMethod = "normal",  
    2 C- w: m$ N8 T! h+ J# A5 [        bootstraps = 500,
    : P* x  E/ P/ r" d! q8 Q! ^7 ]' g        alpha = .05)  [% w7 _  P/ ~: S4 H7 w

    1 D: A+ `  O+ @' E( k0 j% R+ g; g) q18 v! A: m* V3 i8 j% Y5 W7 S
    查看结果,$estimates给出了不同组的NRI以及总的NRI,包括了使用不同方法(KM/IPW/SmoothIPW/SEM/Combined)得到的结果;$CI给出了可信区间。! U+ o; J4 t$ p3 t

    . A. K* O8 W) b, ^, V" l: y( bres( O! T% L; r/ K2 K
    13 q( ~# a+ \% i4 |
    ## $estimates, g+ \4 X# A) Z) W* ]: M
    ##            NRI.event NRI.nonevent       NRI
    + U2 C% o0 i6 V4 c5 A  Z## KM        0.20445422    0.3187408 0.5231951
    ' f: ~* P- }; ^0 _" _+ l2 L: t## IPW       0.22424434    0.3273544 0.55159877 t$ F$ d, [1 J/ q* U9 T5 G
    ## SmoothIPW 0.19645006    0.3144263 0.5108763
    " H) n1 I8 A& p/ S) v) |## SEM       0.07478611    0.2632127 0.3379988
    4 J! M1 q( n  j% I( I## Combined  0.19633867    0.3143794 0.5107181$ b) X' i7 @3 V# w! C, y
    ## 4 {' @- @9 c( ^5 s& S7 l( X( u( G5 U
    ## $CI) m: U' ]. ~' E' ?: ?
    ## $CI$NRI.event; a# Z9 R# Z- A7 u6 N' L
    ##                     KM         IPW   SmoothIPW        SEM   Combined
    ' ]% E3 X  |$ C4 W- d, y## lowerbound -0.03915924 -0.02185068 -0.04724202 -0.1162587 -0.04737237 O" g3 O9 t3 @$ _  q8 r
    ## upperbound  0.44806768  0.47033936  0.44014214  0.2658309  0.4400496$ N+ k3 w  Z- s! p* u
    ##
    + z0 g" Q0 z$ p- @! L( _## $CI$NRI.nonevent
    0 s' t) ~( E1 H# [% d+ L$ v##                   KM       IPW SmoothIPW        SEM  Combined  ~. Y( ]# J) l) f3 z7 ]
    ## lowerbound 0.1317108 0.1396315 0.1286685 0.08638933 0.1286426& y, v/ C3 @) i, K/ _
    ## upperbound 0.7102251 0.7393216 0.6966341 0.51482212 0.6964549
    % k6 O, T9 L2 c8 j- ^0 b##
    ) G5 s! c+ Q; j) }  N8 j5 E## $CI$NRI
    3 z* K4 l# p0 }% S( K# g##                     KM         IPW   SmoothIPW         SEM    Combined
    : a/ X/ K  A) m## lowerbound -0.05112533 -0.04569046 -0.05439863 -0.04132364 -0.05443409
    1 h/ d& v3 u5 y0 }5 A- H; f## upperbound  0.89306122  0.92464359  0.87970125  0.64253510  0.87953153
    ! P. p  ~2 n, M5 r##
    - M0 L) \' _% @: ?##
    . [, ], e" M+ _) u1 `" g6 j- p## $bootMethod
    0 r3 N' p6 X' {) u## [1] "normal", f% t6 M1 _! g, q
    ## 8 o; i' m5 v3 Y  D1 ^- m
    ## $predict.time
    ' @0 Q# R- U# s$ m2 V7 @## [1] 2000
    4 V0 q! G, l% r- n& a## 0 l, q; A0 z5 E4 b; I
    ## $alpha6 ~+ `4 Q9 E4 s2 _( U8 s
    ## [1] 0.051 {$ t. Y" P' f
    ## 0 j3 T: \; X& R. P' Q
    ## attr(,"class")
    ! W* M4 ]+ x& I( s! ~  `) B## [1] "survNRI"
    , e7 z) c1 i" J$ s3 j! G4 A
    # t7 N. _+ y. r0 N9 Z0 A1- K7 m+ y! ?- b
    OK,这就是NRI的计算,除此之外,随机森林、决策树、lasso回归、SVM等,这些模型,都是可以计算的NRI的,后面会继续介绍。大家如果有问题欢迎在评论区留言。
    7 \# x. b0 N1 r& ?/ a( i0 q: }: L$ b% S! l
    本文首发于公众号:医学和生信笔记$ W* x: V; M: d

    : U$ _+ f, |3 ]$ }+ C9 O8 _“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。
    / D! L) P9 u7 p4 a& a% f本文由 mdnice 多平台发布
    3 R& U2 m: o. B————————————————
    $ \) P% U) p2 x; I3 [3 H版权声明:本文为CSDN博主「阿越就是我」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    2 P& g% e! i  u9 h2 u原文链接:https://blog.csdn.net/Ayue0616/article/details/126768006
    ' c/ v0 P, I" q: f) H4 X! C" ~/ H$ s( h: |2 O' E& d7 Z- u

    - n' m% J; q% Z2 o) b1 _; O1 P8 s
    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-5-25 13:12 , Processed in 0.334342 second(s), 51 queries .

    回顶部