QQ登录

只需要一步,快速开始

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

    ' z$ V) K6 c& U  y% ]4 p8 Y净重新分类指数NRI的计算
    5 G" g! X5 U, W$ `, B“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。+ e; o+ e+ u5 m( k
    NRI,net reclassification index,净重新分类指数,是用来比较模型准确度的,这个概念有点难理解,但是非常重要,在临床研究中非常常见,是评价模型的一大利器!
    # N  g( T1 G- b+ i* Y9 d8 m9 M' d( s& ]1 t* q7 o# i/ i+ F& G, d4 Z
    在R语言中有很多包可以计算NRI,但是能同时计算logistic回归和cox回归的只有nricens包,PredictABEL可以计算logistic模型的净重分类指数,survNRI可以计算cox模型的净重分类指数。
    1 B) s0 u- j7 L5 r. |8 `* {/ Z/ z) w+ D& S
    logistic的NRI# `4 T. H, S7 F$ [* H/ e
    nricens包
    $ y' \, K: g. W4 M+ e  jPredictABEL包
    ( }8 e" G; r- Z0 B  O- x7 [# A生存分析的NRI
    " k0 E0 w" Q1 G7 f. _4 s8 ]3 @nricens包, V8 z5 ]4 {4 d& N( P, b! B% u1 M9 G- c. ^
    survNRI包0 K: M5 s9 f/ A$ B
    logistic的NRI/ E- t2 J8 B3 J
    nricens包( y. C9 d! j, ^% [" u- ^
    #install.packages("nricens") # 安装R包
    4 E8 V& Q8 N  {: P( M+ e3 C! Qlibrary(nricens)
    5 j& ~! h: V' }% v1 |0 [# G1
    2 D, ?1 w# r8 P3 q  v" m4 A## Loading required package: survival9 z) W7 Z. e* Q! L- o) Q
    16 f5 d1 x: U8 X+ }% l: j
    使用survival包中的pbc数据集用于演示,这是一份关于原发性硬化性胆管炎的数据,其实是一份用于生存分析的数据,是有时间变量的,但是这里我们用于演示logistic回归,只要不使用time这一列就可以了。7 p4 ?( p+ ]' p4 q* m
    / q' o9 E# L+ k2 c- A! Y3 S
    library(survival)0 r1 M2 N) o0 V/ V; e
    9 q9 ]' o9 E  t3 m
    # 只使用部分数据8 G( @: m4 G# s8 F  J
    dat = pbc[1:312,]
    $ W7 [+ y, G9 Ndat = dat[ dat$time > 2000 | (dat$time < 2000 & dat$status == 2), ]+ |& v4 E- r8 w/ v- _4 ?) T* W4 S
    % B- g5 j, q% G- b  d" _! C) P" {4 j
    str(dat) # 数据长这样/ e+ _- F/ T4 R/ t( S3 S
    1( v8 p" M7 a+ ?4 l5 \5 t: i
    ## 'data.frame': 232 obs. of  20 variables:, m8 [  u, o2 P' C! [
    ##  $ id      : int  1 2 3 4 6 8 9 10 11 12 ...' l7 }' I, X- K
    ##  $ time    : int  400 4500 1012 1925 2503 2466 2400 51 3762 304 ...
    7 A( Z0 d8 F0 u1 |##  $ status  : int  2 0 2 2 2 2 2 2 2 2 ...
    ' ?. A2 ^5 [$ Q: X  ^2 O1 o5 e# Q##  $ trt     : int  1 1 1 1 2 2 1 2 2 2 ..., `: _  F) @4 U9 f8 `/ r/ k! j7 `
    ##  $ age     : num  58.8 56.4 70.1 54.7 66.3 ...
    : a8 F& a! O4 i4 g* P$ H9 R$ [##  $ sex     : Factor w/ 2 levels "m","f": 2 2 1 2 2 2 2 2 2 2 ...
    6 S/ S  o1 G1 a* t% g" v##  $ ascites : int  1 0 0 0 0 0 0 1 0 0 ...
    - `4 g, A" x2 ^3 x& e##  $ hepato  : int  1 1 0 1 1 0 0 0 1 0 ...
    : I% L4 O% ~. F( r- G1 G##  $ spiders : int  1 1 0 1 0 0 1 1 1 1 ...
    2 U/ g+ A/ r8 h3 q9 Y  F##  $ edema   : num  1 0 0.5 0.5 0 0 0 1 0 0 ...
    ) z3 C' J3 B6 y! u3 T" n##  $ bili    : num  14.5 1.1 1.4 1.8 0.8 0.3 3.2 12.6 1.4 3.6 ...9 o) O6 ]) U9 @- }1 U0 f
    ##  $ chol    : int  261 302 176 244 248 280 562 200 259 236 ...* x$ _) u3 t3 B- h
    ##  $ albumin : num  2.6 4.14 3.48 2.54 3.98 4 3.08 2.74 4.16 3.52 ...: ~- l4 t! A! G$ ^3 T2 G/ ]  o
    ##  $ copper  : int  156 54 210 64 50 52 79 140 46 94 ...3 ^. J- L: {5 A; I# g
    ##  $ alk.phos: num  1718 7395 516 6122 944 ...1 T1 C& F, _0 I0 W; o
    ##  $ ast     : num  137.9 113.5 96.1 60.6 93 ..., N6 |7 {0 ^7 V1 u8 V0 P
    ##  $ trig    : int  172 88 55 92 63 189 88 143 79 95 ...
    & a$ {# I$ ?( `) v( u6 m% J##  $ platelet: int  190 221 151 183 NA 373 251 302 258 71 ...! W0 f2 t3 I$ X' {2 E9 r6 k
    ##  $ protime : num  12.2 10.6 12 10.3 11 11 11 11.5 12 13.6 ...5 f" L1 X5 V5 j+ h3 L& \
    ##  $ stage   : int  4 3 4 4 3 3 2 4 4 4 ...
    ! `& r; R. `( r& J# L
    2 W3 {- w: n) p0 \- h! H: ~- C1
    1 }8 h: v  D$ N3 q9 y9 Cdim(dat) # 232 20! C5 D# w3 q+ p) R9 w
    1  m* V- U7 \# {9 C  W4 Z
    ## [1] 232  20% x* C. E# r! C+ ^. H# i
    11 C4 \( ]9 R5 ~* u7 U9 j: W" A! K
    然后就是准备计算NRI所需要的各个参数。
    0 H/ q, T7 \; Q9 t# P0 G3 B
    7 U  y) P/ L* [# 定义结局事件,0是存活,1是死亡
    6 j0 L; k, U, B  z" n8 }' ievent = ifelse(dat$time < 2000 & dat$status == 2, 1, 0)
    1 j  o# f) J6 R% l
    % ~: p# V, t- C# 两个只由预测变量组成的矩阵
    , Y& n7 m! J( _1 U# I/ iz.std = as.matrix(subset(dat, select = c(age, bili, albumin)))
    $ A+ o7 ]2 u$ y. b  J, Q; F2 \z.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))
    / @- k2 c4 g9 r6 C, s6 K2 l+ m
    % e6 h5 j/ u9 D# 建立2个模型
    # H+ m( i4 v+ k/ V. G" V; |3 umstd = glm(event ~ age + bili + albumin, family = binomial(), data = dat, x=TRUE)4 h1 n+ y  a, ~7 R% ]5 }
    mnew = glm(event ~ age + bili + albumin + protime, family = binomial(), data = dat, x=TRUE)
    2 [: E$ i7 @. {$ @2 x* I$ B  K
    . ?4 p* Y( I) R* @# M! u) ~8 Y, X. @( T# 取出模型预测概率
    ' `- y6 F! z. M# T% yp.std = mstd$fitted.values
    * P1 b" q! u) A2 hp.new = mnew$fitted.values4 v& X/ a  F+ E+ a$ e/ P
    8 W* y3 N+ V  ~9 M' h/ t0 j) I+ u
    1
    & T: {) D/ C( y5 n# j然后就是计算NRI,对于二分类变量,使用nribin()函数,这个函数提供了3种参数使用组合,任选一种都可以计算出来(结果一样),以下3组参数任选1组即可。 mdl.std, mdl.new 或者 event, z.std, z.new 或者 event, p.std, p.new。
    : m* Y( {3 E  J  d' |1 o7 N% h$ q# n* L$ z( i
    # 这3种方法算出来都是一样的结果1 ~0 j4 Y* ]& O
    * I- r4 i: U  R9 P
    # 两个模型
    : [5 c6 O! x4 ^# H' \0 {( l/ r/ _1 {$ qnribin(mdl.std = mstd, mdl.new = mnew, 8 @. S* V( m# v0 `" y
           cut = c(0.3,0.7), % e- I' X# Z8 X1 o; [) S4 D$ F
           niter = 500,
    $ L( z3 j+ @; A3 V7 J+ g       updown = 'category')
    * U) m$ I* T" G( a. z: ?/ s: L
    0 z( P+ F1 h6 l1 m# 结果变量 + 两个只有预测变量的矩阵$ X: f$ d! W7 U' b, R5 ~
    nribin(event = event, z.std = z.std, z.new = z.new, ; t. K) z3 q# n( K
           cut = c(0.3,0.7),
    $ b5 S5 C+ U, `9 }( i5 t2 I4 g       niter = 500, * j$ g, g0 U/ N) |6 {/ f! s
           updown = 'category')
    1 o9 V  @  t5 J& _# o1 K0 ?  r
    - Y. i( H( O" r8 V## 结果变量 + 两个模型得到的预测概率1 [" `8 @, O" z* L' v. L; A
    nribin(event = event, p.std = p.std, p.new = p.new, ) c' }4 l- h; K- T9 b1 F
           cut = c(0.3,0.7),
    3 z6 g+ d$ c6 h% k' _3 _       niter = 500,
    ( g) t  F2 u+ a       updown = 'category')
    5 E! T- x' m/ w& ^8 t8 x/ ^$ c/ O; ?! d7 L; y+ Z0 p8 ^4 v0 l
    1& W) h: [! F! J8 e
    其中,cut是判断风险高低的阈值,我们使用了0.3,0.7,代表0-0.3是低风险,0.3-0.7是中风险,0.7-1是高风险,这个阈值是自己设置的,大家根据经验或者文献设置即可。
    0 l# }! r; l6 x  z
    / _# I/ L1 C3 x! wniter是使用bootstrap法进行重抽样的次数,默认是1000,大家可以自己设置。
    ) t8 `) E$ r! L0 n" d
    " |3 v, k, k) n" F; @5 Wupdown参数,当设置为category时,表示低、中、高风险这种方式;当设置为diff时,此时cut的取值只能设置1个,比如设置0.2,即表示当新模型预测的风险和旧模型相差20%时,认为是重新分类。
    $ N/ X. s6 Z% L
      r( _0 r# I* }% V& t- S上面的代码运行后结果是这样的:
    ' M8 h. |# @- K/ L; [* f! c( s  U' v8 ~/ l  ]
    UP and DOWN calculation:
    ! B6 B7 O. P$ N$ G2 ^  #of total, case, and control subjects at t0:  232 88 144% O% l5 ^0 ^" i7 G/ D7 o* g6 F, y7 N' r

    ( [. O9 f- t& E1 m, T  Reclassification Table for all subjects:
    3 U2 l. X% E, x% w0 O        New
    * s. Z  ?- b3 y- n4 EStandard < 0.3 < 0.7 >= 0.77 x) u5 c- q% P1 E+ i( u" X. O
      < 0.3    135     4      08 P  G* U) g9 ^3 J1 L3 w
      < 0.7      1    31      4
    2 k7 P, |( K" q& [  >= 0.7     0     2     552 F& G0 u* M8 p. _% I: u1 Y) g

    2 }4 d* K$ I2 ~) i; z+ M  Reclassification Table for case:
    ' w+ X" P1 M( \- e. p$ _1 h- O9 q7 B        New4 m8 ]& O' S' x2 H9 a
    Standard < 0.3 < 0.7 >= 0.7+ t/ u( j1 T' I" i
      < 0.3     14     0      06 M. f2 z8 r! ]2 a; m  @
      < 0.7      0    18      3
    ! h+ F# W2 k' S0 {6 m# K" z; [  >= 0.7     0     1     522 v' O0 O# N% u' q
    ' _4 H3 z% \% m+ u, e
      Reclassification Table for control:
    4 a: N  T3 ~, e3 H2 H- }        New' D# h0 R, y% N
    Standard < 0.3 < 0.7 >= 0.7
    8 A! O  I1 _' q7 X  < 0.3    121     4      00 _* c" t' d+ P
      < 0.7      1    13      18 S: @9 U" Y8 ^0 G2 l3 d
      >= 0.7     0     1      3
    ! v8 ?9 A5 @7 ^+ w$ x1 n
    " z  F, `  B$ ZNRI estimation:5 G& V8 e& ?* {. h8 q% B
    Point estimates:
    + \* ]4 _8 |* j3 T9 T. o                  Estimate' j$ n1 a2 L" B2 B8 v; x6 K# d
    NRI            0.001893939
    , e* x0 G3 [6 q& ANRI+           0.022727273
      Z9 A2 m1 D; \# v) \NRI-          -0.0208333335 Q3 d$ \  n+ \
    Pr(Up|Case)    0.034090909
    $ z& h  p% ]% R7 A( gPr(Down|Case)  0.011363636
    : F6 q$ i! c: _" sPr(Down|Ctrl)  0.013888889
    0 W3 C0 J* j9 _" ?' h' b) A) d& hPr(Up|Ctrl)    0.034722222
    . `$ N4 w' k1 {8 U7 o
    ; B% D* r- K2 F# @3 WNow in bootstrap.., L, ]4 S) `  J( I# g- I" N6 f) b
    ) M3 P  t, M. M3 }
    Point & Interval estimates:( i- ^0 W& ]- O: W
                      Estimate   Std.Error        Lower       Upper* [& U( D' r4 \. E
    NRI            0.001893939 0.027816095 -0.053995513 0.0553544495 w( R7 s9 _* Q$ I
    NRI+           0.022727273 0.021564394 -0.019801980 0.065789474
    4 o5 l) f) v( hNRI-          -0.020833333 0.017312438 -0.058823529 0.007518797
    ' x% j7 D  e% _% F+ y' KPr(Up|Case)    0.034090909 0.019007629  0.000000000 0.072164948
    - W) k& K" F3 j( s  j+ \! ^Pr(Down|Case)  0.011363636 0.010924271  0.000000000 0.039603960
    8 w2 t3 j+ n/ F8 {; VPr(Down|Ctrl)  0.013888889 0.009334685  0.000000000 0.035211268
    * _+ H4 }$ N' @+ V: F+ a* LPr(Up|Ctrl)    0.034722222 0.014716046  0.006993007 0.066176471' ~: Q2 G* Q8 g- t8 J" p$ Q6 z7 ?

    6 S" O) E. w, h, ?* {1 h1
    ! d8 r+ |) s  R; M$ h( _首先是3个混淆矩阵,第一个是全体的,第2个是case(结局为1)组的,第3个是control(结局为2)组的,有了这3个矩阵,我们可以自己计算净重分类指数。
    8 ~% w" p: G# J# i* t$ R3 S) L' ~( ~% d
    看case组:, L4 f: y6 h  b$ C/ O7 i/ K

    6 b- d! P4 |6 I1 d净重分类指数 = ((0+3)-(0+1)) / 88 ≈ 0.022727273
    7 E$ y: |8 ^4 G; f( B7 u- i# W8 m) o
    再看control组:5 c' R: o: O( o
    " ?: T2 \3 c' L5 Y; X. ?
    净重分类指数 = ((1+1)-(4+1)) / 144 ≈ -0.020833333
    , ^( b5 S8 I7 _1 i
    - d7 g" m9 k7 A  H- ]0 L- D3 z相加净重分类指数 = case组净重分类指数 + control组净重分类指数 = 2/88 - 3/144 ≈ 0.000315657; v9 Y7 Z; |+ h  I5 r

    3 e$ g# ?6 ~) U) D+ M再往下是不做bootstrap时得到的估计值,其中NRI就是绝对净重分类指数,NRI+是case组的净重分类指数,NRI-是control组的净重分类指数(和我们计算的一样哦),最后是做了500次bootstrap后得到的估计值,并且有标准误和可信区间。6 s" n- X* J: Y. `9 M5 Y
    9 E2 @) P, O* |; l% y
    最后还会得到一张图:. ^" ^9 \% e- z; t9 X
    6 @1 ~+ E8 C' Z. {( c9 k; q' P% K- K
    这张图中的虚线对应的坐标,就是我们在cut中设置的阈值,这张图对应的是上面结果中的第一个混淆矩阵,反应的是总体的情况,case是结果为1的组,也就是发生结局的组,control是结果为0的组,也就是未发生结局的组。5 t1 M# P5 g! I0 _% U1 T

    & C6 ?/ g# [7 Q* n6 }; e6 qP值没有直接给出,但是可以自己计算。4 k' d1 D1 G; }$ M, ~" f% W! \" L
    9 }( A' c& i0 p( q0 C5 O9 X
    # 计算P值
    7 j* d8 `' K) v, p& ez <- abs(0.001893939/0.027816095)
    . |. E; E- D& e1 o# O$ R! p9 ~p <- (1 - pnorm(z))*25 H( y1 m# l" n& c$ W
    p; ~/ _8 l. k4 f2 F9 V: P/ x2 I
    1
    4 |  d* {4 t& ~$ O) Z8 R6 F! k5 P/ v## [1] 0.9457157
    0 Y; y& J5 ^4 j0 _$ v1
      H% w2 V! J( R4 t3 o6 m5 Y6 d  Q" kPredictABEL包
    ) b1 p% K1 q! i8 V* c#install.packages("PredictABEL") #安装R包; l4 ^7 P5 s/ A: a! G
    library(PredictABEL)  6 n$ P/ P+ N' r1 H% K

    7 o1 @+ s+ I; U# 取出模型预测概率,这个包只能用预测概率计算- j* v( p1 J9 X. e0 w
    p.std = mstd$fitted.values" J! q6 J/ d5 u8 O0 H% G1 _7 i
    p.new = mnew$fitted.values ) D5 w5 ~4 \5 o0 ~7 w1 j* E
    1
    0 |# l7 y1 ~5 C然后就是计算NRI:$ }/ ^) U2 `: C: q0 O5 L8 z+ a' f, A
    0 C  ]# M7 D/ b$ V6 u; E# o
    dat$event <- event2 v0 e$ ~2 r5 J

    3 |: ^! q8 e# S* Y/ N9 K% }5 ~" |4 kreclassification(data = dat,; n1 {. O! E2 V+ L. J! i' f
                     cOutcome = 21, # 结果变量在哪一列
    ) M, W7 a1 L2 x: @" y+ y% _! G2 d: g                 predrisk1 = p.std,6 ]6 `1 ~& e) K8 I$ B
                     predrisk2 = p.new,
    . o8 R: d) T2 K) d                 cutoff = c(0,0.3,0.7,1)
    % l9 X2 G* A7 s5 v3 R2 {; \0 O                 )
    2 B- p3 b- s5 k  p  O1
    - M, k1 ~: Z" k" ^) X8 v/ w##  _________________________________________+ r. k0 x1 |" b+ i: J
    ##  
    6 n& L: O' r% c- B: [* P+ m##      Reclassification table    8 G0 N; b" q  G
    ##  _________________________________________
    7 E4 D) N+ V# F! {8 |, L: R## 4 ?3 b9 i$ O3 ^/ h, {
    ##  Outcome: absent : j2 i0 z  k6 y, }4 Z" `, q
    ##   
    # S% }! G; l$ a& W5 j5 n##              Updated Model
    5 E9 N! X( V  U8 I( n9 g( K## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
    6 X* E+ Q) d; W8 z##     [0,0.3)       121         4       0               3
    5 H! M2 x3 @' h- w2 ~##     [0.3,0.7)       1        13       1              13
    2 r7 K+ g; a$ \) f$ t5 r5 {##     [0.7,1]         0         1       3              25
    2 o7 T3 b: r7 \1 Y/ x##
    / ^' x4 ]1 g: ]) M: i##  2 Y. K% [: r4 `6 F  t8 X+ I
    ##  Outcome: present / ^) u6 t3 b6 `& I" H" y; ~; B
    ##   2 V/ ^2 i+ U# Z8 O
    ##              Updated Model# D1 v( u# w( D4 U
    ## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified9 _( s9 _, m  ]& i3 a
    ##     [0,0.3)        14         0       0               0
    8 I% Q) q9 T! D; ^% x##     [0.3,0.7)       0        18       3              14
    $ {5 o( \1 I5 i6 J* h0 [5 C0 w6 n2 u##     [0.7,1]         0         1      52               2
    / _2 f4 Q* _% B. O## 9 `3 P$ F' d0 O8 T8 {& Q
    ##  
    " K& G3 s& `& A9 P) {##  Combined Data 2 ]2 t/ _: G/ V3 @! p. c! e
    ##   4 L* |* q2 V# t) U3 q/ U
    ##              Updated Model* `! j, c- y, b
    ## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified7 |8 J6 b; ^, V+ ]0 `% Y% }" m/ K7 c
    ##     [0,0.3)       135         4       0               3
    4 M* v( p( g  o7 }( {. @3 u; D##     [0.3,0.7)       1        31       4              14
    ; c' P' s; A% P##     [0.7,1]         0         2      55               4
    ( F+ A$ C0 }9 M##  _________________________________________) j" }# O! A+ p0 I# R) ^2 ]1 m, w( ~- g
    ##
    , o, J( X7 C( r  s##  NRI(Categorical) [95% CI]: 0.0019 [ -0.0551 - 0.0589 ] ; p-value: 0.94806 $ ^0 B7 D- W2 [9 \, S7 D
    ##  NRI(Continuous) [95% CI]: 0.0391 [ -0.2238 - 0.3021 ] ; p-value: 0.77048
    8 z2 ^; ?% A6 V3 z' t5 b0 |. l* M##  IDI [95% CI]: 0.0044 [ -0.0037 - 0.0126 ] ; p-value: 0.28396
    ( V: t* H# Y, u1 ?1 g1 }7 M$ _. H& z9 ^2 H; _
    1* K" h8 [+ k2 A7 n/ L6 S
    结果得到的是相加净重分类指数,还给出了IDI和P值。两个包算是各有优劣吧,大家可以自由选择。  g% N# p: @5 u) m# J
    7 o( z: @0 i1 H0 p5 P5 y+ P7 v
    生存分析的NRI# z9 l; c( N5 d" B5 t, c
    还是使用survival包中的pbc数据集用于演示,这次要构建cox回归模型,因此我们要使用time这一列了。
    1 V6 Z% y6 c  e, P; x4 {4 n( L; C6 H
    nricens包
    9 [' C* \& z# V( Zlibrary(nricens)- q8 J& t7 [7 s2 c& F
    library(survival)
    , B) w2 N: t3 n7 t6 I1 {6 Z. H. f. `* i6 C% f
    dat <- pbc[1:312,]
    # e2 N- N- n! t2 ?+ Ddat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡# {* F9 H' z" a. C# h; C, Q
    1% R, e& Q* V  f' s, O
    然后准备所需参数:" s. I4 m1 p$ F+ z9 l. f2 `

    % y& j5 p4 b" w$ Z8 q* s. ]# 两个只由预测变量组成的矩阵
    . G1 m, {& m5 Z/ F. [z.std = as.matrix(subset(dat, select = c(age, bili, albumin)))
    4 {, x) {! N3 ?; e; u9 q- W4 f3 uz.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))9 B; t5 k! b7 e$ l  @* R
    * Y, h. @$ _' u! ]
    # 建立2个cox模型
    2 c# q2 S7 i0 G7 g: H4 Kmstd <- coxph(Surv(time,status) ~ age + bili + albumin, data = dat, x=TRUE)
    ' B7 n% x7 d& Y# \0 q: rmnew <- coxph(Surv(time,status) ~ age + bili + albumin + protime, data = dat, x=TRUE)
    # r( f+ c$ L- x5 M& O+ `% k/ {% h" U
    # 计算在2000天的模型预测概率,这一步不要也行,看你使用哪些参数
    + z" Y" |1 @; L( I! ep.std <- get.risk.coxph(mstd, t0=2000)
    + \; X! E# {( \8 G6 K3 Ep.new <- get.risk.coxph(mnew, t0=2000)$ T, k* ~7 K/ a& W2 B! U0 J
    1; E1 T& E- f4 k( a
    计算NRI:+ ], _2 z- z8 q! z- q

    0 P1 X! c  U+ z2 y2 e, x+ |nricens(mdl.std= mstd, mdl.new = mnew,
    3 s; b, k0 h) C1 D4 U& R* Y7 i        t0 = 2000, " m! u- V& N3 F, e
            cut = c(0.3, 0.7),4 w( k& B1 ~: X0 |: v' E
            niter = 1000,
    4 _+ n3 t. p% I        updown = 'category')
    / t  N$ e: `. l& A0 u: J% n
    " o/ n4 ^0 W6 }. u3 B. TUP and DOWN calculation:( O& B0 S6 F( w4 N) X" @
      #of total, case, and control subjects at t0:  312 88 144
    9 O* O* x) _' {: N2 E
    " E# [2 l) e: A0 _2 U  u$ H8 J  Reclassification Table for all subjects:! q* v5 S+ \! C
            New0 L  e! t- Q/ n8 ~
    Standard < 0.3 < 0.7 >= 0.7
    - S  _" v0 a0 o) j1 V  < 0.3    202     7      0
    " y* _) k) E/ M! p, Q: M( T  < 0.7     13    53      6; t& e. E4 |  n9 p# V1 s5 t
      >= 0.7     0     0     31
    1 Z  m% A5 `$ m/ \/ ?( [# }3 j/ X  S9 o% v7 r' C" U& ~3 f
      Reclassification Table for case:
    & o7 s% _3 E' ^& H& z# d        New
    # s2 \, ^1 A; }7 _Standard < 0.3 < 0.7 >= 0.7
    , q7 E8 k& {3 G& W7 n  < 0.3     19     3      0; l' `# T) w; p: \# a
      < 0.7      3    32      4
    ) U- T# A3 w- w; r2 C  >= 0.7     0     0     275 F8 R5 a) y8 S% Z. D

    % K) m7 O2 K$ W* {1 @% g  Reclassification Table for control:
    $ O, R9 {; n. H) J  L        New
    6 _6 Y8 R6 W' v" c9 |9 W8 mStandard < 0.3 < 0.7 >= 0.7
    0 @, f5 s: ^. M9 a; I- @  l  < 0.3    126     3      0/ m, i; H; ~! B% e+ t( E0 e$ f
      < 0.7      5     7      2
    ; F  {3 R: O& O. \; s4 M: x  >= 0.7     0     0      1
    * ~, a2 p0 ?: I4 m) G7 ~3 u0 T2 B$ o; M1 U, r0 {$ h
    NRI estimation by KM estimator:
    7 u- B) w+ M6 G/ [: R
    & ]9 X8 ^/ _  f5 oPoint estimates:
    ) R6 K/ T/ O0 ^3 y: t8 \                Estimate
    9 h  c+ N1 q4 I8 b" {NRI           0.05377635
    / b! _5 c9 F" m! JNRI+          0.03748660
    - V2 D8 o0 ]& x% _NRI-          0.01628974$ P! s1 N/ j9 B+ \+ |+ q
    Pr(Up|Case)   0.07708938' \5 b* o& J  V! b
    Pr(Down|Case) 0.03960278$ N( G5 P4 P, q: P
    Pr(Down|Ctrl) 0.04256352! }& t% \% M! E% F  K& L9 D8 |
    Pr(Up|Ctrl)   0.02627378+ c* D( M% f% m1 i" u$ p
      o. J- `% x" H; G! c. I
    Now in bootstrap..
    , F7 X) L. h) g3 ~+ u  z
    # W4 g) [  V7 [  XPoint & Interval estimates:$ C: H( W6 f( U
                    Estimate        Lower      Upper
    " y/ d( @, Z8 a* _1 H1 jNRI           0.05377635 -0.082230381 0.16058172; R" q3 t9 ^7 G$ E/ Z8 k
    NRI+          0.03748660 -0.084245197 0.13231776+ U0 A. R! ]9 J0 T, A6 I' m7 g
    NRI-          0.01628974 -0.030861213 0.067536167 {9 u8 C& \- Z
    Pr(Up|Case)   0.07708938  0.000000000 0.19102291* k& h& N5 A) k1 G9 j( R* m
    Pr(Down|Case) 0.03960278  0.000000000 0.15236016* D. B3 x% }) w9 v" }( N
    Pr(Down|Ctrl) 0.04256352  0.004671535 0.09863170
    & u6 b# X0 y' y2 x% e$ j; b  V$ cPr(Up|Ctrl)   0.02627378  0.006400463 0.05998424! K. Z1 z3 x1 s0 ]

    ! }3 U* r2 g5 `/ i- Q$ U8 v/ w* t; S3 G1
    4 ~( q! X, g2 C1 f% s8 d; D  h/ ]) v, W1 c' B+ B, |+ T1 [
    Snipaste_2022-05-20_21-49-38
    8 l- n4 u! N6 b: I) L' a结果的解读和logistic的一模一样。
    0 m* M! v, F1 @/ g5 P# \: b) b0 i) d( n+ d" G" {- i$ E8 E. v
    survNRI包5 l( H, P% E2 L: h* @
    # 安装R包7 I) n( U# i, v( ]" A, S
    devtools::install_github("mdbrown/survNRI")
    8 }6 \  u, S! N" S- e! |1
    * A/ U) s- x- ]. z; |( c4 p+ ~) I加载R包并使用,还是用上面的pbc数据集。* g( ~( d$ Z+ ~& p; l2 K
    0 m5 ]* c) D: ]7 }& S
    library(survNRI)
    + H8 R5 N  a) |" {4 c9 _1
    8 N$ v; a! b3 @" e. Z/ ^0 T. C## Loading required package: MASS
    ) G0 Y/ W1 i) `: g" N; i+ `1
    6 a. s8 g( j3 o& `) s- b! x3 jlibrary(survival)5 t5 i8 Z% J3 _: t8 f. N1 Q3 r
    3 {+ x+ ?9 T8 }0 a1 U
    # 使用部分数据
    4 d' [, U/ q/ ?5 C2 D; S* X! i+ Vdat <- pbc[1:312,]8 r# n& I5 b) v- b% x6 [5 w
    dat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡
    % H9 i# J8 d# X- z7 b9 z, A4 h8 b) H! q% M; ^0 P
    res <- survNRI(time  = "time", event = "status", 4 |. |( J- r* F& K. J5 n$ K9 U5 x
            model1 = c("age", "bili", "albumin"), # 模型1的自变量8 u2 x, B4 w( O; x" e+ h
            model2 = c("age", "bili", "albumin", "protime"), # 模型2的自变量
    + p* R) M( C  i$ W- p' R2 O! [        data = dat, 2 U7 m: G7 a# e6 x( N' X; R
            predict.time = 2000, # 预测的时间点
    & m; `4 G! i! {( `        method = "all",
    # `3 ^2 M/ @5 J" i        bootMethod = "normal",  
    & d- i1 K% {# ?# W  s        bootstraps = 500,
    6 b, E- ^' u7 k& R1 T3 [        alpha = .05)
    8 k. L  Y. ?+ W$ r6 q2 ?2 G9 w& u( l+ W& K
    1" X/ S' i9 ^8 a0 {* i1 N
    查看结果,$estimates给出了不同组的NRI以及总的NRI,包括了使用不同方法(KM/IPW/SmoothIPW/SEM/Combined)得到的结果;$CI给出了可信区间。! D( y+ S& u+ v. x
    0 K4 X* e  c, F1 ~
    res) }2 F& y! n* j
    17 ?! u% ^9 g$ G* f1 t
    ## $estimates. O( P" O' {2 J8 R  U
    ##            NRI.event NRI.nonevent       NRI
    ! z7 g- m! G: S# n## KM        0.20445422    0.3187408 0.5231951
    & `$ x2 p: O4 U1 r6 w## IPW       0.22424434    0.3273544 0.5515987
    0 ]2 I# {. z/ {7 g" m## SmoothIPW 0.19645006    0.3144263 0.5108763
      N, ~1 V+ H5 ?$ y2 x4 W## SEM       0.07478611    0.2632127 0.3379988' U4 L. z, r, n0 v
    ## Combined  0.19633867    0.3143794 0.51071818 a, k) z! D$ i* T' Y5 U! b
    ## : M9 X3 ]; \% R/ V+ q  b
    ## $CI& i2 i  l- X+ ?$ {4 f' L" R/ G* V
    ## $CI$NRI.event
    / Y& y8 p! c+ X# s' ]##                     KM         IPW   SmoothIPW        SEM   Combined  u1 S4 v$ m- x% E$ x
    ## lowerbound -0.03915924 -0.02185068 -0.04724202 -0.1162587 -0.0473723
    # F. k5 T1 a- ^5 h- t" h3 e## upperbound  0.44806768  0.47033936  0.44014214  0.2658309  0.44004967 ], M. N% p! g& s8 ~: Q# m- g: Z
    ## * ^* k8 r% H0 O1 E
    ## $CI$NRI.nonevent
    ( w( x" j) d5 Q" y' |" u4 _7 G/ h##                   KM       IPW SmoothIPW        SEM  Combined( K; F9 L7 @9 |+ {& ?
    ## lowerbound 0.1317108 0.1396315 0.1286685 0.08638933 0.1286426! Z# ?- V$ B/ _% J! |' t
    ## upperbound 0.7102251 0.7393216 0.6966341 0.51482212 0.6964549
    " J/ v5 L6 m8 D' K2 I, `) p. ?##
    , x3 ?) \+ Z. `, E+ q/ r; o5 e## $CI$NRI! Q: o- q+ e- I. p* `5 U8 P/ r( u
    ##                     KM         IPW   SmoothIPW         SEM    Combined
    ' h3 b9 ]$ e3 j) L1 Q& Q## lowerbound -0.05112533 -0.04569046 -0.05439863 -0.04132364 -0.05443409
    5 y/ V% a7 p! ?# B+ M3 B. Q1 B## upperbound  0.89306122  0.92464359  0.87970125  0.64253510  0.87953153
    5 S$ p4 _& h- r+ C+ `: i## ' H7 N! F+ V' L8 S( A
    ## 2 S9 p# b, N5 @+ G
    ## $bootMethod0 Q( [3 L* e) x) o$ J  B
    ## [1] "normal"- }. h9 k7 n7 U- d* I
    ##
    3 G. [1 ~% g' f4 m+ x4 o2 U+ [  a& _## $predict.time
    8 |* P$ j" E( [: |## [1] 2000  s7 F9 g9 w" w& ^
    ## . H! q7 O8 ]+ o, I
    ## $alpha
    + U' B7 e3 d) J## [1] 0.05
    2 l0 ?# ~1 ]0 f0 I3 C' O2 j* K## / V: ?2 ^8 X" J. @2 S
    ## attr(,"class")+ e0 l/ E" g. J: B& ]6 l8 T
    ## [1] "survNRI"
    . i3 p8 h, h2 e
    # T, ?: M% d9 ]3 e! y3 w1- s3 a/ t) N3 z# ~
    OK,这就是NRI的计算,除此之外,随机森林、决策树、lasso回归、SVM等,这些模型,都是可以计算的NRI的,后面会继续介绍。大家如果有问题欢迎在评论区留言。% Z( u7 o9 [( h* \: Q& g0 l; U2 ^

    + E4 i) J/ Y8 n5 A! G: G; n本文首发于公众号:医学和生信笔记1 Y6 i- q" T. H$ j" L  v/ {

    ' J; y8 A% I6 T2 [- j& H“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。/ F4 h$ I4 {3 t% }  a& Q
    本文由 mdnice 多平台发布
    0 A( O& d9 X* _4 `————————————————; V; E3 Q' ^- c
    版权声明:本文为CSDN博主「阿越就是我」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。* K/ N) y  A9 ~, o5 n
    原文链接:https://blog.csdn.net/Ayue0616/article/details/126768006, r2 `% `; O& K; \% @. }! o& p

    4 V0 ~* ]  g' E4 R  H1 B- X! `( D' z
    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-7-29 15:12 , Processed in 0.421238 second(s), 51 queries .

    回顶部