QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3082|回复: 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
    ' U! P: d9 j3 h/ f0 x
    净重新分类指数NRI的计算
    $ x, R3 L$ S4 O& y! D: ?% e# k( W“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。4 [+ Q# _& k) N. ~9 Y& p
    NRI,net reclassification index,净重新分类指数,是用来比较模型准确度的,这个概念有点难理解,但是非常重要,在临床研究中非常常见,是评价模型的一大利器!% N* t) Z' j' \" d1 F, [; H! ~
    ; i  i, e5 A& F' b
    在R语言中有很多包可以计算NRI,但是能同时计算logistic回归和cox回归的只有nricens包,PredictABEL可以计算logistic模型的净重分类指数,survNRI可以计算cox模型的净重分类指数。  S/ S$ |% m' T5 ~" b2 S3 m
    , }8 l/ V3 |) W; ?; o( z
    logistic的NRI
    - p( O* ~: {8 d) u$ }nricens包4 _5 n/ h9 P$ }. Y# X
    PredictABEL包
    ! V6 m. z3 {/ z. @5 r生存分析的NRI
    ; O# H8 Z3 @  tnricens包  V. r- N2 i: n5 @
    survNRI包
    ' k! x. |, N$ b% Z2 U4 I5 Dlogistic的NRI
    3 ^( ^% y2 Q. n( Znricens包* j; N$ |: f7 S' G
    #install.packages("nricens") # 安装R包
    # H+ q: A5 L+ U0 ?4 x& \7 Mlibrary(nricens)
    6 M6 q' t. e4 A/ y# x1# w% G/ a7 Z4 I& K0 {4 O
    ## Loading required package: survival
    / l, x' w$ T. e$ [4 y' \! B: B0 o1
    + L) }# @) J+ b+ w& s使用survival包中的pbc数据集用于演示,这是一份关于原发性硬化性胆管炎的数据,其实是一份用于生存分析的数据,是有时间变量的,但是这里我们用于演示logistic回归,只要不使用time这一列就可以了。4 @& |( ?; u" B: M# ^
    * D( v6 }5 V4 A1 k2 K- A3 S
    library(survival)& I% w3 U. Y0 ]6 c- Z" t6 \' i
    " E5 P- S$ j% g' t6 U- K
    # 只使用部分数据
    & M) P5 ^1 G: E7 V% S. _3 edat = pbc[1:312,]
    # [* u0 F) w* i3 n' w9 zdat = dat[ dat$time > 2000 | (dat$time < 2000 & dat$status == 2), ]
    9 V$ y# B, Q) P) n2 E7 z8 a* y7 |/ h* ^0 S8 F5 P
    str(dat) # 数据长这样
    1 ?) o7 b2 F) f8 e' D$ ?1
    . ]/ d2 T& ?2 l: q( m## 'data.frame': 232 obs. of  20 variables:; Y8 y0 _0 i' n- [$ m' |" G- Y! i
    ##  $ id      : int  1 2 3 4 6 8 9 10 11 12 ...
    + s& \/ n7 i: y4 T2 ]* j$ {##  $ time    : int  400 4500 1012 1925 2503 2466 2400 51 3762 304 ...; b2 x) [( |6 {, a' c
    ##  $ status  : int  2 0 2 2 2 2 2 2 2 2 ...& G/ D& d0 M2 Z1 Q" W9 i
    ##  $ trt     : int  1 1 1 1 2 2 1 2 2 2 ...
    * n  n9 s, `: i' E8 c##  $ age     : num  58.8 56.4 70.1 54.7 66.3 ...5 }( Y( n/ x' X' ]
    ##  $ sex     : Factor w/ 2 levels "m","f": 2 2 1 2 2 2 2 2 2 2 ...
    ( U6 ^! W" r7 K; ]/ F- ]##  $ ascites : int  1 0 0 0 0 0 0 1 0 0 ...
    ( F- \. |+ ?( H# B; V0 v# P##  $ hepato  : int  1 1 0 1 1 0 0 0 1 0 ...0 ?) w5 Z$ d, |% @$ R9 S7 B0 ]/ t( F
    ##  $ spiders : int  1 1 0 1 0 0 1 1 1 1 ...
    # W- f& T3 y( E! ^& L1 {$ K9 f##  $ edema   : num  1 0 0.5 0.5 0 0 0 1 0 0 ...
    ' c& B, I1 X8 K! A6 J7 e- d: r##  $ bili    : num  14.5 1.1 1.4 1.8 0.8 0.3 3.2 12.6 1.4 3.6 ...4 D! R  Y, g1 \: ]& M5 b% j2 d3 S
    ##  $ chol    : int  261 302 176 244 248 280 562 200 259 236 ...
    7 w  y" i0 S5 o( [5 ?' N##  $ albumin : num  2.6 4.14 3.48 2.54 3.98 4 3.08 2.74 4.16 3.52 ...
    " b4 S/ d9 u0 I  t+ x##  $ copper  : int  156 54 210 64 50 52 79 140 46 94 ...1 W, z  X0 y2 C2 u6 P% u
    ##  $ alk.phos: num  1718 7395 516 6122 944 ...8 K/ M% z/ {% }" S+ `
    ##  $ ast     : num  137.9 113.5 96.1 60.6 93 ...$ r, m( X6 \; A- }
    ##  $ trig    : int  172 88 55 92 63 189 88 143 79 95 ...
    4 I' x# \. S  S5 T) k' Q, w##  $ platelet: int  190 221 151 183 NA 373 251 302 258 71 ...' X8 F  R" A" a
    ##  $ protime : num  12.2 10.6 12 10.3 11 11 11 11.5 12 13.6 ...
    7 E: y% }; d* ^# z3 S##  $ stage   : int  4 3 4 4 3 3 2 4 4 4 .../ ^# n* }' e0 O; k; D7 K% B3 T/ f
    , g' s  \% q3 K' z8 X" Q
    14 o6 J, `. P8 p" `) `! {8 w
    dim(dat) # 232 20) m9 I) _. l' V& @
    18 }5 x$ Y9 w. V
    ## [1] 232  200 w1 s; L2 j  K( t3 }
    1
    + A. R$ R, |2 {$ j$ R5 `1 f然后就是准备计算NRI所需要的各个参数。
    ( a0 A2 C$ r% o6 x) T( l
    - j1 x6 T! a; G8 [# 定义结局事件,0是存活,1是死亡
    9 Q. V2 _9 \( z" mevent = ifelse(dat$time < 2000 & dat$status == 2, 1, 0)# e6 E/ \: k! n$ ^" z5 A. k8 Q

    4 i, _% @0 ~) ^7 A/ y# 两个只由预测变量组成的矩阵
    : j1 a# G# B, V. s% u5 g' Pz.std = as.matrix(subset(dat, select = c(age, bili, albumin))): o" J! H0 J$ g- R( w5 d  p
    z.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))+ I* ^( `/ Y+ y* V

    + c8 F& q0 J  y# 建立2个模型7 x: K1 U6 J2 a+ L( ^& d( S
    mstd = glm(event ~ age + bili + albumin, family = binomial(), data = dat, x=TRUE)3 ?0 U, u6 Z! m  c+ b/ o5 e  o
    mnew = glm(event ~ age + bili + albumin + protime, family = binomial(), data = dat, x=TRUE). H, z7 O: Q: f

    6 K( O, {' T! {- \7 W# 取出模型预测概率
    : a9 X6 N% ^; _8 |0 Z+ z) B# sp.std = mstd$fitted.values# k: X' t2 z7 A6 _
    p.new = mnew$fitted.values4 T$ P/ o" u" c" A8 _: X/ W# A

    ; _0 L* ^$ c+ U1
    % Q8 o& h+ w% O然后就是计算NRI,对于二分类变量,使用nribin()函数,这个函数提供了3种参数使用组合,任选一种都可以计算出来(结果一样),以下3组参数任选1组即可。 mdl.std, mdl.new 或者 event, z.std, z.new 或者 event, p.std, p.new。
    % R) ^# e, W$ m; @% I; q. q0 a+ x3 S( U; n+ r9 V* ]
    # 这3种方法算出来都是一样的结果
    3 ]/ F, r8 b, H4 `$ `
    2 t8 F! q/ z# N4 v" e; E# 两个模型
    ( h' U3 u5 |* Snribin(mdl.std = mstd, mdl.new = mnew, 6 W8 @( q: b, a) I0 U1 ^; |  h
           cut = c(0.3,0.7),
    8 p0 t+ G% t7 \% _* ~       niter = 500,
    9 S8 E) m5 v" e1 K: F  ?% `1 P       updown = 'category')
    % C- u) r4 v; s! T; x0 V" `7 U$ X9 \5 A
    # 结果变量 + 两个只有预测变量的矩阵
    / V# o2 E& E# ^7 Jnribin(event = event, z.std = z.std, z.new = z.new,
    . F& ^+ M6 Z: c  G# x       cut = c(0.3,0.7),
    1 Q1 {3 D9 a, i  y) C& s0 m       niter = 500,
    # T/ @& r% A; C       updown = 'category')
    / {4 [; O: i  m! v6 _( m! y3 }. b7 {3 y! k! K' a* P  T
    ## 结果变量 + 两个模型得到的预测概率' i5 R% W: y! H# b- P  T
    nribin(event = event, p.std = p.std, p.new = p.new, 4 F4 T3 g# v) T
           cut = c(0.3,0.7),
    0 c$ g2 s! R$ ]5 {+ \       niter = 500,
    & P. e+ q# n2 `7 b4 f       updown = 'category')
    , K: }' l1 u/ D* m
    / ^! E- U, q5 {+ `1
    " c9 i* V: A# ]. b) N9 n其中,cut是判断风险高低的阈值,我们使用了0.3,0.7,代表0-0.3是低风险,0.3-0.7是中风险,0.7-1是高风险,这个阈值是自己设置的,大家根据经验或者文献设置即可。
    ! S, L3 X4 b( ?1 G# V$ P% ]
    ; d! N1 @2 v$ ~& Z: xniter是使用bootstrap法进行重抽样的次数,默认是1000,大家可以自己设置。
    6 ~: i+ }+ D0 [1 m0 @' {, r
    & }: i+ W# ?& l2 K4 Q( x, t. Uupdown参数,当设置为category时,表示低、中、高风险这种方式;当设置为diff时,此时cut的取值只能设置1个,比如设置0.2,即表示当新模型预测的风险和旧模型相差20%时,认为是重新分类。
    ' T1 d+ V4 s3 L0 u% M- h# m+ e' Y) I; J# I* _
    上面的代码运行后结果是这样的:
    $ y4 a9 O+ W8 P2 {/ c3 P
      {& @7 n. [4 }UP and DOWN calculation:
    1 n9 T, a. y0 J6 b- r  #of total, case, and control subjects at t0:  232 88 144
    5 I6 G4 n8 d8 o% n1 g  q  p* a' ^- v" E7 b. v9 V9 U
      Reclassification Table for all subjects:' D2 o9 m/ S- N
            New
    / G8 y6 N& @0 W" nStandard < 0.3 < 0.7 >= 0.71 e" d$ f/ j) v5 A9 ?! t8 ~
      < 0.3    135     4      01 N) Y# Y% _" G8 R" E$ r: m" m
      < 0.7      1    31      4
    / J0 q& o; g! ~- T- `  >= 0.7     0     2     55
    5 \& F7 D$ P5 z8 I1 T  V) L) C0 b7 z  D3 q) Q0 E  @7 D5 k
      Reclassification Table for case:
    ) V2 G1 [1 Q+ n9 V6 `4 Y        New1 k& d# t6 e  m( k1 ]. `, q! I
    Standard < 0.3 < 0.7 >= 0.7
    4 A1 O4 Y9 m. r) q& [$ F5 j9 X  < 0.3     14     0      0! @) A. C; M" j1 ~3 g% ~# r
      < 0.7      0    18      3
    # A3 |1 v8 Z" g) ^& G7 l" B( E& ]  j  >= 0.7     0     1     52! D: O7 k% i& r6 v: b: t

    % j0 N- s# D7 l; j0 I& }  Reclassification Table for control:  j# D$ `9 {+ e' h3 \4 p
            New. R: Z8 W+ C6 W( {/ h( V( E  t
    Standard < 0.3 < 0.7 >= 0.7; D; I' K: `( Z$ Q
      < 0.3    121     4      0
    + a1 Q: A3 r# a1 m* d& C  < 0.7      1    13      11 P6 ~* j6 h) A) H# z' V
      >= 0.7     0     1      3
    + t2 K  t, m% S. D3 j& e- j4 c+ ?% S
    6 N# ~* M2 G- T7 K- S  QNRI estimation:
    0 o0 G( v/ q% x" U2 PPoint estimates:, E) e) h+ C7 h0 U
                      Estimate
    % s" ^/ E: B7 `* b0 C, nNRI            0.001893939
    * X. t  L3 B7 _. r5 uNRI+           0.0227272737 n6 q8 E' g) |  f1 Y0 P
    NRI-          -0.020833333' e+ K' D3 |" ?3 g) l5 o3 P# {9 |
    Pr(Up|Case)    0.034090909
    , W% p1 B- ?3 U6 b% h1 X. _# QPr(Down|Case)  0.011363636) b3 }6 y0 n$ \4 V
    Pr(Down|Ctrl)  0.0138888897 y0 h6 [! o+ m7 q
    Pr(Up|Ctrl)    0.034722222
    , m# x* O7 x' b% a. i# L& k1 u+ f
    , }# V- Q  w9 E  PNow in bootstrap..
    ! t' D% b4 k' p  c# p
      Q; r: g. `$ ~& t) }" s- w# DPoint & Interval estimates:
    5 l% q5 Z$ ]* ^$ v                  Estimate   Std.Error        Lower       Upper! t+ f0 e& P6 ^$ u1 m
    NRI            0.001893939 0.027816095 -0.053995513 0.055354449) b' L0 Y6 S. S, n$ I* R
    NRI+           0.022727273 0.021564394 -0.019801980 0.065789474! ^4 S+ V: k1 e) b- O: w1 Y
    NRI-          -0.020833333 0.017312438 -0.058823529 0.007518797
    8 E) n( Q: j- @% ePr(Up|Case)    0.034090909 0.019007629  0.000000000 0.072164948
    7 U4 i. J2 L9 APr(Down|Case)  0.011363636 0.010924271  0.000000000 0.039603960
    ( H; m$ n& y$ h$ l6 G& pPr(Down|Ctrl)  0.013888889 0.009334685  0.000000000 0.035211268/ ?! v) S/ B' o9 |+ s
    Pr(Up|Ctrl)    0.034722222 0.014716046  0.006993007 0.066176471
    , C$ P6 A4 ]: v8 N! Q. [% J3 J/ ]! ?$ b: O" M; q- N+ M7 o
    1/ X+ k5 l) g' B1 R
    首先是3个混淆矩阵,第一个是全体的,第2个是case(结局为1)组的,第3个是control(结局为2)组的,有了这3个矩阵,我们可以自己计算净重分类指数。; c$ s( K7 m- v! ^9 ?: ]  z

    / l. J& C5 X! `* B: s7 `看case组:) }5 O! x  L! E3 g

    , G( c, z# U2 q$ g2 x净重分类指数 = ((0+3)-(0+1)) / 88 ≈ 0.022727273( V, ^; c! A. [1 \
    ; M5 l, I* i# K
    再看control组:  K3 t( O" R. S2 a: E2 `
    # g- w9 L: f9 b: |) }
    净重分类指数 = ((1+1)-(4+1)) / 144 ≈ -0.020833333
    6 F# f  v( g* s+ R) X. g- R6 B# q0 W" [
    相加净重分类指数 = case组净重分类指数 + control组净重分类指数 = 2/88 - 3/144 ≈ 0.000315657
    8 F" ?& t. x/ r& t: L$ j( X/ f3 q$ D0 \+ M" Y4 r
    再往下是不做bootstrap时得到的估计值,其中NRI就是绝对净重分类指数,NRI+是case组的净重分类指数,NRI-是control组的净重分类指数(和我们计算的一样哦),最后是做了500次bootstrap后得到的估计值,并且有标准误和可信区间。
    ' E% S- g6 q2 w5 R9 X0 |) m+ G1 p9 j+ t) b7 c
    最后还会得到一张图:
    , C3 w% y& h% H2 x! z6 x9 _: O6 L. i/ w9 u+ A, ~7 \
    这张图中的虚线对应的坐标,就是我们在cut中设置的阈值,这张图对应的是上面结果中的第一个混淆矩阵,反应的是总体的情况,case是结果为1的组,也就是发生结局的组,control是结果为0的组,也就是未发生结局的组。. W9 `0 \& ^9 y: L

    + f7 W/ E- G- qP值没有直接给出,但是可以自己计算。/ X5 Y! T, c) k! X5 E  o

    $ w1 @% t) q, a3 b# 计算P值
    * j/ @1 U6 w$ Q* Y4 {& Cz <- abs(0.001893939/0.027816095)7 n- p; ^2 J4 d- c% b7 Q: x7 E
    p <- (1 - pnorm(z))*2- g6 k( S6 c$ t' q
    p( k& m3 z! R8 _4 W( `6 [/ v8 e
    13 j0 y1 G* c/ Z( v( t/ x
    ## [1] 0.9457157: \  `  J1 Z3 m6 d' U2 D% D: S* j
    1* X% |' W) i: h3 C6 ]
    PredictABEL包. C- r3 J$ K5 V/ O0 `7 p* d# K
    #install.packages("PredictABEL") #安装R包; K) j. W( o2 Q+ i9 P$ e9 c
    library(PredictABEL)  + e8 Z8 F  I1 j8 ]8 q4 I

    8 J# n: G7 T' h$ c* P5 A! _# 取出模型预测概率,这个包只能用预测概率计算
      I7 m# {) ]3 P& h' Sp.std = mstd$fitted.values
    . i7 y$ U6 j4 b, v9 Gp.new = mnew$fitted.values ! p! J7 |1 m; A! v* n# {: s% h0 f
    1
    9 O* y$ y7 ^* ]  |& O然后就是计算NRI:- [$ s6 N2 [6 K' V1 p& E$ M' A  R* @- i& D

    ' \6 I2 v  V* ?- V  T2 n/ w4 a: bdat$event <- event
    ! ]& D% [) y* C% O
    * L3 M. F8 d8 @5 d/ X- D8 M0 r3 Qreclassification(data = dat,$ X' Z. ^* j6 R* n, X
                     cOutcome = 21, # 结果变量在哪一列
    5 _1 }, Q' G) Q6 X2 ?0 @4 q                 predrisk1 = p.std,! l! R( K+ G& i) Q* M
                     predrisk2 = p.new,
    7 m' |; H1 K' Q8 d                 cutoff = c(0,0.3,0.7,1)/ Y- s, y( M5 s+ ]
                     )
    8 r9 ?; p6 n: T8 ~: q& y( H2 L1* Q& B8 T- G" K
    ##  _________________________________________3 M8 ?/ O4 b. M" @
    ##  
    0 T" K% r6 S: s/ i2 Y) X! g##      Reclassification table   
    $ {5 s5 J7 F0 V. S8 Y+ w: K' t1 j##  _________________________________________2 [6 l8 z# h9 x4 h. L+ Z
    ##
    ; w( c$ W1 D5 }! B##  Outcome: absent : w: y5 C* w9 R' q  L2 q
    ##   
    % b0 b3 N. j$ g9 A. [+ h; o4 u##              Updated Model( I+ r+ s: x% t4 p
    ## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
    % v( B% x( M9 L0 O( Z, T##     [0,0.3)       121         4       0               3
    7 p* s6 q' D" a3 T##     [0.3,0.7)       1        13       1              137 I: X& o+ t8 }7 Z" e+ c
    ##     [0.7,1]         0         1       3              25
    ; S8 T5 Z" c# s+ q9 o9 {: \##
    " a" J* H9 \5 K* u2 _; q##  
    ! F) l; t/ G+ m7 e* A##  Outcome: present 4 x/ K" w( s/ K% R0 J1 d  x$ Z9 ~
    ##   ' z- U& [5 H2 ?& H
    ##              Updated Model, g# M+ m5 p  @. h# X# s% z) Z* z
    ## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
    ) _7 b( [: r9 D7 l4 a/ O8 A##     [0,0.3)        14         0       0               02 V" Z1 }+ ^2 v$ i
    ##     [0.3,0.7)       0        18       3              148 B+ n  O- M! d, I4 v0 W2 v
    ##     [0.7,1]         0         1      52               2) j, D) U. N8 K. c3 u
    ## ) l0 P+ ]/ O' z8 j7 g; K, X, P
    ##  ) N; R6 ^; N5 C7 k: S, k
    ##  Combined Data
    ' I! R5 e$ A3 @2 E9 ~/ z& e6 O+ q7 I##   , W% x3 m9 v; ^, I) O
    ##              Updated Model
    . h* h, E% f' l( C* `## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified  R' @/ a% [3 p  _. z
    ##     [0,0.3)       135         4       0               3( R7 @. c0 V* x. E# w
    ##     [0.3,0.7)       1        31       4              14  I+ `6 H$ |' H! }# c  O
    ##     [0.7,1]         0         2      55               4) O+ @! k1 P9 @9 L
    ##  _________________________________________
    / r% M; W+ K9 l+ x% L##
    . k1 Q' k' [- _6 b/ I& S& v##  NRI(Categorical) [95% CI]: 0.0019 [ -0.0551 - 0.0589 ] ; p-value: 0.94806 ) _( h0 D3 Q6 [5 T$ I# H6 Z
    ##  NRI(Continuous) [95% CI]: 0.0391 [ -0.2238 - 0.3021 ] ; p-value: 0.77048 1 E' u% B; `8 u* f. y# X& k
    ##  IDI [95% CI]: 0.0044 [ -0.0037 - 0.0126 ] ; p-value: 0.28396* i# `7 b/ T+ A7 v

    4 a# K9 p9 ^8 J( N: s. v18 v8 r( X" b4 b% u
    结果得到的是相加净重分类指数,还给出了IDI和P值。两个包算是各有优劣吧,大家可以自由选择。
    , `4 B% {5 w8 O( i5 ^0 D% `7 J
      h: ~1 Y  R' X- P: O; T( W生存分析的NRI
    5 V! s$ f$ L9 w3 |0 X% o' Y还是使用survival包中的pbc数据集用于演示,这次要构建cox回归模型,因此我们要使用time这一列了。
    . b2 J3 |3 m# n. X
    " K0 n! a( S) unricens包- a  m6 k5 U) h; }; o7 i
    library(nricens); K8 m, P' w7 A+ L$ c, b2 b) r
    library(survival)" }$ h# R6 U1 i) O! N

    / ]% c2 h* D7 b5 z9 k- odat <- pbc[1:312,]' S3 I9 z$ T$ R1 I7 q, b
    dat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡2 M/ |% t! m' p' E6 W
    1
    + N3 g. k2 N3 b& w然后准备所需参数:
    + P$ A* z5 P" L# Z  W* D
    2 Y- w- E; T" D# 两个只由预测变量组成的矩阵
    ) V: E+ S& f$ U1 w* V) k% u4 Hz.std = as.matrix(subset(dat, select = c(age, bili, albumin)))3 c4 b, V3 w3 `5 S: O) ?  X
    z.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))' K- q" E' T- j4 z
    5 ]) {& b# k* p; [2 u6 u% P" m1 b
    # 建立2个cox模型
    6 [6 G; I9 u2 }" Y2 z, |7 Hmstd <- coxph(Surv(time,status) ~ age + bili + albumin, data = dat, x=TRUE)" C2 O* |" O/ i5 o) V7 v) X
    mnew <- coxph(Surv(time,status) ~ age + bili + albumin + protime, data = dat, x=TRUE)
    ) M( P" o$ [1 \$ o1 M* w  b  T1 n5 {5 s! G: ^2 k
    # 计算在2000天的模型预测概率,这一步不要也行,看你使用哪些参数
    3 J4 r5 W0 n6 X) I# d5 O6 v& |p.std <- get.risk.coxph(mstd, t0=2000)
    # X( ?4 ?! \1 [* ^# ]+ \p.new <- get.risk.coxph(mnew, t0=2000)
    / Q1 g0 S: A* G1
    & W+ Z- K, x5 s" L; i' ?* u) P计算NRI:
    & H6 q: u  @6 O% ]% G) R/ H( _: w+ `5 D
    nricens(mdl.std= mstd, mdl.new = mnew, ( N; P  y# U; X: G
            t0 = 2000, & z" W' I6 l2 D  _' J; g) H
            cut = c(0.3, 0.7),
    ( i. B7 l" s, A' E& X        niter = 1000, % m% x0 z& Y* i
            updown = 'category')* s  y8 ~) C6 L- _* m" {9 o
    8 z+ x  B7 |$ l4 S" w0 N
    UP and DOWN calculation:7 f* A7 |9 A" S. M. _
      #of total, case, and control subjects at t0:  312 88 144
    " \) g- B- ~& O& P+ S8 J1 V8 n9 e
    ! W# m6 E% {, ?/ {- l- s  Reclassification Table for all subjects:
    / z* [; i7 {  q' H        New
    ; d2 G) p6 [. B" t' K7 E! GStandard < 0.3 < 0.7 >= 0.7
    : m; o- v  ?0 O0 X$ [$ B" c" T  < 0.3    202     7      0
    9 ]4 b0 q0 B+ p& J  < 0.7     13    53      6
    . e3 e$ b1 l2 ?7 o8 C( p2 W& z  >= 0.7     0     0     315 ~* \) o/ S3 y8 ^! r* m

    2 G3 G9 @; w, w/ V& L4 l  Reclassification Table for case:6 j3 G6 s5 @$ H5 n/ F1 O
            New& G) L! Z$ i8 y$ D
    Standard < 0.3 < 0.7 >= 0.7; Q: f" f% L8 ]% q+ ]  ~5 F7 A
      < 0.3     19     3      0
      K7 E$ c$ R+ E* a6 A. }1 M4 G# v  < 0.7      3    32      4
    / y( G* m& B  c2 Z8 ]$ p8 j5 y  >= 0.7     0     0     27
    ; m+ P; e/ C/ H2 x3 c  {/ z7 ^# ]2 J- ]& p2 A
      Reclassification Table for control:8 G! r. M* f4 A9 d7 `8 K# L% P
            New
    $ }, L, m' X9 p: W) J' i0 G% q5 ?Standard < 0.3 < 0.7 >= 0.7
    " F, x. N) y9 x4 t, X  < 0.3    126     3      0
    ' V4 }, l0 F2 ?/ s8 x  < 0.7      5     7      2
    8 D$ d4 ]# R9 {6 Q7 \& k: Z1 S) g  >= 0.7     0     0      1
    9 h0 o' S4 M3 N0 x0 ?- K! ~* k2 y: {$ q1 z7 J% W' `5 s
    NRI estimation by KM estimator:
    9 @0 j- k( O% R1 O: s' W3 i: s0 A; T/ ^9 K; G
    Point estimates:
    2 ]' V+ i0 ]& j+ K- V! i                Estimate
    & U' E6 n# _- G- pNRI           0.05377635
    % z  M4 d2 `/ B( p7 Q" X' ANRI+          0.03748660. o6 B( W" x4 Q8 W( G' R- A' y
    NRI-          0.016289745 {! f0 ^( s, J, p3 _: ~
    Pr(Up|Case)   0.07708938
    . f. ^8 G" L- l' u' t% D9 e2 |6 kPr(Down|Case) 0.03960278
    ( Q5 d/ l2 T* J$ dPr(Down|Ctrl) 0.04256352
    ' z) U9 H, C& u  HPr(Up|Ctrl)   0.02627378$ G5 [5 R( |/ ^- g) J1 e

    + y( N3 X* D$ J; R, C+ A# [Now in bootstrap..
    / S4 S; v7 |0 \& @4 \7 @! c( m2 o& k/ h+ C& ~) }
    Point & Interval estimates:( K8 X* @9 f% Z/ X
                    Estimate        Lower      Upper
    / X) X4 L0 w& Y/ P; c( yNRI           0.05377635 -0.082230381 0.16058172
    : u- F% {' I/ G* WNRI+          0.03748660 -0.084245197 0.13231776
    " V/ w# i# P" u3 {' ^! ONRI-          0.01628974 -0.030861213 0.06753616& B* r1 V* b0 g* \3 r
    Pr(Up|Case)   0.07708938  0.000000000 0.19102291
    % ^; t0 q6 r- u; P! l5 G6 yPr(Down|Case) 0.03960278  0.000000000 0.152360162 s9 e5 W1 B  y6 N- ?
    Pr(Down|Ctrl) 0.04256352  0.004671535 0.09863170
    5 R3 L* W* ^+ BPr(Up|Ctrl)   0.02627378  0.006400463 0.05998424
    . {. S3 c* b' C/ T7 S  N' n& w; n8 l, y  U2 v+ q5 w
    1
    2 C9 c( R0 Q. E$ W. ?1 @7 g# C# e
    * j8 \/ ?" K, ^9 ZSnipaste_2022-05-20_21-49-38# q* M4 A- t1 t% J5 E: ^
    结果的解读和logistic的一模一样。9 \# t# c! S8 }9 b

    1 _$ ]3 D0 P9 S+ {' qsurvNRI包3 ^  B$ Z2 h1 Y3 r# `
    # 安装R包
    + T8 m  _8 M) B/ T. t( A" J5 ndevtools::install_github("mdbrown/survNRI")
    # U! M) f, q+ |  L" U1
    $ l5 |7 q' A' \! ]6 R9 }1 r% O  M加载R包并使用,还是用上面的pbc数据集。
    1 \+ e/ }7 c! E% g5 w2 K6 S  S
    6 j# {* ?% x- l: zlibrary(survNRI)$ F* C/ ?! q$ F* H# o
    15 M; L2 P9 V6 F1 U& p1 d, F
    ## Loading required package: MASS
    ( |* D1 `+ G1 @2 |9 f( M1! q0 T6 k" M5 P/ h5 W; O% _1 g6 g" f
    library(survival)
    ) D; H- u. R9 S& {2 }
    ' K! @5 d* z/ I" u# 使用部分数据
    0 v3 i7 D& _4 A, k( B, A, k* ndat <- pbc[1:312,]
    4 ^4 w9 K8 S* C8 \' u( xdat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡
    * f( v& ~5 i& W+ L+ n$ |* c) N8 w3 V! i# R
    res <- survNRI(time  = "time", event = "status",
    9 y3 `' x2 N7 G4 H6 ?        model1 = c("age", "bili", "albumin"), # 模型1的自变量) Q' F! O& r/ y; m# B* ]
            model2 = c("age", "bili", "albumin", "protime"), # 模型2的自变量* e0 ~, ~; Z7 q, m" @7 S" {
            data = dat, . m" [4 D* w; y) ^/ A1 I
            predict.time = 2000, # 预测的时间点
    5 a; t- p1 [% }) [; m1 t& P8 F5 q! |        method = "all",
    . z2 o6 K! g0 h, \9 |7 e6 }+ K        bootMethod = "normal",  7 y0 Y+ V0 _8 ?
            bootstraps = 500, 9 N/ `& N6 S( d$ l+ P$ D- Q
            alpha = .05)6 {! a& ?5 H* {' h  p% G& t. ?
    * e$ p  m( J( M: d9 u
    17 Z& l$ J7 r/ u# u2 T9 d6 B& V$ T
    查看结果,$estimates给出了不同组的NRI以及总的NRI,包括了使用不同方法(KM/IPW/SmoothIPW/SEM/Combined)得到的结果;$CI给出了可信区间。
    # z. M4 h$ W& P) x  n5 I& X% U8 P1 t% y1 V2 a& Y* e4 k4 B1 O
    res
    % y( c2 m8 S, Z9 [5 [; Q1  A; v1 u% ]( u2 ]; }: P& e
    ## $estimates
    5 @( d( d& x0 J' V0 D) l% Z# c##            NRI.event NRI.nonevent       NRI/ M6 ?7 w( Y! v( [2 ?, t0 \
    ## KM        0.20445422    0.3187408 0.5231951# y4 K, J( c* j9 n
    ## IPW       0.22424434    0.3273544 0.5515987
    : }. ~/ r  c1 t% ?, A: E. m## SmoothIPW 0.19645006    0.3144263 0.5108763
    ' j% ]  G! x1 x8 }6 P1 r## SEM       0.07478611    0.2632127 0.3379988  k( Q9 t* H( ^4 Q  C2 U4 ~
    ## Combined  0.19633867    0.3143794 0.5107181$ E7 W0 O8 q+ o9 Y4 }7 f
    ##
    & {1 c* n3 Q! y6 B7 ?6 V## $CI5 P* ]/ z8 }8 N5 J
    ## $CI$NRI.event
    , Q: k0 k6 R" j; i, X##                     KM         IPW   SmoothIPW        SEM   Combined1 P5 f0 o4 k. |* P
    ## lowerbound -0.03915924 -0.02185068 -0.04724202 -0.1162587 -0.0473723$ X" ~" L/ Q$ D) _
    ## upperbound  0.44806768  0.47033936  0.44014214  0.2658309  0.4400496
    ' u5 z7 b% a  D0 a* ]& }##
    9 r$ U" u* Q$ P; |9 X! }4 ~## $CI$NRI.nonevent
      x. {% Z- Q! N5 A##                   KM       IPW SmoothIPW        SEM  Combined
    # V( y8 h* j# A& V## lowerbound 0.1317108 0.1396315 0.1286685 0.08638933 0.1286426, b2 L2 n) }  P  U: M
    ## upperbound 0.7102251 0.7393216 0.6966341 0.51482212 0.69645497 k; M4 q  M% E# L( s" S
    ##
    + I$ F. h3 H' r) c, W## $CI$NRI8 K' q. \2 G7 V& @7 R" ^
    ##                     KM         IPW   SmoothIPW         SEM    Combined
      A% i  ^/ t2 q) R. A9 E## lowerbound -0.05112533 -0.04569046 -0.05439863 -0.04132364 -0.05443409& X5 D8 ^- t5 L
    ## upperbound  0.89306122  0.92464359  0.87970125  0.64253510  0.87953153) C: E4 H* ^* S. B: t$ q
    ## 9 W! x- N, _0 p. e8 L& I! i- W5 ?$ ~9 j
    ##
    5 k! J+ }$ c- r' S8 ^( y## $bootMethod7 Q, d) y- E" }# J
    ## [1] "normal"
    6 D; a0 Q" J" p, f## 4 |& X) {* A5 x. Q- ?
    ## $predict.time
    / {) c6 S( B' |0 [1 z, l5 \/ p## [1] 2000+ r' O- s3 d2 L1 g9 f' U5 I
    ## - F0 z2 x" i& ^( z; R( @& W: J
    ## $alpha0 h. ?# c( E2 E1 N% L" d* f. |
    ## [1] 0.058 ?7 O2 f3 n, R* E" P' f, w( w& L
    ##
    5 j# K8 D6 {6 ?' a$ N; S$ o* E## attr(,"class")8 f# H+ E! s: x8 @
    ## [1] "survNRI"
    : l3 k! \2 ]. q' c$ I+ q' ^8 V1 ]
    6 d( ~9 w1 o- e$ x; R1
    : V5 |% J  |' J- M$ |% T% aOK,这就是NRI的计算,除此之外,随机森林、决策树、lasso回归、SVM等,这些模型,都是可以计算的NRI的,后面会继续介绍。大家如果有问题欢迎在评论区留言。  }' L( z! W0 y0 v

    # L3 m/ e4 |* C$ ?8 I- G+ f& q本文首发于公众号:医学和生信笔记
    1 A3 Y, V6 `9 L7 e! G. t7 A; O! j9 r  M
    “ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。
    ! T8 G6 Z0 O/ o% m: B! x本文由 mdnice 多平台发布
    ' W; Q& t) [6 O' B3 E3 w0 V8 W————————————————+ _; q' f" G7 k# h% `1 R' Z
    版权声明:本文为CSDN博主「阿越就是我」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。, p( ~! t4 h% e* O, z
    原文链接:https://blog.csdn.net/Ayue0616/article/details/126768006& ?) u# P; r+ W! u% }  b% T; O( L- N
    2 ^3 o' k9 z$ o$ q$ k% D
    5 \. X: W1 V2 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-7-31 11:54 , Processed in 0.747882 second(s), 51 queries .

    回顶部