QQ登录

只需要一步,快速开始

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

    $ `( u7 s3 Z# x9 S3 {+ q净重新分类指数NRI的计算" i9 X" b6 a' K: {2 l7 E& z
    “ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。; {: P$ h8 q% c/ A
    NRI,net reclassification index,净重新分类指数,是用来比较模型准确度的,这个概念有点难理解,但是非常重要,在临床研究中非常常见,是评价模型的一大利器!
    * K1 Q1 ]: V! k% ]9 ?4 D$ @' B) I$ |5 f
    在R语言中有很多包可以计算NRI,但是能同时计算logistic回归和cox回归的只有nricens包,PredictABEL可以计算logistic模型的净重分类指数,survNRI可以计算cox模型的净重分类指数。
    . {. ^: K/ @9 M6 T1 g! B. L5 q- o; F% O) @' S
    logistic的NRI4 G; P( c0 t1 m
    nricens包
    ! Z/ i6 j9 W" ]9 G8 ^  H3 TPredictABEL包: E( M2 U$ m- D7 Q# V; ?- A' h4 ~
    生存分析的NRI" E1 y2 g  j+ Y( K" U0 K5 I4 j
    nricens包- P) B% X# e7 h' ^8 Z
    survNRI包8 B3 q. N" S: s) d# y2 m7 C
    logistic的NRI
    3 Y6 I$ L. m- ?( D- anricens包
    ( f' |# V$ v, S1 k9 t#install.packages("nricens") # 安装R包
    $ {4 f6 _1 l% m) ~; k4 U* P2 C+ Blibrary(nricens)8 i2 S8 A5 |! C! K. d  z
    1
    2 l; f* F! A) {; C& l## Loading required package: survival
      G4 q1 n6 R" c/ C6 b1
    % c5 {0 m2 @8 T. x$ X使用survival包中的pbc数据集用于演示,这是一份关于原发性硬化性胆管炎的数据,其实是一份用于生存分析的数据,是有时间变量的,但是这里我们用于演示logistic回归,只要不使用time这一列就可以了。
    - Y4 f9 |$ R! E3 g' u" m# r1 D4 i8 O' ]2 q% z  F
    library(survival)
    ' k7 X) _0 \$ B' v1 }2 m: S4 J. ?% d6 T, U
    # 只使用部分数据
    # I1 a, ]- e% c; S1 Mdat = pbc[1:312,]
    : ]! j+ O* C, Z0 M5 {5 V2 S  ndat = dat[ dat$time > 2000 | (dat$time < 2000 & dat$status == 2), ]8 p; Y% f+ q0 A  T& d+ O( @

    * h2 p" P- j7 u' _str(dat) # 数据长这样
    - _6 N4 ], u" ^2 {# v& }1
    % l1 f8 h1 h3 z) W" e## 'data.frame': 232 obs. of  20 variables:6 G& w* X4 U8 d" ]
    ##  $ id      : int  1 2 3 4 6 8 9 10 11 12 ...
    ' j* e  S  I) X+ t( L( V##  $ time    : int  400 4500 1012 1925 2503 2466 2400 51 3762 304 ...
    ; H9 s( T1 k- a. h& J" }8 l##  $ status  : int  2 0 2 2 2 2 2 2 2 2 ...! g: Z* z6 c* D" I8 y
    ##  $ trt     : int  1 1 1 1 2 2 1 2 2 2 ...
    - {3 B$ u# O+ d1 p4 f1 C) h& N$ G! R##  $ age     : num  58.8 56.4 70.1 54.7 66.3 ...1 M0 b& H" A# v; p5 d% v
    ##  $ sex     : Factor w/ 2 levels "m","f": 2 2 1 2 2 2 2 2 2 2 ...  @' ]7 m) j, Z( [" K
    ##  $ ascites : int  1 0 0 0 0 0 0 1 0 0 ...2 A- L, a1 M* S6 D4 R
    ##  $ hepato  : int  1 1 0 1 1 0 0 0 1 0 ...
    / q! M1 Y6 Y& P8 h##  $ spiders : int  1 1 0 1 0 0 1 1 1 1 ...! U: G/ v) V7 K5 O0 T' z- p4 T
    ##  $ edema   : num  1 0 0.5 0.5 0 0 0 1 0 0 ...
    " R$ G2 k' N/ y9 z$ b1 U' V, N" l##  $ bili    : num  14.5 1.1 1.4 1.8 0.8 0.3 3.2 12.6 1.4 3.6 ...8 Y; \( k4 R9 Z) B
    ##  $ chol    : int  261 302 176 244 248 280 562 200 259 236 ...4 @3 r3 t; E8 Y: R
    ##  $ albumin : num  2.6 4.14 3.48 2.54 3.98 4 3.08 2.74 4.16 3.52 ...
    1 E; ?* v2 T  ?# s$ Q##  $ copper  : int  156 54 210 64 50 52 79 140 46 94 ...
    - i0 k( F  |) R( R6 [##  $ alk.phos: num  1718 7395 516 6122 944 ...  m% |1 y: k4 u* }
    ##  $ ast     : num  137.9 113.5 96.1 60.6 93 ...
    ) z/ W3 h5 ^5 V8 u5 C! v8 s##  $ trig    : int  172 88 55 92 63 189 88 143 79 95 ...
    ! Z/ K' i# W. o7 H6 r  O##  $ platelet: int  190 221 151 183 NA 373 251 302 258 71 ...
    3 X0 I/ c( ]0 I% d5 p% ~* f' m1 m##  $ protime : num  12.2 10.6 12 10.3 11 11 11 11.5 12 13.6 ...' T1 Y/ g$ e( o  n- \
    ##  $ stage   : int  4 3 4 4 3 3 2 4 4 4 ...
    ! B" _( q" _! K+ |9 \  E! @- z2 W5 _- y; z
    1
    * i# c  p+ j4 x+ J, U# V8 ?1 fdim(dat) # 232 20
    * J! E7 @/ o0 Z% {; j- }  B13 z7 m; \: `9 b
    ## [1] 232  20
    " M- L! \- l1 e1 N" Z1 P4 E2 `; Z1
    6 b' j* D5 ?% r! E4 h( d; l2 v然后就是准备计算NRI所需要的各个参数。
    - F/ i) ~5 ~5 X% r9 b+ h  N5 m" e  h1 l  M5 A
    # 定义结局事件,0是存活,1是死亡$ N7 O! f; @. l- ^+ W2 n: D& m0 T
    event = ifelse(dat$time < 2000 & dat$status == 2, 1, 0)4 e$ q9 i3 `9 `) }# k

      [- I+ ]: n& M) d  t# 两个只由预测变量组成的矩阵7 B/ h& J+ G, `# s1 R" u
    z.std = as.matrix(subset(dat, select = c(age, bili, albumin)))
    ' m# d1 J1 A" ]/ rz.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))1 U% U, l5 g$ S( q
    5 [2 W6 J, S' y% q* d. h, h* l
    # 建立2个模型% B! ]! Z7 e/ }3 q" Z
    mstd = glm(event ~ age + bili + albumin, family = binomial(), data = dat, x=TRUE)
    / ?# c$ z6 D1 Z$ r" G9 ^mnew = glm(event ~ age + bili + albumin + protime, family = binomial(), data = dat, x=TRUE)
    ( y( J( i& Z, }0 `& p' w$ F5 `! Z- J( X$ W7 ^
    # 取出模型预测概率
    " r) `$ C; [/ Pp.std = mstd$fitted.values/ K) G, s9 S& H5 I4 F! v+ {8 E
    p.new = mnew$fitted.values8 I  s' g! Y8 h. Z

    2 v6 x$ R- ]+ S! b17 I- v2 W5 ?1 Y3 u3 ]
    然后就是计算NRI,对于二分类变量,使用nribin()函数,这个函数提供了3种参数使用组合,任选一种都可以计算出来(结果一样),以下3组参数任选1组即可。 mdl.std, mdl.new 或者 event, z.std, z.new 或者 event, p.std, p.new。
    % k) X, L% F+ d8 p5 U! s" }; \. L/ L8 _' j- j& s# k1 P
    # 这3种方法算出来都是一样的结果: h/ V7 m2 [6 z- I6 m

    % ~3 S3 Y- e( i4 q( D# 两个模型- c, y  F9 A! `. q
    nribin(mdl.std = mstd, mdl.new = mnew,
    # l8 F- I& D2 o7 u       cut = c(0.3,0.7),
    # Y6 W* [$ X1 C% v7 s       niter = 500, 8 b- U# E0 ^9 a
           updown = 'category')
    5 g6 u( V& {. C' e; H9 l8 e
    8 ^9 _, B1 {( M: F! n6 b# 结果变量 + 两个只有预测变量的矩阵( }8 q: B3 {* n+ c9 C* f
    nribin(event = event, z.std = z.std, z.new = z.new, 9 B" v; b8 s8 A8 f/ ^
           cut = c(0.3,0.7), ) t: i+ \; f- {
           niter = 500,
    0 U3 g8 m7 [5 V0 r6 c       updown = 'category')4 o7 y6 f) U, C- v* B3 u( ~
    9 q8 D$ p) D0 O7 {
    ## 结果变量 + 两个模型得到的预测概率
    ! Q2 }2 i2 r7 D  J7 p0 ~1 wnribin(event = event, p.std = p.std, p.new = p.new, - N- ]- H; g$ Z
           cut = c(0.3,0.7), . H7 I2 e# O' Q  p. a8 F
           niter = 500, . t, C! @' G+ ?" G
           updown = 'category')
    8 I8 f% r" _$ L" w+ x
    : Y8 J) n" }& ^( S6 |$ _- a, ?1
    ; ]# e' j8 ~: y5 [$ e! G9 A其中,cut是判断风险高低的阈值,我们使用了0.3,0.7,代表0-0.3是低风险,0.3-0.7是中风险,0.7-1是高风险,这个阈值是自己设置的,大家根据经验或者文献设置即可。
    5 d" s3 b3 L  L. ~; f6 f4 L. X& \0 Q9 _# I3 g0 g9 y9 E
    niter是使用bootstrap法进行重抽样的次数,默认是1000,大家可以自己设置。$ [4 M' c  H2 }3 U+ o! j
    * D9 C# X( d/ b' z! Z( U0 ]) N
    updown参数,当设置为category时,表示低、中、高风险这种方式;当设置为diff时,此时cut的取值只能设置1个,比如设置0.2,即表示当新模型预测的风险和旧模型相差20%时,认为是重新分类。
    0 i1 I1 Z8 g: W
    * f3 f2 Z0 x7 `1 n, x上面的代码运行后结果是这样的:$ }/ {4 g! u' b( j' N
    6 c' S9 a4 \4 \0 x& |) d
    UP and DOWN calculation:: v( x) p3 V5 }2 g
      #of total, case, and control subjects at t0:  232 88 144
    1 t: t; y  d2 e& J
    ) a# L4 m( j- |% X! n  Reclassification Table for all subjects:# {& A6 h$ h0 B  E% O- [* _8 b; g& \
            New
    + U" g% ^5 g& m( F3 d7 B& A& wStandard < 0.3 < 0.7 >= 0.7
    * I: [( T  ~% ?& p2 Z  < 0.3    135     4      0
    0 I( i9 E1 j4 E3 [  < 0.7      1    31      4
    ( s: ]$ J$ \$ S& B% ?5 C; I8 p" v  >= 0.7     0     2     55
    & V; w# ]8 S* d/ S# [# t! j. q
      Reclassification Table for case:' ~/ b9 Z( U) V4 Y0 E7 Y7 e( E
            New& Y' M- o+ c( V9 S6 G  P! X% H0 b
    Standard < 0.3 < 0.7 >= 0.7& q; W. \& o) z; {
      < 0.3     14     0      07 j+ \% p, Y. O: U
      < 0.7      0    18      3
    % d' `. c5 m  h: N" ?  >= 0.7     0     1     52; \/ P/ v, x3 l& ?( b
    " ~. j$ r  H9 O: z) ?
      Reclassification Table for control:* Y& B; I5 j% G
            New" u# o0 w5 s7 r
    Standard < 0.3 < 0.7 >= 0.7
    4 D+ r" C% y- c( j( x  < 0.3    121     4      0
    $ e- S8 ?8 V5 R: P  < 0.7      1    13      1$ P0 ~; d$ a: M
      >= 0.7     0     1      3
    & g% ]8 c6 `( d  S7 M- p/ `
    7 L+ G9 y- U  a9 Q5 K+ g# ^NRI estimation:0 ]+ k* U# [# d( m! n0 f* N( h! p$ p
    Point estimates:* \) D  P2 X# w; c! A" ]2 }+ `
                      Estimate
    3 w% p9 e* _. nNRI            0.001893939, t) L$ W# M! D5 k7 o; S! I
    NRI+           0.022727273
    . W. N! x) `$ V0 D$ u  DNRI-          -0.0208333339 q' i- |9 _- Z5 p5 H9 I% z" K
    Pr(Up|Case)    0.034090909
    ' U) X1 L6 o0 s4 j; C- zPr(Down|Case)  0.011363636
    0 S; r6 g$ J1 J% i6 g! I- RPr(Down|Ctrl)  0.013888889
    * ~# o, H3 G. @7 \+ vPr(Up|Ctrl)    0.034722222+ E2 `! K1 D2 a/ y/ D
    - R4 }. [6 n- p* M3 Y9 E( T2 G
    Now in bootstrap..
    4 U/ b# }1 ^6 U6 O1 ]( |* o3 X8 ~) E" ~3 x
    Point & Interval estimates:
    2 O( z$ T! |* ^( N' k2 Y- Z5 S9 u                  Estimate   Std.Error        Lower       Upper
    . l8 R! ^( a* I* _6 }0 P  C0 Q7 cNRI            0.001893939 0.027816095 -0.053995513 0.055354449  o* t4 W7 U  e; m8 K
    NRI+           0.022727273 0.021564394 -0.019801980 0.065789474
    7 Q9 ^9 l  E& CNRI-          -0.020833333 0.017312438 -0.058823529 0.007518797
    9 A$ a7 S; v( @7 r, [0 xPr(Up|Case)    0.034090909 0.019007629  0.000000000 0.072164948
      ^! O' U/ v# o, VPr(Down|Case)  0.011363636 0.010924271  0.000000000 0.039603960
    ; H: w) u3 b: K% t6 V% KPr(Down|Ctrl)  0.013888889 0.009334685  0.000000000 0.035211268  O; [* C. Q& E7 @# S  b4 @5 t
    Pr(Up|Ctrl)    0.034722222 0.014716046  0.006993007 0.066176471
    - _8 n: B1 @& e5 Q
    ; K, I1 S# d2 s& W9 B1
    4 [* u% X  m8 i首先是3个混淆矩阵,第一个是全体的,第2个是case(结局为1)组的,第3个是control(结局为2)组的,有了这3个矩阵,我们可以自己计算净重分类指数。
    4 V+ U/ ~9 R# w3 P  `) Z
    % }. |: ^: P, O# i看case组:
    7 v* b2 O, S4 {# I& z+ y9 x) f( V
    1 ^. C( h4 B$ y3 [% P! W$ F净重分类指数 = ((0+3)-(0+1)) / 88 ≈ 0.022727273( I9 X3 w+ Q: g9 w2 Q

    ' y6 t& P5 |# x/ {& T  R再看control组:
    : ?5 U. Q) d5 U' c% {! j3 i) _& [+ n5 @5 V& b
    净重分类指数 = ((1+1)-(4+1)) / 144 ≈ -0.020833333
    & Z* Y( s% G4 y; L$ i6 M/ p1 }# v: f% _$ c
    相加净重分类指数 = case组净重分类指数 + control组净重分类指数 = 2/88 - 3/144 ≈ 0.000315657
    9 P% B2 \- i' E! I, q& O! H+ X7 |' ~9 S
    再往下是不做bootstrap时得到的估计值,其中NRI就是绝对净重分类指数,NRI+是case组的净重分类指数,NRI-是control组的净重分类指数(和我们计算的一样哦),最后是做了500次bootstrap后得到的估计值,并且有标准误和可信区间。/ h& i2 H' b8 l/ O8 r: b7 P7 V

    + `. t0 T: E6 c; m& L1 Z最后还会得到一张图:. L. Z) q4 H; m# e5 h0 o$ F
    + y3 L- b, L& }6 ~/ W  a: a
    这张图中的虚线对应的坐标,就是我们在cut中设置的阈值,这张图对应的是上面结果中的第一个混淆矩阵,反应的是总体的情况,case是结果为1的组,也就是发生结局的组,control是结果为0的组,也就是未发生结局的组。
    5 b5 ]! v* ~, |" ~: y  y  U
    . ^- ?3 S7 }+ S( ~P值没有直接给出,但是可以自己计算。6 w% m$ ]7 t( H+ ^2 p) |, J

    - k' ~$ {) Z6 `; i8 n. w2 z# 计算P值9 U. d% u, C+ ]
    z <- abs(0.001893939/0.027816095)0 y2 O- c) ^) P- z/ o& Z
    p <- (1 - pnorm(z))*2
    " ]1 _. Y! ^) s5 _: e2 B# g% Pp/ z' |2 o4 E1 K+ H9 Q5 M6 L* m+ ^% Q4 A
    1, k' q. Z6 N: f
    ## [1] 0.9457157
    ( ^& r( I; z7 o- S; k1
    & P/ u9 R4 L' x: y" P/ X) QPredictABEL包
    % w- D3 P- k0 {! W$ [: z#install.packages("PredictABEL") #安装R包$ u. Q  B( W' x3 M5 Y3 f
    library(PredictABEL)  
    / b9 {1 T2 Y" W3 d- v! y
    + B' z. a" b4 D' Y- b& k8 b# 取出模型预测概率,这个包只能用预测概率计算) Y+ v) u' U9 m0 Y+ q
    p.std = mstd$fitted.values( C$ J: c! ?9 b7 z4 B$ ]8 S6 S
    p.new = mnew$fitted.values
    9 l  Q* a$ s5 T9 E- o+ k1+ |' z& A+ q. D; b: Z; @& e
    然后就是计算NRI:( Q3 Y. u( q+ j* }) A
    ) A. H! q" l# O" l
    dat$event <- event
    ; R# M. W+ f  _& S2 g" ]% z, N" B6 G0 e7 R) o; @" J( z
    reclassification(data = dat,
    2 t7 w% p. T/ ?                 cOutcome = 21, # 结果变量在哪一列
    $ q" P& u) z9 T+ R- n/ a                 predrisk1 = p.std,
    ( H2 h! u) u, J! }, q, O. ]: t                 predrisk2 = p.new,
    9 ~# T( U5 Z0 M( @! F2 d                 cutoff = c(0,0.3,0.7,1)" h, v$ e& R, @/ h- A" g
                     )/ L+ d4 ?0 Z+ J$ W+ i
    1$ z2 |/ A9 u9 p& u1 Q
    ##  _________________________________________- X! U& l& N' R& A3 Q- ?
    ##  
    5 o- U$ a7 Z9 F' g9 \& r/ M1 z##      Reclassification table   
    ) ]1 M4 Z9 f3 Y##  _________________________________________
    1 C8 i2 `. \0 i7 h% b7 V! Q##
    * c6 _' _; K' M5 Y/ u! N8 p3 \8 p##  Outcome: absent
    8 B' W7 ^$ a- v5 c1 C  t7 g* x##   & Y6 U" m+ f" `$ }' u5 r( L0 V
    ##              Updated Model
    $ a7 C& @( [& }1 Q. \" D  J## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified3 z2 s* U( k4 `- G) b
    ##     [0,0.3)       121         4       0               3
    ! X8 q+ l0 N/ W##     [0.3,0.7)       1        13       1              13
    3 l2 f& R. Z8 M; T- ^: y##     [0.7,1]         0         1       3              25
    1 H% M" h. ~8 j! K/ \##
    8 a3 D7 @1 Z% P  B) y& s0 P##  * F  {+ T9 F* u
    ##  Outcome: present
    % G; ^- n+ x9 m##   
    4 m- G' r! F+ J$ q2 m##              Updated Model
    ) @; m. d) A  k; A; w/ e4 X" e## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
    6 K" u7 P. D. J, L% r3 M' c##     [0,0.3)        14         0       0               0
    % B, k0 M$ j! ]% h* C; _##     [0.3,0.7)       0        18       3              14
    - g8 |5 F1 b# N$ e##     [0.7,1]         0         1      52               22 v, \  S2 l: k6 g# d# Y
    ## + F9 \& P' n2 v/ w5 \6 h
    ##  , y# v) E5 N0 v2 V
    ##  Combined Data
    % P; v) p+ n$ n# k; ~' Y##   
    ! p" h8 _2 L& p, F##              Updated Model
    , E9 l* {3 |$ |## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
    / D& t5 G  ~# I7 u+ O##     [0,0.3)       135         4       0               3* S% v5 R- J, M% f
    ##     [0.3,0.7)       1        31       4              14, m) o; z% n1 L" i9 s' M+ [: n1 M
    ##     [0.7,1]         0         2      55               4; G+ a# ^' n1 ]5 s% @
    ##  _________________________________________
    ( w$ q+ u9 m* Q+ n4 X. f## 6 ~# i  X7 e  H) _! z' H7 A+ s
    ##  NRI(Categorical) [95% CI]: 0.0019 [ -0.0551 - 0.0589 ] ; p-value: 0.94806
    8 P8 K5 o& f0 G! N% d: X/ R0 A+ t##  NRI(Continuous) [95% CI]: 0.0391 [ -0.2238 - 0.3021 ] ; p-value: 0.77048
    ; n7 r0 P' g$ P( P2 \##  IDI [95% CI]: 0.0044 [ -0.0037 - 0.0126 ] ; p-value: 0.28396
    * v" ]+ y2 h' A8 r) A' x
    % S1 }4 V" l- ~1" D' k$ n9 E$ @0 B0 A; P/ C/ {% ?
    结果得到的是相加净重分类指数,还给出了IDI和P值。两个包算是各有优劣吧,大家可以自由选择。7 d, d4 n4 e* ]/ J

    2 i. i  M% |, r" z  q生存分析的NRI
    3 o( U& B' ]$ l0 f/ ?还是使用survival包中的pbc数据集用于演示,这次要构建cox回归模型,因此我们要使用time这一列了。& `/ [% t' f/ y: g
    2 J* F8 ^( P& J& U% w/ @
    nricens包' [( O4 l" \6 B+ S! F" p( L( `# u* f
    library(nricens)/ b/ E) h7 A3 u: j
    library(survival): m) e3 L; Z  W2 L

    9 b) v2 \: a5 j/ W$ @dat <- pbc[1:312,]  Z% z0 _; a- e% w
    dat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡
    & F, ?% a4 W' N14 w- G' _+ T- X) {/ t
    然后准备所需参数:
    4 o/ H" O6 i- N; {, Q+ f  S1 I- O7 h3 L( W/ h: H5 N* e0 Q7 h
    # 两个只由预测变量组成的矩阵- n* w1 \* l+ S" e8 k3 O" D$ Z
    z.std = as.matrix(subset(dat, select = c(age, bili, albumin)))* |  k" v9 K+ I- _1 U# P* k
    z.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime))); ^8 z7 o8 R. ?4 {

    # k+ h0 ^( F. d6 k' L" W$ k# 建立2个cox模型& q* a" I, n& t2 p* }( ~
    mstd <- coxph(Surv(time,status) ~ age + bili + albumin, data = dat, x=TRUE)/ x" n7 d' d& Z. u' ^
    mnew <- coxph(Surv(time,status) ~ age + bili + albumin + protime, data = dat, x=TRUE). P% t+ ^- s0 V7 X+ G, O, R

    ' i0 T0 f! y0 Q: k) K" a! s8 [# 计算在2000天的模型预测概率,这一步不要也行,看你使用哪些参数
    1 @  g* g) j3 t: W1 T" T4 Hp.std <- get.risk.coxph(mstd, t0=2000); K$ b/ E3 {  ]* t' _
    p.new <- get.risk.coxph(mnew, t0=2000)
    , E, I: k+ F( R2 M1% g: n: f& v0 e+ w2 X
    计算NRI:! i0 h# G& g& |; y  Q& }  H% I
    ' O, j4 @" ]" Y  q" V
    nricens(mdl.std= mstd, mdl.new = mnew, % e9 q; o3 e0 B! r6 M) L
            t0 = 2000, ! f2 h8 ^' R! O. N/ }, y- p; Y% Y
            cut = c(0.3, 0.7),
      n* P0 Q& O6 [  u        niter = 1000,
    # a, K, g$ V( l- W        updown = 'category')9 h* ^4 p8 L$ D! p! {- m
    $ c* K5 ~0 E5 r6 \- }. O+ b, K
    UP and DOWN calculation:# F+ ~3 r/ M- Z
      #of total, case, and control subjects at t0:  312 88 1447 i2 ?" q+ P* k( S8 K* n
    4 ~% @$ n8 F& ^) R% W( R& h& V
      Reclassification Table for all subjects:
    4 V( G- R/ h  x2 }' {' d$ `( I/ ~2 e* |        New7 V' w3 T9 f6 p( @1 L1 w  t6 L, E/ @5 G: C
    Standard < 0.3 < 0.7 >= 0.7, u/ W/ B2 h  h. S+ Y5 X$ a
      < 0.3    202     7      0
    1 R' I. ?5 I- ~6 D' h8 B" ~; U. \  < 0.7     13    53      6% S4 X' Z! y) ~$ q6 X( Z
      >= 0.7     0     0     31
    : q  ?2 ]7 V' ?$ q
    8 P7 R3 G6 P: y) v: S8 W  Reclassification Table for case:9 k' S6 ]$ ?  K' T
            New
    ) a4 r, _& i0 o! a2 c/ a8 i7 M, V* SStandard < 0.3 < 0.7 >= 0.7- o/ E: v- J, L8 ]0 d
      < 0.3     19     3      04 N' y  m8 V' u0 {' b9 s
      < 0.7      3    32      48 @5 R! ^, Q3 q
      >= 0.7     0     0     27
    3 h& Q% y/ i# f" M/ E8 I' z. a. N7 ]/ v0 s
      Reclassification Table for control:
    6 d  M" B4 Y2 T3 B+ M" h! [        New3 |* l4 h3 a/ b! \4 g: E7 d
    Standard < 0.3 < 0.7 >= 0.7
      d! s. m3 S3 r0 K4 H  < 0.3    126     3      0+ u6 @8 m/ s, Y* o2 G5 ?: ], y
      < 0.7      5     7      28 q, P! F- {1 Q. ?6 n) G6 e
      >= 0.7     0     0      1
    1 h; N* [$ }6 K& m* E8 t$ e6 F
    ; T4 m* [' G3 N! E. F2 m. f6 T+ O1 [NRI estimation by KM estimator:- r. N5 A: `( `2 K- f

    " D6 D0 K3 ^0 B4 sPoint estimates:, c* b* g% U/ A! S
                    Estimate( p+ _0 [* l; t5 b# M! C1 W
    NRI           0.053776354 x& u) i: s; ?4 B$ I7 \, X
    NRI+          0.03748660
    * h1 H. P. O1 q/ J6 t% aNRI-          0.016289742 }/ d4 o9 u. k8 N/ Z3 c7 r
    Pr(Up|Case)   0.07708938
    % \, o. v7 j" p4 s- T& YPr(Down|Case) 0.03960278
    0 d  }2 W  U! x: A- HPr(Down|Ctrl) 0.04256352
    , [( I' _' T$ _% ^; M) Y3 ^: [Pr(Up|Ctrl)   0.02627378
    ( s1 ^% F4 x+ ^2 A& h9 j. k4 a
    Now in bootstrap..
    7 r9 e* Q- a5 o/ f0 N; Y+ F+ b% z5 X+ a
    Point & Interval estimates:
    8 L' ?. n4 Y: }9 a4 Q                Estimate        Lower      Upper
    # y  z* T( }- I; Z% B9 X% [, [NRI           0.05377635 -0.082230381 0.16058172- Z; S* i! m. _% i4 M3 u/ [2 k
    NRI+          0.03748660 -0.084245197 0.13231776
    $ \$ @3 m1 ?2 A2 H0 {  z( z  f1 JNRI-          0.01628974 -0.030861213 0.067536161 ^9 b2 x& ^5 _
    Pr(Up|Case)   0.07708938  0.000000000 0.191022916 p6 T% `& {5 u4 `+ g# p7 {# L
    Pr(Down|Case) 0.03960278  0.000000000 0.152360169 l' C# ~/ `  \$ n$ V
    Pr(Down|Ctrl) 0.04256352  0.004671535 0.09863170
    8 r: O8 }- N+ O9 ], L, U# x: C* WPr(Up|Ctrl)   0.02627378  0.006400463 0.05998424
    5 Z; a1 P1 J/ r. i: ~6 I
    * S4 m; @6 X. L+ s8 ]5 l& M1 a2 G1& K* e* f" V& D

    0 b9 s1 Q- Z' {$ b  \2 pSnipaste_2022-05-20_21-49-38
    1 R8 {  Z* |9 @& x7 E! t结果的解读和logistic的一模一样。
    . |4 }$ }% ^" r. }- G. w5 u- b9 H; D% l; }$ ]1 v
    survNRI包" s  l# Z* q4 u7 ~  O* _
    # 安装R包
      Z/ b) c" q6 s5 w' \& R" w1 Bdevtools::install_github("mdbrown/survNRI")6 M5 V) E  m! C
    1* f+ Z% p: O$ O" n" X
    加载R包并使用,还是用上面的pbc数据集。5 U. E! u# L6 E' z5 j2 s5 n  @
    1 I) ]: W! t0 W# Z+ i
    library(survNRI)
    0 `% N1 M  D/ s4 e9 C' K1
    9 r4 ^+ w) r9 {' E## Loading required package: MASS7 b5 z# g, D0 r, r4 B
    1
    2 m! w& E5 I6 [6 F* J% O) j9 glibrary(survival)
    5 E! @3 O7 @2 h" ~% U* v8 u) U1 ]  S8 ]6 w# d4 y2 P
    # 使用部分数据
    $ M2 a& g2 _- N9 C* k, C' vdat <- pbc[1:312,]
    . ^+ t# b6 }2 B. g" udat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡
    ' X3 z3 G+ n! i! k% `" q& n% U/ t1 c5 e3 b% g$ O8 d
    res <- survNRI(time  = "time", event = "status",
    . U; f2 C# r5 Y$ \  |: u9 x        model1 = c("age", "bili", "albumin"), # 模型1的自变量
    0 B# m4 o, j2 B. c0 F        model2 = c("age", "bili", "albumin", "protime"), # 模型2的自变量9 G$ {* L, n" t1 H: p
            data = dat,
    ! f: Q( ~5 s- R3 J$ u9 D+ _        predict.time = 2000, # 预测的时间点
    & f) l  r. w8 C: S+ |2 R        method = "all",
    , I+ {' G. C& \9 u        bootMethod = "normal",    S% q* s! X- T" r8 A; e
            bootstraps = 500, ! }9 A9 G6 q. c; w
            alpha = .05)
    3 G" D5 K7 a  J+ j+ J6 F$ L& _
    " J9 l  ^: N: p2 O1
    ( A/ i6 m# }  L; Y7 y% E) w查看结果,$estimates给出了不同组的NRI以及总的NRI,包括了使用不同方法(KM/IPW/SmoothIPW/SEM/Combined)得到的结果;$CI给出了可信区间。* |7 l6 J" P, p3 Y6 {2 L

    3 D, `( o8 F# {7 ?, W$ vres7 ?' {. A# S% e* j4 D6 s
    1
    : g) V7 W3 B' Q3 T## $estimates$ ]! x' F6 v" c+ U
    ##            NRI.event NRI.nonevent       NRI
    1 l) i- u& w7 k6 R## KM        0.20445422    0.3187408 0.5231951
    1 J7 x; L1 `' y; F# m- A- C$ }## IPW       0.22424434    0.3273544 0.5515987
    8 q3 x+ v- Y( b6 o7 ]0 [## SmoothIPW 0.19645006    0.3144263 0.5108763
    - r$ n4 b  b  Z& R## SEM       0.07478611    0.2632127 0.3379988
    $ }- s9 X% N" \! K0 l5 j3 G## Combined  0.19633867    0.3143794 0.5107181% F2 ^8 \7 l/ z& A, z; T3 |3 z/ R
    ##
    8 n8 P9 X  d- S# s% C2 A' M- ?## $CI
      v% t5 s, c# F! c" l( P; }## $CI$NRI.event6 i/ v- z) j2 W& j* C
    ##                     KM         IPW   SmoothIPW        SEM   Combined
    ( P( G1 y* x/ f## lowerbound -0.03915924 -0.02185068 -0.04724202 -0.1162587 -0.04737232 J6 K  _! Q) S  P- Y+ t7 D- J  o
    ## upperbound  0.44806768  0.47033936  0.44014214  0.2658309  0.44004962 i+ R+ ?! ]6 A: J" V6 w6 o& U
    ##
    7 s1 n- T6 e( A- }# A% C; d  o8 h## $CI$NRI.nonevent7 @4 l+ C% W# {3 y/ F2 m" Q# }( g1 L
    ##                   KM       IPW SmoothIPW        SEM  Combined$ d, O5 V) O' ?7 P
    ## lowerbound 0.1317108 0.1396315 0.1286685 0.08638933 0.12864267 M( x, A9 e7 G' S& k6 i! F- A
    ## upperbound 0.7102251 0.7393216 0.6966341 0.51482212 0.6964549
    ( B2 `" [! d4 C## 6 A+ D3 V: z5 A. K
    ## $CI$NRI
      {& s  W  }0 g0 D6 T##                     KM         IPW   SmoothIPW         SEM    Combined1 f5 O* E" g8 O6 J5 B6 w5 G
    ## lowerbound -0.05112533 -0.04569046 -0.05439863 -0.04132364 -0.054434094 S# g. G" o) n8 r3 f
    ## upperbound  0.89306122  0.92464359  0.87970125  0.64253510  0.87953153
    9 h* |. U7 s: d9 a: V## 4 c# r- Q2 k* O+ j1 |$ T% f  d
    ## + D4 \! U' {( P
    ## $bootMethod
    ) U, z0 S5 k$ g) {! }6 k6 ^## [1] "normal"; b' j( ]$ V! k6 [3 C# b
    ## ' i4 J$ Q$ w: r% l' Z
    ## $predict.time+ d2 i" v& ]5 m: A% Y
    ## [1] 2000& R) Z: e/ x0 d3 E" d/ g
    ##
    . V2 f7 f( ?! i1 S5 w1 v## $alpha0 {" V1 Q% a0 P4 O; q
    ## [1] 0.05. K' o- H0 d- h% x- X8 f
    ##
    4 `3 d4 _3 N$ `5 I, f3 Q7 P## attr(,"class")5 I( g& r' j9 v: p) }& g
    ## [1] "survNRI", m! O/ }2 D: Q

    ) v2 S1 z  \' R1: z' y' Z/ K1 D$ c- d3 @
    OK,这就是NRI的计算,除此之外,随机森林、决策树、lasso回归、SVM等,这些模型,都是可以计算的NRI的,后面会继续介绍。大家如果有问题欢迎在评论区留言。
    / k# _7 a1 ~7 q( i
    " |# y' K/ z9 A本文首发于公众号:医学和生信笔记& Z) t# k' `& Q
    9 {- y* |' ?' X8 X
    “ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。8 T, U; [# \8 P
    本文由 mdnice 多平台发布) h. t' _* O  p! H
    ————————————————! t& j$ i' k0 D* ], g' v# m
    版权声明:本文为CSDN博主「阿越就是我」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。* I& N- t& y! l& W/ O. t
    原文链接:https://blog.csdn.net/Ayue0616/article/details/1267680064 f0 s) p7 T% c* ?. W' f+ U
    ( p6 w+ F+ t7 E6 z( |
    3 H1 B5 l/ u8 a( S) }" N
    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-9 21:22 , Processed in 0.490824 second(s), 50 queries .

    回顶部