QQ登录

只需要一步,快速开始

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

    " L' Z0 G) C) d' J5 V3 x净重新分类指数NRI的计算
      ]8 k0 N4 o+ g1 W. Y; @  Z8 o5 z“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。
    ) m. l5 Z6 ?* z' pNRI,net reclassification index,净重新分类指数,是用来比较模型准确度的,这个概念有点难理解,但是非常重要,在临床研究中非常常见,是评价模型的一大利器!3 K$ H# D/ {" R6 c* M

    ; T% |$ G( P* |: f. ~$ `; ~在R语言中有很多包可以计算NRI,但是能同时计算logistic回归和cox回归的只有nricens包,PredictABEL可以计算logistic模型的净重分类指数,survNRI可以计算cox模型的净重分类指数。
    6 B2 c7 A1 o% J. y3 V* ^! ~! {! }0 ~
    logistic的NRI* B8 k( A+ t* F/ y* Z+ v2 D
    nricens包
    & \; u" V; T% {, Q+ Y: o* ]4 r9 cPredictABEL包% `) X' H8 `4 x
    生存分析的NRI+ s5 ]: t/ |4 b2 B
    nricens包
    5 H. F+ r0 A& E3 w4 UsurvNRI包. D/ D4 ]  e. D
    logistic的NRI7 {" t* G: C8 Z" A3 s8 s5 K: ]5 U9 e
    nricens包
    ! R! Y0 E4 _! q/ a% R#install.packages("nricens") # 安装R包
    ) M! c/ G6 V' O2 `! Elibrary(nricens)* x+ K$ i! Y4 @/ m7 [
    1/ X' m0 g# X5 e1 E6 U& A6 y- l8 \
    ## Loading required package: survival# e- a- ^( l. E. y. D* g0 @
    18 Q7 @+ z0 D6 a! \
    使用survival包中的pbc数据集用于演示,这是一份关于原发性硬化性胆管炎的数据,其实是一份用于生存分析的数据,是有时间变量的,但是这里我们用于演示logistic回归,只要不使用time这一列就可以了。
    " g! q9 H) r: m, V
    , u0 a8 n0 J$ x$ L0 f1 elibrary(survival)
    / x! _$ _  x$ P7 v6 u' S; `' l# N9 R9 \
    # 只使用部分数据
    4 |, @0 f2 n& ~% ?7 X+ k) }dat = pbc[1:312,]
    " W4 m" F2 w4 cdat = dat[ dat$time > 2000 | (dat$time < 2000 & dat$status == 2), ]9 S( z% c! p$ I$ M5 v8 d

    . Y  D4 y! C6 u! ?/ c0 ystr(dat) # 数据长这样! I6 v- x9 ~1 s" H# }
    1$ t. `9 F) g! [  E& j/ Q$ F
    ## 'data.frame': 232 obs. of  20 variables:
    + G7 |* a0 f- \7 `. H' H$ |##  $ id      : int  1 2 3 4 6 8 9 10 11 12 ...
    5 F* {( p6 u) W  [) H! f##  $ time    : int  400 4500 1012 1925 2503 2466 2400 51 3762 304 ...; R. ?% N9 X- x: `& g9 B- n
    ##  $ status  : int  2 0 2 2 2 2 2 2 2 2 ...
    5 j# g9 @- T! R##  $ trt     : int  1 1 1 1 2 2 1 2 2 2 ...
    2 J" b4 L( K& |5 [2 g# U; u##  $ age     : num  58.8 56.4 70.1 54.7 66.3 ...
    % B0 c# j/ i6 q, T9 s! E##  $ sex     : Factor w/ 2 levels "m","f": 2 2 1 2 2 2 2 2 2 2 ...' z4 [2 h" ?; m6 G* I3 r
    ##  $ ascites : int  1 0 0 0 0 0 0 1 0 0 ...
    ' S0 [) i; M8 m  ^##  $ hepato  : int  1 1 0 1 1 0 0 0 1 0 ...3 G, l- n1 E( P/ }6 B; X+ D
    ##  $ spiders : int  1 1 0 1 0 0 1 1 1 1 ...
    3 m) _, K! |+ }" O##  $ edema   : num  1 0 0.5 0.5 0 0 0 1 0 0 ...2 Z( z' f1 g/ t4 T8 p- j
    ##  $ bili    : num  14.5 1.1 1.4 1.8 0.8 0.3 3.2 12.6 1.4 3.6 ...
    9 K- I2 x; m$ {2 T##  $ chol    : int  261 302 176 244 248 280 562 200 259 236 ...$ ^: L7 P) h: q$ K( A% G
    ##  $ albumin : num  2.6 4.14 3.48 2.54 3.98 4 3.08 2.74 4.16 3.52 ...
    . k6 _" S) v- O! e1 ?5 m##  $ copper  : int  156 54 210 64 50 52 79 140 46 94 ...
    6 @9 C9 j' w; u: x, h##  $ alk.phos: num  1718 7395 516 6122 944 ...
    8 k/ ?9 o; u) j0 A! Z. k##  $ ast     : num  137.9 113.5 96.1 60.6 93 ...5 ?" ^5 J; V3 y. h. ~" u
    ##  $ trig    : int  172 88 55 92 63 189 88 143 79 95 ...( e6 _4 F% F* b# r
    ##  $ platelet: int  190 221 151 183 NA 373 251 302 258 71 ...
    4 H  {" R9 s9 D" F" _+ |##  $ protime : num  12.2 10.6 12 10.3 11 11 11 11.5 12 13.6 ...0 P  O. G7 L7 Y! d
    ##  $ stage   : int  4 3 4 4 3 3 2 4 4 4 ...2 A. V4 t+ X2 m1 v: |8 I
    . y4 w( t# _( Q+ z8 N' k; K1 u* C
    1+ k: I3 }* \8 D6 M3 o
    dim(dat) # 232 20( c* ]2 u7 ^: |. m, M  u6 ^
    11 w* c* l0 ?2 s
    ## [1] 232  20
      [9 h8 p7 x- a  n; _1" y- V% U* [, M3 {* M9 `  v
    然后就是准备计算NRI所需要的各个参数。
    / U/ n/ g5 x6 ]# `
    1 x2 ?2 h; G, H  o# 定义结局事件,0是存活,1是死亡
    6 g* v  M& x' o( t- [7 ^event = ifelse(dat$time < 2000 & dat$status == 2, 1, 0)3 G" M2 {& V# @) C
    0 o3 H! A+ Z( _: S# r0 V$ ~
    # 两个只由预测变量组成的矩阵5 n) r9 R- v3 `' J8 S$ Z; k
    z.std = as.matrix(subset(dat, select = c(age, bili, albumin)))9 |$ j7 V' P& e7 g( r+ L7 H3 D" C& N
    z.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))8 b" C+ n2 a/ G3 s. m' L

    ' P0 d1 G! T4 w- G3 A# 建立2个模型) Q6 w0 ~7 _; J  k& Q/ O
    mstd = glm(event ~ age + bili + albumin, family = binomial(), data = dat, x=TRUE)( d2 I. R  @4 B* @; v
    mnew = glm(event ~ age + bili + albumin + protime, family = binomial(), data = dat, x=TRUE)
    ) s! U, ?- b: E3 P2 X+ k
    / N; V9 L' L  ?0 u) q/ c! g# 取出模型预测概率' J! ]1 _+ D% S) h3 ?
    p.std = mstd$fitted.values0 G7 U0 D5 G- |( K% U7 ~8 q
    p.new = mnew$fitted.values: L# v0 _4 U4 b& L$ f8 `& ~6 \

    / r- j" d$ T4 k+ O" K1% h" G3 r1 M: y# w( z
    然后就是计算NRI,对于二分类变量,使用nribin()函数,这个函数提供了3种参数使用组合,任选一种都可以计算出来(结果一样),以下3组参数任选1组即可。 mdl.std, mdl.new 或者 event, z.std, z.new 或者 event, p.std, p.new。
    " ^) u' Q/ b  N9 _* {# v, D  h) u  p, @3 ~( k7 p8 z$ a
    # 这3种方法算出来都是一样的结果
    6 i9 [: k+ u3 {2 w6 o! ]) W9 I
    , o+ t8 j5 ]! p6 U5 J& W# 两个模型) X) r# E8 D1 H* y$ A$ D
    nribin(mdl.std = mstd, mdl.new = mnew,
    2 _, Y& F2 }* n* V+ |( t       cut = c(0.3,0.7),
    3 q$ h/ V9 D6 e% D8 A, R       niter = 500,
    / [0 M) p7 @" a( h4 L" K0 j       updown = 'category')" C) b$ u6 O, s6 Y: D! J$ M5 k% ?

    3 I1 t4 {# n5 M3 a0 L/ [# 结果变量 + 两个只有预测变量的矩阵9 y3 I# x. M/ I, @3 h4 y
    nribin(event = event, z.std = z.std, z.new = z.new,
    4 l, l9 N  g  w) B: _       cut = c(0.3,0.7), ) S! s/ l7 k7 e. ~, x
           niter = 500, 9 q9 l0 I' _5 c  _2 G9 W! O( r
           updown = 'category')9 o0 m3 T# q' M9 s  Y

    / p5 i0 X6 _: h; E' u/ o' y## 结果变量 + 两个模型得到的预测概率
    * g" k2 p& A. P' F( A- {1 Rnribin(event = event, p.std = p.std, p.new = p.new, 4 R8 d+ h. R* c
           cut = c(0.3,0.7), 5 Y* m7 |$ `( {4 R
           niter = 500, / o1 f/ f' [& n; E, _! W
           updown = 'category')) H# @4 i) }: }+ T3 r* f8 w& D
      W4 R3 ^# @2 \
    1
    + r& ^: }, v$ b5 ]% ]0 u1 U" C% Z" }其中,cut是判断风险高低的阈值,我们使用了0.3,0.7,代表0-0.3是低风险,0.3-0.7是中风险,0.7-1是高风险,这个阈值是自己设置的,大家根据经验或者文献设置即可。6 J( }% s7 e% i8 w! [' }0 t. x

    . U& B. ?! a4 S; jniter是使用bootstrap法进行重抽样的次数,默认是1000,大家可以自己设置。4 k6 N$ R& H: `* j
    . r1 a0 b+ S# w+ W7 ~& n
    updown参数,当设置为category时,表示低、中、高风险这种方式;当设置为diff时,此时cut的取值只能设置1个,比如设置0.2,即表示当新模型预测的风险和旧模型相差20%时,认为是重新分类。3 F( j+ G' d3 N6 Z  |6 c' b
    , L6 Y4 C- y0 U( O0 v* `
    上面的代码运行后结果是这样的:/ j8 Q: \9 q* p
    + T- T/ W+ A* `
    UP and DOWN calculation:
    ' _% R' _: \5 M" Q  #of total, case, and control subjects at t0:  232 88 1442 W3 }0 u4 q+ |: k
      m2 u& B# Y- n0 I/ g* I
      Reclassification Table for all subjects:1 x# j  P+ P! B9 c, f
            New
      g* \6 u5 K& PStandard < 0.3 < 0.7 >= 0.7) q; g. o8 L" K4 F. L
      < 0.3    135     4      0
    / X# p; `5 W3 h  < 0.7      1    31      4" i8 \: }, a, H% z2 v5 m
      >= 0.7     0     2     551 D' m" w; Q" {; R
    + n7 ?7 h) R; W& A
      Reclassification Table for case:" H6 M. p- H8 J4 s# f( }* b
            New7 ^8 r% W1 A, z
    Standard < 0.3 < 0.7 >= 0.7- o/ W5 s& i5 r, D5 s
      < 0.3     14     0      0
    + u2 {, j# T+ n, S3 D  < 0.7      0    18      3
    # ^- i$ f5 s, r& ^9 P  >= 0.7     0     1     52/ T. l2 K) u4 y. R* F! o  @

    ; B2 L5 \% z7 P: {$ S8 U  Reclassification Table for control:. A. x6 d- G# ]' e
            New
    6 e' r( F) H* OStandard < 0.3 < 0.7 >= 0.7( `( \3 k7 j! L5 r
      < 0.3    121     4      0! @! `2 p% w. [( A3 Z
      < 0.7      1    13      1& v& X( ?6 E8 M. s' ~$ P
      >= 0.7     0     1      3# Y5 C( J$ Z, S: V# N

    % M; w, N( t1 d8 n) |  S' A7 rNRI estimation:
    - ]- Z8 J& A3 f7 n, y  @( ^Point estimates:
    : T& X' o6 o1 }6 h6 a( p! Q                  Estimate9 o$ R  |3 ^; I6 q! C
    NRI            0.001893939
    % }. e1 r* D5 zNRI+           0.022727273' p- ?7 X, Z3 ?4 n) G$ R  A
    NRI-          -0.020833333
    $ i9 t$ p) y7 ~+ Y0 ePr(Up|Case)    0.034090909
    # o8 t2 F" p$ `" APr(Down|Case)  0.0113636366 H' L8 f" H7 f: S: B
    Pr(Down|Ctrl)  0.013888889
    7 b  O. @" {( E; J) s1 {" t2 BPr(Up|Ctrl)    0.034722222
    , X: g5 A4 B% I  D- D" T& Q
    ) l: h- h8 D2 t$ A  L4 M3 sNow in bootstrap..
    / m1 z" b& L; y1 s; T: D
      T1 Z+ E+ m4 JPoint & Interval estimates:
    - r1 x' Y! ]' t, n  n# i$ e; Q                  Estimate   Std.Error        Lower       Upper
    2 p8 d8 E+ R/ B( Y- p8 U+ P- R' P( ?NRI            0.001893939 0.027816095 -0.053995513 0.055354449
    5 l. Z* e8 H7 V0 j, i+ g$ RNRI+           0.022727273 0.021564394 -0.019801980 0.065789474$ Y8 b3 J0 X' O& E7 x2 W- O# Q1 m) F
    NRI-          -0.020833333 0.017312438 -0.058823529 0.007518797
    $ L& h, d- ~9 E) j; F4 jPr(Up|Case)    0.034090909 0.019007629  0.000000000 0.072164948
    3 V9 @. G. x6 k6 OPr(Down|Case)  0.011363636 0.010924271  0.000000000 0.039603960
    6 e5 J, i9 g4 JPr(Down|Ctrl)  0.013888889 0.009334685  0.000000000 0.035211268* _* A, N9 ?/ c+ }
    Pr(Up|Ctrl)    0.034722222 0.014716046  0.006993007 0.066176471
    ! ]# v0 M+ I4 i; s5 T9 R
      q5 c$ o5 W! i+ K/ M. e: B8 w+ Q1
    7 P( f" \2 D; ~4 v首先是3个混淆矩阵,第一个是全体的,第2个是case(结局为1)组的,第3个是control(结局为2)组的,有了这3个矩阵,我们可以自己计算净重分类指数。& |/ t, T8 u  H; z; J, ]: {. e

    7 `6 [) U7 E4 D% T( N/ s看case组:
    5 _; H- w* U6 l9 s* S4 {( s
    6 r2 s% B# w  T净重分类指数 = ((0+3)-(0+1)) / 88 ≈ 0.0227272737 l( {; Y) C$ l6 m
    ' v. i  ^$ F! [0 L6 D
    再看control组:$ t) [) N7 u) O! Z8 P/ k$ |8 A
    6 G, R! e. a4 R- K
    净重分类指数 = ((1+1)-(4+1)) / 144 ≈ -0.020833333
    , K! v$ I+ i6 R3 p( A4 i. j7 x8 M6 h% D! {8 K1 a
    相加净重分类指数 = case组净重分类指数 + control组净重分类指数 = 2/88 - 3/144 ≈ 0.000315657
    ) [6 m4 M. r7 [+ d' Y0 ]' e. R2 j% N+ ]6 A* @! b" m2 W6 y
    再往下是不做bootstrap时得到的估计值,其中NRI就是绝对净重分类指数,NRI+是case组的净重分类指数,NRI-是control组的净重分类指数(和我们计算的一样哦),最后是做了500次bootstrap后得到的估计值,并且有标准误和可信区间。+ ?0 \/ |( N% S" o" ]
    ; p" r* ], D" A* ~5 y
    最后还会得到一张图:
    ( D5 b: L: Q$ L3 C/ f& f0 M  M3 s* `0 R* ]! ]- A$ C6 R/ E
    这张图中的虚线对应的坐标,就是我们在cut中设置的阈值,这张图对应的是上面结果中的第一个混淆矩阵,反应的是总体的情况,case是结果为1的组,也就是发生结局的组,control是结果为0的组,也就是未发生结局的组。
    + E9 z+ m/ t  R% p. b) ?5 `% w# [' z9 ^
    9 ^# X! F3 T8 R7 R1 u5 I3 y7 i: N' eP值没有直接给出,但是可以自己计算。
    9 y% b  r2 S4 Z$ O$ v9 X, T: G  k  w/ d8 R
    # 计算P值+ @& ], u& @* ~7 [3 v
    z <- abs(0.001893939/0.027816095)/ U/ D/ j% v2 q: A
    p <- (1 - pnorm(z))*2
    4 q, N8 G" L- P. h" J. O, qp
      s1 a8 a! |- t6 f3 t% O1
    0 a5 c. p- b& F3 M; n  r% U## [1] 0.9457157
    + e) p' @1 X1 a* q1
    8 v7 _1 P$ r6 j5 P/ TPredictABEL包
    1 b4 r6 x# o9 ]8 Q#install.packages("PredictABEL") #安装R包
    % s. d5 o5 |8 A# ]8 zlibrary(PredictABEL)  
    0 `3 y3 r/ i. i- a) K2 d
    : n) x1 ?, m# N8 H) S. U4 I+ ^; d4 A# 取出模型预测概率,这个包只能用预测概率计算; ?6 \7 I' O- R0 L9 Z5 G: h
    p.std = mstd$fitted.values+ t1 H  D; ]1 V; @8 c/ t( Y
    p.new = mnew$fitted.values
    6 ]* z) P, ^+ A6 m- v6 V# c1! W! m. ~. c. X+ ^! L& U" g
    然后就是计算NRI:0 b8 v. ~# K; n& ^# k1 y; V

    * b# M* P. @! N% xdat$event <- event
    9 O2 Z% o* I* W3 e0 p- f$ t/ i: w; u) G: b! g! r
    reclassification(data = dat,
      w) S" e) R3 {: c                 cOutcome = 21, # 结果变量在哪一列
    + O* J1 _5 k9 S" p) S) E" }( _                 predrisk1 = p.std,
    # n% }8 X4 w8 p                 predrisk2 = p.new,
    3 I7 y2 X; f/ \4 y! V3 T                 cutoff = c(0,0.3,0.7,1)
    1 V) j! j$ Z! j9 _4 ^8 X/ o+ \                 )
    & b2 ?7 T8 h- e) m8 _: t1 g& T9 Q7 e1
    + `/ `+ m+ G  d##  _________________________________________3 F9 L7 e+ ]9 X- K- J
    ##  
    6 f. a# ?# Q3 I3 R##      Reclassification table   
    + v4 D4 l9 v- @2 X* ^* L##  _________________________________________; A) o+ n; P5 V
    ## & q  q* x0 P+ ?; G7 U. H
    ##  Outcome: absent 9 F% y( V" [" Q: ]1 X/ ~
    ##   0 N  o. G2 [% H$ _
    ##              Updated Model+ }* B; I. ~4 @
    ## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified2 R2 v" C) W4 e' g) W" {
    ##     [0,0.3)       121         4       0               3/ U. c; e! j# z) Z, _5 s* t
    ##     [0.3,0.7)       1        13       1              13
    / T; F: R6 z( M0 k  j##     [0.7,1]         0         1       3              25; V  X+ Q! U# l
    ## ' R+ O4 ~. G  N0 V
    ##  
    ) Z7 g; y6 {* u4 m. v##  Outcome: present
    4 D" u; r2 h: n2 N/ }##   
    4 @2 I% ~6 v9 G) d2 b# y$ g; X5 N##              Updated Model- \, K7 b5 \2 t& v. o! `- P: [
    ## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
    / e  d: P) e4 A; H, H##     [0,0.3)        14         0       0               0- ?8 C. a( F+ h! B- C
    ##     [0.3,0.7)       0        18       3              14$ W; ]; Y. h! N) t4 D! V" H* M2 B
    ##     [0.7,1]         0         1      52               2
    5 ]" ]! V  X( ~& m$ u+ `## 4 V! p3 f/ D; G; U3 ]8 B
    ##  4 i, n# {3 J8 r0 s3 C
    ##  Combined Data + ?# Y4 h( B; S4 j
    ##   0 M. Q( L/ |2 I) K' p
    ##              Updated Model* O$ L# f; a" m4 {9 t7 M! Q
    ## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
    " y& W. Y. T  |! \5 |##     [0,0.3)       135         4       0               31 g3 J; H& L; N8 t  o: w4 O
    ##     [0.3,0.7)       1        31       4              14
    ' V" N7 C' v, }6 Y( I) F9 o##     [0.7,1]         0         2      55               4
    9 N% _* u1 \& v# I" \) g; Z##  _________________________________________# I4 e& m' {& g  M' h* G" A3 ~
    ## - X+ K% U+ g" U2 G+ d- q
    ##  NRI(Categorical) [95% CI]: 0.0019 [ -0.0551 - 0.0589 ] ; p-value: 0.94806
    ) o& n8 S$ C# [# ]; O; t) G7 b##  NRI(Continuous) [95% CI]: 0.0391 [ -0.2238 - 0.3021 ] ; p-value: 0.77048 ) a# t5 a  Q8 \. z% _' `, T
    ##  IDI [95% CI]: 0.0044 [ -0.0037 - 0.0126 ] ; p-value: 0.28396& h/ u; [: J4 ]4 o. w
    7 ~1 T; [/ F; @9 ?) j- S+ T1 P
    1$ L; K4 M0 V) a3 q3 P9 y  T
    结果得到的是相加净重分类指数,还给出了IDI和P值。两个包算是各有优劣吧,大家可以自由选择。% q5 X/ e- c) k9 e$ C
    " J: i% d3 y6 {& O. N% l+ d
    生存分析的NRI
    # S) R) S8 V4 b2 c; {0 w还是使用survival包中的pbc数据集用于演示,这次要构建cox回归模型,因此我们要使用time这一列了。
    $ |0 a- `2 k4 W( f1 W; c1 s" H' e! }8 w4 k# v# x0 j8 t
    nricens包
    8 K; M7 ^" [: C) G* H( N8 ?3 Vlibrary(nricens)
    5 s) [8 u8 S  Z7 B2 {1 glibrary(survival)
    7 k" c8 p: J# M: E: ?7 Z# i& q+ h3 S" s; x1 e, r/ _0 N2 P! I% m
    dat <- pbc[1:312,]
    / U# r$ g, C' a- G' ~dat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡
    ; r7 ]7 ]. d- j# Y1 ~1
    : c. ?9 d$ M3 h0 N5 W% ]然后准备所需参数:( F& o! p( G6 O$ y3 q+ Y

    % V0 l9 w" N6 e1 J# 两个只由预测变量组成的矩阵- V% Q2 z8 s8 K  u6 r  F
    z.std = as.matrix(subset(dat, select = c(age, bili, albumin)))
    ; V' W. g3 @, ?1 i! c4 `z.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))
    7 y/ p9 ~6 ~( E- D  [0 g( L; y+ S0 I
    1 K5 Z, K/ ?" i7 `1 |# 建立2个cox模型
    . l: J2 `# j/ M; smstd <- coxph(Surv(time,status) ~ age + bili + albumin, data = dat, x=TRUE)
    & K% D! I# ~# d* x+ ymnew <- coxph(Surv(time,status) ~ age + bili + albumin + protime, data = dat, x=TRUE)
    + @# {  B( {; g, S! }; T) \8 ]; Q; N# U
    # 计算在2000天的模型预测概率,这一步不要也行,看你使用哪些参数# I0 C+ D, ^, p" }' L; `4 F" F
    p.std <- get.risk.coxph(mstd, t0=2000)) t, z7 F" y9 P: W, U" V
    p.new <- get.risk.coxph(mnew, t0=2000)
    + ]* G' ?* i% X* o& I0 H' M0 Q11 L" K9 G! V+ X; P7 a6 D/ X
    计算NRI:
    4 x/ f3 O' z$ t2 D; D) _# Q* n% n) a& j
    nricens(mdl.std= mstd, mdl.new = mnew, 1 o; C3 D& x. X+ e; G
            t0 = 2000,
    , @/ j2 H; Y& ?$ D        cut = c(0.3, 0.7),6 B/ ~- O! C2 D) Z9 v7 D
            niter = 1000,
    " O5 H7 G5 W, I; s- c  h" D  ]3 A        updown = 'category')
    9 x& m2 V8 h8 E( e# i
    & U1 i& E+ x/ c; i3 MUP and DOWN calculation:* N7 o% W0 P# u6 l% U6 k+ l
      #of total, case, and control subjects at t0:  312 88 144
    8 y. ^' H! e0 n6 `- O% Z+ f( F
    ! P' @0 u' U* {  Reclassification Table for all subjects:$ H, S; ]. m- [; ]4 Y/ A1 \' y8 \
            New2 Y. }+ x* e! ]/ ^
    Standard < 0.3 < 0.7 >= 0.71 N+ E* r6 V3 g# x4 n' b
      < 0.3    202     7      0
    ! t( e! S4 w+ \0 H& r  H0 s  < 0.7     13    53      6
    ' q: [; o- U4 ^; k  >= 0.7     0     0     31
    ) N. o; Y7 Y: w/ }5 }3 x
    6 ], z( D( K9 Z  Reclassification Table for case:
    ) w" J& c* u+ l! ]8 P        New
      n! n5 E' J$ m# K% ]4 ^; TStandard < 0.3 < 0.7 >= 0.7: U/ k: R& f1 O( }( y9 a
      < 0.3     19     3      0
    ! c% u0 U4 v  F+ p* g7 d  < 0.7      3    32      4+ j8 o& Z' ^" x2 [+ ~  Q0 _1 y
      >= 0.7     0     0     27
    9 G  q6 r; A- D5 D
    ' @" j# B( A. W) i& ~  Reclassification Table for control:
    7 J, W5 [" l' p3 z, c8 G$ M        New
    ) n+ d! i7 z; e- X7 d2 xStandard < 0.3 < 0.7 >= 0.76 [+ n! j, L" d  C* f5 }
      < 0.3    126     3      0; k1 C) j; S7 a# {5 [  @3 E5 Z* |
      < 0.7      5     7      2
    * X+ G2 \& E, M' `# X  >= 0.7     0     0      1) D# V5 e- {. \( l6 y$ ?
    % e& c. _5 Q  i: L
    NRI estimation by KM estimator:
    " E) n. b7 m  D- n8 u: F/ X3 q! D" S/ ^
    Point estimates:
    4 f. l) f7 G& f% ~. v                Estimate# o. i& U5 F! [7 \3 y1 X2 }
    NRI           0.05377635
    " N. V, d' F! {/ uNRI+          0.03748660
    ( H1 [0 C, L- R, ONRI-          0.016289748 u  h) f. T1 X6 j- g8 V
    Pr(Up|Case)   0.07708938
    & N% {3 `4 S0 R7 Y6 k+ M+ bPr(Down|Case) 0.03960278
    ' b3 R: X5 ]) W! W9 r3 ]Pr(Down|Ctrl) 0.042563527 t# q* h" f) g8 ?; x1 Q: l5 z
    Pr(Up|Ctrl)   0.02627378
    ( c. r! Z4 w: T$ @! e# ]* B# l) e& C$ {7 t3 O, I
    Now in bootstrap..& W( B) _' q4 P( Y6 p3 T, E% L1 w

    ( |3 C& N" F" p, kPoint & Interval estimates:& A7 d+ @. d9 v8 C" G# g6 o
                    Estimate        Lower      Upper0 \$ k. [% A+ T/ [
    NRI           0.05377635 -0.082230381 0.160581728 Z1 G( m9 n3 L
    NRI+          0.03748660 -0.084245197 0.132317763 d! G3 x# h! K& J2 A% p9 \2 Q" P9 z
    NRI-          0.01628974 -0.030861213 0.06753616
    7 C; l7 m" F# k1 w6 o) ZPr(Up|Case)   0.07708938  0.000000000 0.191022911 w( a" ~) i/ p* R2 V% s
    Pr(Down|Case) 0.03960278  0.000000000 0.15236016& q+ ?5 @* l0 Q
    Pr(Down|Ctrl) 0.04256352  0.004671535 0.09863170
    ' `# ~+ X/ p: R& K  IPr(Up|Ctrl)   0.02627378  0.006400463 0.05998424
    + P% ^% o) D2 y2 Y% [' `' u8 F+ b2 h. v/ f6 [5 H, \
    1
    6 g8 y! h: z' l( }0 A
    , t4 j6 w& W- b, s* ]8 VSnipaste_2022-05-20_21-49-38
    . r4 _, r5 }0 E) o6 X5 P结果的解读和logistic的一模一样。
    % Z  q; U4 q& t! {+ H0 x
    7 w4 Y) `$ S9 l9 V% hsurvNRI包) g- w# S( G: Q) y) k
    # 安装R包
    % S, ?2 D! C) Xdevtools::install_github("mdbrown/survNRI")
    3 e/ }0 W5 Z! `+ }' x16 ^5 I" C! A6 N0 |$ S& O
    加载R包并使用,还是用上面的pbc数据集。* T; d7 X4 Y7 _8 ^/ J

    4 |/ c7 @+ ~; F8 [6 k1 Wlibrary(survNRI)
    8 p$ w) C# |9 h4 ?% J1
    # v$ e2 o! F; c' f" F# `8 x3 k## Loading required package: MASS/ C7 ]  X' d8 n; K0 r' k8 A" Y6 }
    1  ?) S/ X6 F7 m/ t; _2 g( [/ C. e
    library(survival)6 r2 ], Q: k& `4 C+ V
    % Y  z6 \! S( C) _
    # 使用部分数据
    ) W7 s! Z$ C  r6 hdat <- pbc[1:312,]3 }' M8 L1 Z4 A# a# K% C( k
    dat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡2 R( t8 Y# p& H. d! R$ a( A

    1 }% i( j" ]: Q6 Lres <- survNRI(time  = "time", event = "status",
    : |# l3 r. X# b9 V6 i        model1 = c("age", "bili", "albumin"), # 模型1的自变量, c" h* Q. e& j3 W  q5 ]! K
            model2 = c("age", "bili", "albumin", "protime"), # 模型2的自变量3 |% h7 [' h1 N& |
            data = dat, . Y4 U: N, H" A/ {
            predict.time = 2000, # 预测的时间点
    ; ^; S' Y* y, W5 y: n! ]) k) [5 o        method = "all",
    : i, h4 N4 h3 K# r7 \- h        bootMethod = "normal",  
    9 m% U6 Q2 m1 c2 A1 p, V9 }( P        bootstraps = 500, % ^, N+ Q& n) B. v, Y
            alpha = .05)- j: n. _" z- {) o
    7 ^0 o5 |4 K7 C0 N0 r% E
    1+ y: V; ]. ]3 Y2 L' ^7 ^
    查看结果,$estimates给出了不同组的NRI以及总的NRI,包括了使用不同方法(KM/IPW/SmoothIPW/SEM/Combined)得到的结果;$CI给出了可信区间。/ o  I* e/ S) d, o  M

    $ `0 {" I) M: X& I$ Y8 Sres
    0 \. g7 v4 X4 a" r' C# i1% |' e5 z* `- Y' O- V8 i
    ## $estimates4 T' m' v2 z5 Y( R/ A! N
    ##            NRI.event NRI.nonevent       NRI
    & v/ x; L+ j* ]1 r## KM        0.20445422    0.3187408 0.5231951: R; R' a2 Q( f* h: Z' U& f
    ## IPW       0.22424434    0.3273544 0.55159876 X: g) \+ q0 ]0 l( y. D' e
    ## SmoothIPW 0.19645006    0.3144263 0.51087637 I( [/ ~- b4 U" r7 R- k, W
    ## SEM       0.07478611    0.2632127 0.33799882 K# C: B$ Z* A( h7 I0 V3 z
    ## Combined  0.19633867    0.3143794 0.51071813 c+ d- R0 V7 O( _" J
    ## ) @- E/ h2 @; E& K- m
    ## $CI
    ) j4 s: X5 t; a( K3 _  H4 W## $CI$NRI.event
    3 K" i3 g$ a0 R##                     KM         IPW   SmoothIPW        SEM   Combined* F$ J( w1 b5 A# N5 a; {6 T4 }
    ## lowerbound -0.03915924 -0.02185068 -0.04724202 -0.1162587 -0.04737239 M$ k- ]1 P1 b* u
    ## upperbound  0.44806768  0.47033936  0.44014214  0.2658309  0.44004962 M, g* h/ z2 j. P( b6 M( F
    ## 2 C# |% ?& _3 P& q0 x
    ## $CI$NRI.nonevent( W# D7 G! W% u/ K& T) f
    ##                   KM       IPW SmoothIPW        SEM  Combined/ W" y3 f) L+ o2 a+ x3 t4 B4 s
    ## lowerbound 0.1317108 0.1396315 0.1286685 0.08638933 0.1286426: _' W+ _. T+ z
    ## upperbound 0.7102251 0.7393216 0.6966341 0.51482212 0.69645496 i; G# P  y. [4 M: {
    ##
    " q2 @4 u3 u) v1 o2 e! @! d6 G## $CI$NRI
    ) |1 I) i" p. u' O, K2 H##                     KM         IPW   SmoothIPW         SEM    Combined
    7 z+ B: o+ r+ |; X4 r+ O/ Q; x4 S4 N## lowerbound -0.05112533 -0.04569046 -0.05439863 -0.04132364 -0.05443409
    ; R3 a: Q4 F4 E+ R- S9 H8 q## upperbound  0.89306122  0.92464359  0.87970125  0.64253510  0.87953153% H5 T% s" e0 f: M9 L1 s
    ##
    2 W& C4 @' j0 N##
    5 a) m/ C5 U  `4 M" R( o2 S( \% c; D## $bootMethod8 z5 ^: w4 N8 B- a; j& ~: s
    ## [1] "normal"
    : {% P- Q2 H; u& o## ( \7 [, V  ^* z( {3 S3 f
    ## $predict.time
    # ]7 x2 t& X. T7 v6 M; `  X## [1] 2000
    ! ]' |* F0 W5 [: J( E- ^5 \" n## 6 C4 w7 F' X, A& F! e- q$ G
    ## $alpha9 }- p' G; S/ g
    ## [1] 0.05
    4 c9 P9 l( Q; I0 r- @##
    8 V, t- ~) y) {3 Z4 x  V0 z## attr(,"class")
    9 e0 I- L8 x+ [; B## [1] "survNRI"
    3 n( m/ `& P9 M$ D  d) i2 q8 Y1 |2 k- L% L  W, |& l2 k
    17 J! b! r+ M, H) C1 h+ V$ o
    OK,这就是NRI的计算,除此之外,随机森林、决策树、lasso回归、SVM等,这些模型,都是可以计算的NRI的,后面会继续介绍。大家如果有问题欢迎在评论区留言。5 q  E+ _( u, x# E' D

    0 p$ r) k* `3 C% w# X0 V: v  j/ e本文首发于公众号:医学和生信笔记" Z# t3 B& S* D  G- z% {3 t" e  B8 d
    - t3 F8 \+ t/ z" K/ K5 a
    “ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。9 z1 a; r+ O5 u5 d$ I% @8 @
    本文由 mdnice 多平台发布6 Y. `* d- {" h/ S
    ————————————————8 ]* D3 n4 N! `
    版权声明:本文为CSDN博主「阿越就是我」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。8 Q. J) q; I9 j. F6 u* C
    原文链接:https://blog.csdn.net/Ayue0616/article/details/126768006
      M6 ]) i! |: I* G& d0 r& n3 M, {4 ~4 f; C8 {$ a2 L4 n
      G3 Y5 A7 G& o
    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-8-24 04:54 , Processed in 0.355513 second(s), 51 queries .

    回顶部