QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3021|回复: 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
    8 @: k& O7 n- ~) {7 X
    净重新分类指数NRI的计算
    6 G8 E, \  g1 \; L9 r, q/ |- x& `“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。
    1 z0 J* Z% J' k3 ]( dNRI,net reclassification index,净重新分类指数,是用来比较模型准确度的,这个概念有点难理解,但是非常重要,在临床研究中非常常见,是评价模型的一大利器!: s( H2 i- n% E( [
    1 h4 J( h8 j0 p4 Z
    在R语言中有很多包可以计算NRI,但是能同时计算logistic回归和cox回归的只有nricens包,PredictABEL可以计算logistic模型的净重分类指数,survNRI可以计算cox模型的净重分类指数。3 U  S( r+ E  u) {8 x

    $ B! c; O' v$ ]4 b  L( T! Ologistic的NRI+ M0 _# f, _4 D, o3 h3 W: Z) L
    nricens包! H. @3 [8 l) k9 n1 V6 Y
    PredictABEL包
    0 N2 p$ ]$ k) H( A' g& j3 }& w生存分析的NRI
    5 c5 M* Y+ L4 {( I4 knricens包' B5 L' s1 d: i& L% j
    survNRI包5 N: X4 u4 }+ |  X: u$ L; ^# {! l. d1 P. t
    logistic的NRI
    7 L# q/ M0 C& C. r$ [2 Y$ Qnricens包
    : o! ~+ Z) a9 k! w% d- g( k#install.packages("nricens") # 安装R包& }- r! l# r4 f/ V! g( G, y  Y
    library(nricens)
    ; S1 U$ ?6 S4 E1' y4 B5 D- c! Z$ ~$ w7 I, Y
    ## Loading required package: survival: b5 N9 Z* t  g
    1; V& U) g) j& U$ v( c' S6 @0 E& g7 i
    使用survival包中的pbc数据集用于演示,这是一份关于原发性硬化性胆管炎的数据,其实是一份用于生存分析的数据,是有时间变量的,但是这里我们用于演示logistic回归,只要不使用time这一列就可以了。6 z0 c5 A  d3 B' v, _* W3 N& \
    9 ~5 X" ~% B* @; u1 R
    library(survival)
    5 B# @: W1 [4 j2 W
    / V" e' j& e5 U7 h) B& R' a# 只使用部分数据
    ' m! Z6 O' `# ]4 e$ b8 E* h! gdat = pbc[1:312,] ! U# W3 }: |# y! ~: ^- n3 T
    dat = dat[ dat$time > 2000 | (dat$time < 2000 & dat$status == 2), ]9 N0 I/ X( C: o) j

    . T2 N, r# }) x- d" |+ jstr(dat) # 数据长这样
    1 {) E8 _5 i0 r% \4 \1
    3 H2 _. I) z/ U! c. k4 M## 'data.frame': 232 obs. of  20 variables:
    : C: N' d% `' G6 e3 A  A& i##  $ id      : int  1 2 3 4 6 8 9 10 11 12 ...
    $ a1 T4 m/ X: m: `9 S##  $ time    : int  400 4500 1012 1925 2503 2466 2400 51 3762 304 ...
    2 \6 c. R% r& v9 ^2 I##  $ status  : int  2 0 2 2 2 2 2 2 2 2 ...
    " l" ]- j. R- J0 z5 r##  $ trt     : int  1 1 1 1 2 2 1 2 2 2 ...+ L, Z. j/ o. `- i
    ##  $ age     : num  58.8 56.4 70.1 54.7 66.3 ...
    5 h# A) l$ _; ~; r5 Z: n##  $ sex     : Factor w/ 2 levels "m","f": 2 2 1 2 2 2 2 2 2 2 ...
    0 F0 N, A; A/ f" d* V5 c( V  m##  $ ascites : int  1 0 0 0 0 0 0 1 0 0 .... v. {/ P3 I( b3 C% [- B4 h  x
    ##  $ hepato  : int  1 1 0 1 1 0 0 0 1 0 ...& E8 M3 b, E, I- n* C
    ##  $ spiders : int  1 1 0 1 0 0 1 1 1 1 ...
    7 @9 q' t& i- L$ }1 P6 ?##  $ edema   : num  1 0 0.5 0.5 0 0 0 1 0 0 ...
    7 Y& s" R0 u- k' r##  $ bili    : num  14.5 1.1 1.4 1.8 0.8 0.3 3.2 12.6 1.4 3.6 ...
    , V0 C8 n$ {6 E- q9 q##  $ chol    : int  261 302 176 244 248 280 562 200 259 236 ...
    4 g& s* g, G. r0 y3 k; e##  $ albumin : num  2.6 4.14 3.48 2.54 3.98 4 3.08 2.74 4.16 3.52 ...: c- ?5 F# U+ H% P" w. v
    ##  $ copper  : int  156 54 210 64 50 52 79 140 46 94 ...
    3 w# A' F6 Z% f# x0 I, o9 [##  $ alk.phos: num  1718 7395 516 6122 944 ...
    $ E  Q: Z3 |5 h# L9 T% i7 [##  $ ast     : num  137.9 113.5 96.1 60.6 93 ...$ M0 i" u' T2 u& P2 a; j
    ##  $ trig    : int  172 88 55 92 63 189 88 143 79 95 ...: }# `' u$ I* p; _- g+ w3 F
    ##  $ platelet: int  190 221 151 183 NA 373 251 302 258 71 ...
    2 X* F: g5 t6 h/ A; H##  $ protime : num  12.2 10.6 12 10.3 11 11 11 11.5 12 13.6 ...
      |- J7 [+ I) `0 {##  $ stage   : int  4 3 4 4 3 3 2 4 4 4 ...- A+ {# J4 f+ P4 a) T2 ?

    ) d" P- {- o1 N: g% l' i8 d1# T. I/ f! p) ?& w/ e4 }" G5 J
    dim(dat) # 232 20. n/ I  G3 o" m3 A8 E; B# Q4 B. @) ~
    1
    + ^! D' Q6 ~) u8 @; g3 Y## [1] 232  20' \& n; `9 F8 z2 F
    1
    0 s: x9 M9 a* z& {$ S# A然后就是准备计算NRI所需要的各个参数。
    4 O: ?  E+ K# }% u7 X
    1 X% m# B4 R4 `) {. A# 定义结局事件,0是存活,1是死亡5 G4 W; U. e# r. |5 B) a
    event = ifelse(dat$time < 2000 & dat$status == 2, 1, 0)/ Q% r. E& g4 l& O8 U4 s, h

    1 |) [$ i4 q% a7 w) R/ y2 A% X# 两个只由预测变量组成的矩阵
    , v: d7 h9 e" L1 l' ?z.std = as.matrix(subset(dat, select = c(age, bili, albumin)))
    1 A7 W; [& s9 ^7 D/ Q2 G+ hz.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))( h" n/ _9 Q/ ]7 |7 B# m1 I

    ! X$ y. j0 m% M# T2 C; ~6 L8 L+ Z: R# 建立2个模型
    : L, \2 }3 ^, N4 A* p& ]mstd = glm(event ~ age + bili + albumin, family = binomial(), data = dat, x=TRUE)% Y. t5 q. ?) T! f7 M, ]6 R3 x7 ^
    mnew = glm(event ~ age + bili + albumin + protime, family = binomial(), data = dat, x=TRUE)
    ' q/ f6 F7 o" Q
    6 l. j; k5 w- y" x4 s( a) u# 取出模型预测概率5 R% M" l* B( y5 Q+ E
    p.std = mstd$fitted.values3 R4 f: D  W; z3 j/ b
    p.new = mnew$fitted.values
    / f( Z) [/ r3 K8 M- n/ L  c. ]1 ]
    ! a: H( x3 X+ ^- l* F1
    - u2 N9 A2 ^$ w  z* V然后就是计算NRI,对于二分类变量,使用nribin()函数,这个函数提供了3种参数使用组合,任选一种都可以计算出来(结果一样),以下3组参数任选1组即可。 mdl.std, mdl.new 或者 event, z.std, z.new 或者 event, p.std, p.new。
    ) {8 f% @9 X- ^! |; ~$ r
    9 p5 _( i5 z) }+ P0 B# 这3种方法算出来都是一样的结果
    . {! l+ q! U. q7 U: V& C4 i  R$ f
    % V/ D% w# p" D5 F; P6 n4 ^* G# 两个模型
    ) m! x3 p& d# k; M: Xnribin(mdl.std = mstd, mdl.new = mnew,
    3 r5 |4 X! d) C( B$ @  V1 L       cut = c(0.3,0.7),
    - Z0 v& x, Q/ I( I( B2 u# s       niter = 500,
    9 _) H5 b# l4 E6 @% z( o       updown = 'category')* c' z( U3 n( \- _7 q

    / q! d7 p! I0 I1 S/ j- y* Y# 结果变量 + 两个只有预测变量的矩阵8 _$ y/ i$ B2 ~/ i9 V
    nribin(event = event, z.std = z.std, z.new = z.new, : s/ J* D- b! ^2 w4 [
           cut = c(0.3,0.7),
    . |$ J7 `% W5 t7 O: v       niter = 500,
    " e: D$ A/ R$ @- K       updown = 'category')- t# G& \$ K; d( G5 x% _

    : [1 N' S# ]" U% |## 结果变量 + 两个模型得到的预测概率4 \6 F) b1 h( z
    nribin(event = event, p.std = p.std, p.new = p.new, ) ], X" R. _' b8 W) l
           cut = c(0.3,0.7), / `" W. Z/ f5 N2 U* Y. ?% J
           niter = 500,
    " ~# ?% M: J$ K( q6 A0 o6 [# ?; u       updown = 'category')2 ?, T2 d! m+ m' G

    $ R; F5 d$ f% u& w, ~- a' r4 L1; k2 y; A3 D9 E  @. Q" J0 Q2 X
    其中,cut是判断风险高低的阈值,我们使用了0.3,0.7,代表0-0.3是低风险,0.3-0.7是中风险,0.7-1是高风险,这个阈值是自己设置的,大家根据经验或者文献设置即可。
    2 L5 t3 N7 r5 Z. ~: s
    5 H1 s; U( K  p& V* tniter是使用bootstrap法进行重抽样的次数,默认是1000,大家可以自己设置。
    9 U, g6 @5 C5 i8 Q7 Q0 w4 O* f. N4 P
    ' e9 B. t7 H  C; i. J8 n0 uupdown参数,当设置为category时,表示低、中、高风险这种方式;当设置为diff时,此时cut的取值只能设置1个,比如设置0.2,即表示当新模型预测的风险和旧模型相差20%时,认为是重新分类。; ~$ O) K' v) E0 e; ^, U7 e: A
    * S" g/ C1 V3 s
    上面的代码运行后结果是这样的:5 y/ a' v% J  g2 U. d4 {

      Y* n7 [% N6 j" u  P0 a- eUP and DOWN calculation:
    - s: {* T4 o! I; C0 r  #of total, case, and control subjects at t0:  232 88 1443 ]( }. |6 Q) z. z; v7 r' J& S

    9 L% U0 w* @, y. |# v: M  Reclassification Table for all subjects:8 s7 G+ g& z3 q% u1 J+ n" v6 t# O/ }
            New% K2 I* O8 Q% J; t, C  F) y
    Standard < 0.3 < 0.7 >= 0.7" `& {, l/ u- B
      < 0.3    135     4      0
    8 ^; f% q+ I! C" _# G1 Q' \3 X  < 0.7      1    31      4& q! z6 d) K; ]& `  [! g/ Z8 a+ T( z
      >= 0.7     0     2     55
    6 j3 r0 l* ]7 ?% s0 |6 C' K: m
    " A* e) g0 _6 o. [  Reclassification Table for case:
    $ I" Z% R9 D$ w( E# m3 I        New  w; M* W6 f6 X: O5 ?
    Standard < 0.3 < 0.7 >= 0.7
    1 d9 |6 ]) [' T/ P; x3 E  < 0.3     14     0      06 U! \; Z1 ^1 }8 }7 A
      < 0.7      0    18      3; p' q3 u! n2 V
      >= 0.7     0     1     52
    5 z" m* S% i% ^. W6 C. X3 u. C# ]2 k+ c7 n
      Reclassification Table for control:6 K' N6 P5 F& {# Z7 r' g4 A* r# u
            New( `5 C' y+ R: m# v/ \% G
    Standard < 0.3 < 0.7 >= 0.7
    : n  R4 P# x. }" N0 a3 T  < 0.3    121     4      0- M8 N) @, M$ K  r
      < 0.7      1    13      1' h& ~7 u1 A6 ~
      >= 0.7     0     1      3- k' @; W& T2 D- N0 n

    / n# j% x8 x; i/ E! ~NRI estimation:9 E4 a2 Y$ l1 b. }, p6 R
    Point estimates:  c3 q$ f. W: F
                      Estimate/ v( k( L5 Z$ o" Q4 T2 X
    NRI            0.001893939
    8 W( l4 J; n% R6 ~$ A" h1 j6 eNRI+           0.022727273" l/ Z" T/ h2 e0 y" i8 X
    NRI-          -0.020833333. n4 M. e/ s. x9 {! ~0 b9 H5 o
    Pr(Up|Case)    0.034090909
    ! t; N) M- ]7 gPr(Down|Case)  0.011363636% p- J1 X2 I# z0 u
    Pr(Down|Ctrl)  0.013888889
    ; g4 {6 j5 {. W3 z# cPr(Up|Ctrl)    0.034722222
    / E8 P( m, M; l: ?8 y( X. a
    % W+ g$ U* R" eNow in bootstrap..1 {. @# ?, P" ?3 W

    8 i; y# z+ `7 QPoint & Interval estimates:: R" q( W% v$ \, U
                      Estimate   Std.Error        Lower       Upper3 G) `6 i: z; _8 K2 |+ [2 ^
    NRI            0.001893939 0.027816095 -0.053995513 0.055354449
    3 T+ q% D" i0 U# h7 X$ ENRI+           0.022727273 0.021564394 -0.019801980 0.0657894745 [  }" w5 y# t, i( Q
    NRI-          -0.020833333 0.017312438 -0.058823529 0.007518797$ m  `& e& I7 Y) Z& c5 R
    Pr(Up|Case)    0.034090909 0.019007629  0.000000000 0.0721649488 }2 ^* R2 b( k; T. D) X
    Pr(Down|Case)  0.011363636 0.010924271  0.000000000 0.039603960
    % O$ M, R. T" R7 t0 KPr(Down|Ctrl)  0.013888889 0.009334685  0.000000000 0.035211268
    4 e  {4 z; n) k: D: P; ~, F% J/ gPr(Up|Ctrl)    0.034722222 0.014716046  0.006993007 0.066176471% @5 R5 N4 E$ _" Y9 ?  Y2 @! h

    2 a& I1 ?; E8 {9 ~1
    % r& t! P2 z$ ], _首先是3个混淆矩阵,第一个是全体的,第2个是case(结局为1)组的,第3个是control(结局为2)组的,有了这3个矩阵,我们可以自己计算净重分类指数。
    3 L+ r3 v$ @1 j. S8 G' ~% r! U7 x. E) j
    看case组:
    . z7 F+ y5 J0 [6 B6 w0 Q( f1 f  M7 h. d- }) g- y  W3 K# t; W" s
    净重分类指数 = ((0+3)-(0+1)) / 88 ≈ 0.022727273, T: k& H  t. \. j! T3 A& a" A

    # g" z! J0 S* B8 g, h8 m再看control组:
    ' ^) w4 t% p1 H7 R3 t# N2 y& _0 O) B+ ?0 Z6 ^2 s/ U# Y' v4 s# Y# u
    净重分类指数 = ((1+1)-(4+1)) / 144 ≈ -0.020833333' x, D. M/ q2 a- s% [+ B: L3 N
    ( T( b; H& y& W- I& Y5 \
    相加净重分类指数 = case组净重分类指数 + control组净重分类指数 = 2/88 - 3/144 ≈ 0.000315657
      X2 H$ \5 g1 l, l# D7 g3 X  ?; i3 ~" a0 h, {; k+ J
    再往下是不做bootstrap时得到的估计值,其中NRI就是绝对净重分类指数,NRI+是case组的净重分类指数,NRI-是control组的净重分类指数(和我们计算的一样哦),最后是做了500次bootstrap后得到的估计值,并且有标准误和可信区间。% v4 W( H$ W' u
    1 i( u  Y/ a  y4 @; v! i
    最后还会得到一张图:
    * g6 B7 f1 x. u9 m3 D8 ]
    , C+ W3 N' X/ B这张图中的虚线对应的坐标,就是我们在cut中设置的阈值,这张图对应的是上面结果中的第一个混淆矩阵,反应的是总体的情况,case是结果为1的组,也就是发生结局的组,control是结果为0的组,也就是未发生结局的组。, Q6 {' u* ^4 m6 U
    * I* M; G( |' c+ @3 L# b3 \
    P值没有直接给出,但是可以自己计算。9 U! M# s+ I7 R4 Y

    ; v- i# C; T  w7 i8 u! R# 计算P值" Y6 r5 B7 j+ |: k0 f; H
    z <- abs(0.001893939/0.027816095)
    6 t' J5 a( ^( sp <- (1 - pnorm(z))*25 o1 ^# X! A0 u' N2 \, ?
    p% Y& |* [# l. ^+ j
    1  f8 x: L8 Y, {
    ## [1] 0.9457157: @7 h: U7 K9 l: z$ d3 d; m# u
    1
    2 l; h8 p0 P0 c6 X: k  Q* YPredictABEL包. K& U/ p& _$ s5 m" B
    #install.packages("PredictABEL") #安装R包
    1 i; Q1 O! X, u5 U% a& ]! blibrary(PredictABEL)  
    4 @. K) l# E. ~7 z! m
    ! c0 `, I" ~4 _5 F# U# 取出模型预测概率,这个包只能用预测概率计算! \! o: l3 |* f4 v# \  k, x. L  \
    p.std = mstd$fitted.values
    / \0 A+ K  ^+ l% j- f! y: e/ B1 kp.new = mnew$fitted.values
    - R1 E% M0 A. O$ \0 C1
    ' F* J2 \, ?0 \( S然后就是计算NRI:& H! R; |+ U% ~3 N- \9 b8 n( v( S4 v3 w

    . P2 H+ m6 V5 Qdat$event <- event
      Q5 x2 F) O# ?; ]2 A" y$ w; `. a; x+ o, D! B  P& p1 U) n+ C
    reclassification(data = dat,: ]7 d* m, r9 ]+ ?5 ?) Y# \
                     cOutcome = 21, # 结果变量在哪一列
    1 p. ~& y. ^% @( q* B8 {+ t                 predrisk1 = p.std,
    + e) V. O* z5 _                 predrisk2 = p.new,
      i3 V) R: l3 M                 cutoff = c(0,0.3,0.7,1)
    + W! H$ l% t+ x( D5 v                 )
    : x  m6 U7 o8 [9 U/ O1
    / k" v9 Z: K( m' Z# M$ @# o. C##  _________________________________________9 w& y- O) x3 M' x/ \- A" ^
    ##  
    / `  v$ i0 M: u" O' K8 o7 [##      Reclassification table   
    , a/ `- v/ I7 h$ b* r##  _________________________________________5 f# I9 S% l1 q, Z# o
    ##
    " s* ^# V6 n" A0 e, b* n0 X##  Outcome: absent
    ; _$ D+ v$ d8 o6 S! l. d" z##   8 k; G  f& b& E9 ~- t
    ##              Updated Model
    0 o) k! W# E$ Q2 o; O: W7 T5 P2 i5 t## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified+ ^2 Y; K5 H  c7 b
    ##     [0,0.3)       121         4       0               3
    - q# j  W4 E, _3 i" a. n. K##     [0.3,0.7)       1        13       1              13  O# X/ t) w4 q5 v
    ##     [0.7,1]         0         1       3              25
    ( U# ?% A9 u3 v. \* K* b4 t5 @##
    3 d2 J0 ?! V  i/ I##  
    , O1 i9 L# l# B% L! U4 @##  Outcome: present
    + L- z$ d" H0 u0 M0 O6 A##   
      P3 T" r0 k6 U" ]##              Updated Model
    ' @9 U( R! |- z5 m## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
    " F9 ^# Z- C- u4 y##     [0,0.3)        14         0       0               0
    ' q! H# ?; l3 R, Q+ b) y##     [0.3,0.7)       0        18       3              14
    . {) E7 ?  P9 x9 ]+ W- a5 Q, ^##     [0.7,1]         0         1      52               23 R) z. v+ ]. A) a/ l7 U
    ##
    * B: h* I3 M5 k4 H7 a# h0 U##  
    - `/ i1 R2 m% p( L9 C0 z! V##  Combined Data
    1 @6 M! Z4 {& Y( T7 R5 P6 d( J2 ^##   8 M1 h) C- `. u' C
    ##              Updated Model7 T1 f& Z8 }  F8 N
    ## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
    6 U) G) ?7 {8 d3 h8 B8 ?! ^##     [0,0.3)       135         4       0               3
    - r3 i  K, d# y, f3 D3 p1 d% F. }' t##     [0.3,0.7)       1        31       4              148 z+ b& }* o" L" C
    ##     [0.7,1]         0         2      55               4- F. Y( j& K$ q
    ##  _________________________________________% I8 j- n( _( j* z  i
    ##
    3 J7 J1 A" n' ~# R" L5 u##  NRI(Categorical) [95% CI]: 0.0019 [ -0.0551 - 0.0589 ] ; p-value: 0.94806
    ; U7 ~9 ]1 _# K! J: [##  NRI(Continuous) [95% CI]: 0.0391 [ -0.2238 - 0.3021 ] ; p-value: 0.77048 ! b' {! o* D, |% n) O% t" {
    ##  IDI [95% CI]: 0.0044 [ -0.0037 - 0.0126 ] ; p-value: 0.28396& `. }' O! o1 w+ i
    ' `* R) ?3 H5 y! ]; [1 I
    1
    6 _2 v0 ^4 z8 L% T结果得到的是相加净重分类指数,还给出了IDI和P值。两个包算是各有优劣吧,大家可以自由选择。3 J' U& k3 m- ~
    % ?& @- v/ b3 }* |
    生存分析的NRI
    * H3 T3 T/ x  H/ g. r. H还是使用survival包中的pbc数据集用于演示,这次要构建cox回归模型,因此我们要使用time这一列了。
    * _* [% G# f* v, \; p! v  }1 |) D' W# s  w! x2 u0 Y( {
    nricens包
    & N) \+ t/ U; z  k1 \6 clibrary(nricens)
    1 x" x! v( m9 \& L6 Hlibrary(survival)
    & v7 e, |2 Y4 M/ |
    5 a) Z5 n2 H( D) @5 ^dat <- pbc[1:312,]
    - C3 ^1 F* `3 v( y6 g" A6 Tdat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡
    4 E% \# i( l: f; S+ ^" m$ F1
    ; k7 X: e9 ]; Y7 j, ]然后准备所需参数:
    * n" q3 @4 f# o. y6 n$ A  f, _+ d: Z% u1 V: b/ M- Z7 S
    # 两个只由预测变量组成的矩阵! O' u: E4 g5 H! o) G7 o% }9 A1 ]
    z.std = as.matrix(subset(dat, select = c(age, bili, albumin)))
    3 i1 U$ r' Q1 W+ P6 \, Dz.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))
    1 f0 m8 {, E& w2 V3 F, {) d% ?% m; b' }$ i7 V. }, }, ?: c3 F
    # 建立2个cox模型5 ?# @/ X( c3 i' i& @
    mstd <- coxph(Surv(time,status) ~ age + bili + albumin, data = dat, x=TRUE): P$ i- q7 |9 f6 C) U
    mnew <- coxph(Surv(time,status) ~ age + bili + albumin + protime, data = dat, x=TRUE)
    6 f5 ?+ j5 [/ i
    / r) C6 B+ S8 s8 I8 \# 计算在2000天的模型预测概率,这一步不要也行,看你使用哪些参数. M; P- x2 N' H6 p  w7 D$ P
    p.std <- get.risk.coxph(mstd, t0=2000)/ P  x& Z/ j( X6 R7 U
    p.new <- get.risk.coxph(mnew, t0=2000); J2 q0 n7 y; }$ i
    1  g7 V# r3 T1 [+ m$ {
    计算NRI:
    - D3 D% K. O$ ~- n- J5 e) [0 m; o" ?9 C3 J
    nricens(mdl.std= mstd, mdl.new = mnew, ! u' M  I  I) F: E8 N0 {, L3 x" c. h: `
            t0 = 2000,
    # A5 t- u5 U  H" Q/ K" `        cut = c(0.3, 0.7),
    / r8 c7 Z- n+ J        niter = 1000, 7 ?4 b9 D' l) J  B* m& U
            updown = 'category')
    / g8 z4 ^& F: G9 O" t; S* {' `% ^" e' G+ r. j: r+ r( o
    UP and DOWN calculation:9 l2 D4 U% v9 O; ^( y  e4 ]6 c& O
      #of total, case, and control subjects at t0:  312 88 144
    $ c$ Z1 f1 [2 L$ X
    * x8 w4 T9 H% l  P) |  Reclassification Table for all subjects:: D* v% P& ]4 Z
            New
    ; B2 N- W* _, L. @' _# W5 `Standard < 0.3 < 0.7 >= 0.7
    5 c' _( @" t0 g  m* E& v0 \  < 0.3    202     7      0
    . \& k' m; W& `" Q  < 0.7     13    53      6
    2 h% j8 Y$ O5 [' u  >= 0.7     0     0     31
    ( N$ M5 ~% V0 k/ \% ^9 L5 Z4 d! A, N1 Q
      Reclassification Table for case:* a4 F+ f; J) \; q
            New, k& R1 ^; i; n# o5 e
    Standard < 0.3 < 0.7 >= 0.7
    - q9 G" u4 H3 T% r% A  < 0.3     19     3      0
    ' Y2 o+ U. `% ?9 y6 v" E  < 0.7      3    32      4+ f# F( i, E: y3 S6 E5 a1 s
      >= 0.7     0     0     27
    " b; I+ B, A/ }5 p7 Z+ Y0 F; k/ |6 M5 ]' m. q9 H% @3 Z9 |7 d1 e7 ]
      Reclassification Table for control:2 d8 m% r! K; E0 B8 L' W
            New
    ( l4 q8 R! f- I. w% }/ zStandard < 0.3 < 0.7 >= 0.7
    / k, e+ M# ~4 d3 c8 c  < 0.3    126     3      0
    3 W" Y. [# s& M* H( K7 r  < 0.7      5     7      2
    2 N( {8 F; l' y6 _5 A1 N; m8 j  >= 0.7     0     0      1% E' _9 y9 p/ _! e% }" u) E4 i
    4 ]6 e' _9 W& }* k* ]; ^
    NRI estimation by KM estimator:& k# ~$ ?* z0 ^% j( E
    " j! j5 ]' G% z0 T$ T6 m
    Point estimates:
    ) J9 D, T1 o" f2 m& R. _5 A                Estimate
    4 H3 l5 L. n4 k4 S5 I/ |NRI           0.05377635  M6 s  u3 o$ N* d5 P
    NRI+          0.03748660
    3 J/ |8 G, O' Q5 b' hNRI-          0.01628974$ H) A3 O# X+ b, s% A" w; z
    Pr(Up|Case)   0.07708938
    0 R- j" }2 [7 p, \) BPr(Down|Case) 0.039602789 X; z" P) f  _$ M$ z
    Pr(Down|Ctrl) 0.04256352' d9 X& A. {0 G( u- w0 f
    Pr(Up|Ctrl)   0.026273787 W, s0 V; h& @' k! Q' A! i

    * M7 J0 J7 G! q8 V% H" ENow in bootstrap..7 p4 T5 {5 k; C

    , z  ^( j+ Y$ G6 G0 kPoint & Interval estimates:: y* j0 [( b1 d1 v4 ]
                    Estimate        Lower      Upper0 y* \7 l4 b! @/ q
    NRI           0.05377635 -0.082230381 0.16058172* }; t. _+ Z5 g' j% }; _! c! _: G2 _
    NRI+          0.03748660 -0.084245197 0.13231776
    * C: o- V  h7 jNRI-          0.01628974 -0.030861213 0.067536166 Q' q6 u# A* u
    Pr(Up|Case)   0.07708938  0.000000000 0.19102291
    ; I  p% Z( N. U- Q- G2 ePr(Down|Case) 0.03960278  0.000000000 0.15236016
    0 P8 `+ S* |, c. ~Pr(Down|Ctrl) 0.04256352  0.004671535 0.09863170
    2 \! }5 Z" G3 w# h2 x$ g, B# H, X3 }# APr(Up|Ctrl)   0.02627378  0.006400463 0.05998424) G* I- z5 B0 {! C# l: M8 Y- k# |

    7 k) g7 Q% A* |# I' [1
      |0 P* s+ w3 s1 T8 `( i
    7 L, O3 B; g" g! D( c0 s6 l& r  }Snipaste_2022-05-20_21-49-38# P$ |% c& M0 Z9 p) A. m, h
    结果的解读和logistic的一模一样。
    5 b- {- U% z/ I- K
    6 `. e- S. u( VsurvNRI包
    - w1 o" u; W% T* Q8 ~# 安装R包
    3 r7 @7 S3 p% U, c: n5 zdevtools::install_github("mdbrown/survNRI")8 ^& J6 ?1 Q" l& V4 r9 D8 j
    1
    8 L8 B0 }9 L1 _( u' Q1 Y加载R包并使用,还是用上面的pbc数据集。! D' g" h5 }' @  e2 f/ `
    3 Z6 x9 j0 L" o0 [) O+ i2 A$ `# W) S
    library(survNRI)
    ' @0 o$ I: o# O4 _3 H! x6 q( C1) d/ N1 p7 W- g* k( n, m- a
    ## Loading required package: MASS
    5 [1 ?, n' T8 x! {7 }1; d: j' m  {6 u$ G
    library(survival)
    - T# z* r7 _( D* x, r# `& Y* W* @8 x( S! e' g' Z+ H7 r. |
    # 使用部分数据5 Y- h% t3 Y0 ^' @$ N" L
    dat <- pbc[1:312,]* q. S4 H- ~* C* M
    dat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡) S" J  O; Q/ r! h5 J
    ! ^5 |, X) B, a) Z- ~
    res <- survNRI(time  = "time", event = "status", $ L  k1 ~" z4 e1 b$ l
            model1 = c("age", "bili", "albumin"), # 模型1的自变量0 [) F# h3 g2 H$ ]2 h* X+ ?
            model2 = c("age", "bili", "albumin", "protime"), # 模型2的自变量1 w0 ]  c+ G+ ]7 r: J
            data = dat, 3 q7 ]- p. `. H# o! X1 t: r
            predict.time = 2000, # 预测的时间点& i0 N, E* }/ ~) }4 {
            method = "all", ; e6 N+ e/ \" W9 @
            bootMethod = "normal",  ( i& ?+ e; L5 D$ G8 T
            bootstraps = 500, ; _0 e" J2 x, Y; W  V. t+ q
            alpha = .05)
    7 K1 E4 T+ d; {5 i6 e  ^/ N- P  u, h" e5 y! g' z" W1 S* V$ }
    1, g4 Z5 ?7 o; @7 |0 b( \# M
    查看结果,$estimates给出了不同组的NRI以及总的NRI,包括了使用不同方法(KM/IPW/SmoothIPW/SEM/Combined)得到的结果;$CI给出了可信区间。1 I# L8 B- Z7 f3 O. G1 p" K. A) @
    ' X% Z8 `( _, S: [( \
    res
    0 O$ S+ H' }6 y7 F7 n( M* I17 s  U# t: c4 {- U
    ## $estimates
    5 ]+ y. t0 j6 f7 H9 C' Y##            NRI.event NRI.nonevent       NRI0 q: m) u) \$ Z
    ## KM        0.20445422    0.3187408 0.5231951. c8 V- w8 [0 l
    ## IPW       0.22424434    0.3273544 0.5515987' t8 V" E/ w7 A
    ## SmoothIPW 0.19645006    0.3144263 0.5108763! l& ]% u" |2 t! K3 n+ M
    ## SEM       0.07478611    0.2632127 0.33799884 W9 h' ^7 B! E
    ## Combined  0.19633867    0.3143794 0.51071812 p7 b1 o+ S" `$ Q$ k2 b$ R8 J
    ##
    & S  G& B( X! k$ Q## $CI9 H. a; e7 V2 [$ u1 @% {
    ## $CI$NRI.event
    - A/ I/ p7 D- M##                     KM         IPW   SmoothIPW        SEM   Combined
    7 l2 M2 `) A) X## lowerbound -0.03915924 -0.02185068 -0.04724202 -0.1162587 -0.0473723
    ( m2 T# w4 k. }: R, i. `6 g, ?; a## upperbound  0.44806768  0.47033936  0.44014214  0.2658309  0.4400496, {6 `( s9 i7 ~4 @% f& x
    ## ' c9 q+ r! t' L2 m8 U7 y
    ## $CI$NRI.nonevent% Y! M( O/ w7 J+ {) L
    ##                   KM       IPW SmoothIPW        SEM  Combined
    + g& N7 d* L* z* a! N7 b## lowerbound 0.1317108 0.1396315 0.1286685 0.08638933 0.1286426! L6 S0 m% Y; a9 g6 M
    ## upperbound 0.7102251 0.7393216 0.6966341 0.51482212 0.6964549
    1 N  h( h. I, z- d% x. {& r( I. M##
      a- o9 W# T$ n( [' M( ]## $CI$NRI
    9 s* i0 l, u/ L- Z##                     KM         IPW   SmoothIPW         SEM    Combined
    + y, ?. S. K9 g3 {" A0 F; n2 u## lowerbound -0.05112533 -0.04569046 -0.05439863 -0.04132364 -0.05443409; }4 X1 b; N5 z6 f. f7 A9 q* N2 a
    ## upperbound  0.89306122  0.92464359  0.87970125  0.64253510  0.87953153
    - v6 K$ @* p- G) Y  w## ( D' F7 t6 Q8 j1 r7 u4 v
    ## ( g( H. ]) Y2 ^) V
    ## $bootMethod
    * M' D& t, v* ^8 l## [1] "normal"* G% F" z. ?, W, H1 B" O( K' k
    ##
    6 I5 k: w- i, K, S. n## $predict.time
    0 K+ Q- M: m9 s## [1] 2000
    . ], `5 r: D% [, Z: Y& l## $ z" b1 d% `2 p
    ## $alpha
    ' s4 U( X' K4 i5 ~. K4 Q## [1] 0.05
    8 I/ E0 `* n5 H1 {& p## - D  r" n, ?' O. ]2 l
    ## attr(,"class")! N. b* ?5 g, F" K% R
    ## [1] "survNRI"
    8 E2 ]: s" L& H( U! F+ J" q2 k4 S
    15 |5 o7 _  Z4 U+ u& D1 t: L
    OK,这就是NRI的计算,除此之外,随机森林、决策树、lasso回归、SVM等,这些模型,都是可以计算的NRI的,后面会继续介绍。大家如果有问题欢迎在评论区留言。: y& L3 L2 A! v6 I
    6 l- ~8 Q) E  J. a5 f
    本文首发于公众号:医学和生信笔记
    1 x. I4 V% Z, L* Y# L: g# ^
    + c9 {+ T6 [- y, m* K- p“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。
      H. K6 G, ?$ \8 d$ @9 O本文由 mdnice 多平台发布
    7 T. h5 Q& u. N8 d; U$ b/ B$ X————————————————5 X% L. h' E' V( G
    版权声明:本文为CSDN博主「阿越就是我」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。7 l7 p# K) J9 t6 \4 ~& j* |
    原文链接:https://blog.csdn.net/Ayue0616/article/details/126768006) r2 c; ^" P) o2 ]" W4 y+ S
    ) U6 [# w& C$ f' e5 L) g8 b. `! h
    / \* h9 l! w/ m+ a3 J4 u
    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-4-12 19:58 , Processed in 0.584142 second(s), 51 queries .

    回顶部