QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3171|回复: 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
    ; B8 H; Z  R$ Z5 q1 q& q) d# F
    净重新分类指数NRI的计算3 F* `9 ^" p8 G) b' H9 b
    “ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。
    9 U2 F1 P6 a8 U  U9 u0 |9 tNRI,net reclassification index,净重新分类指数,是用来比较模型准确度的,这个概念有点难理解,但是非常重要,在临床研究中非常常见,是评价模型的一大利器!
    ( ~' R. u5 U' w( G* `9 x! {- w1 V9 K7 s" V2 x9 W2 q
    在R语言中有很多包可以计算NRI,但是能同时计算logistic回归和cox回归的只有nricens包,PredictABEL可以计算logistic模型的净重分类指数,survNRI可以计算cox模型的净重分类指数。7 A6 i! a  E$ M. A

    : c8 o. O# I! V- R5 J# [: ~8 Alogistic的NRI
    / X7 M5 {5 p1 w) e2 y& ?nricens包0 N% Q8 i+ C5 G6 b+ }
    PredictABEL包
    3 C' k* R* y, I" ]& h生存分析的NRI8 \8 @% P- `5 D6 k$ x0 t! P
    nricens包% }8 y% V7 n6 Z" u
    survNRI包; Y* H) S+ n- o1 a: m  N9 G9 [
    logistic的NRI
    * K2 S( o( _/ Snricens包
      K5 B7 A/ g0 ]( G* a1 ]% \1 F7 j#install.packages("nricens") # 安装R包0 }$ J+ c( h: }* M6 R: Z" A) F4 m0 r
    library(nricens)
    2 Z) W1 P% N/ |) f1
    ; H- J+ N- @, C## Loading required package: survival
    * c, f# n9 h7 a* t1( x& H- y( }* x2 W( p) p
    使用survival包中的pbc数据集用于演示,这是一份关于原发性硬化性胆管炎的数据,其实是一份用于生存分析的数据,是有时间变量的,但是这里我们用于演示logistic回归,只要不使用time这一列就可以了。- D4 k& R  M, ?$ b& @2 _! r% o
    & [2 g; _) ?/ q* Y6 N
    library(survival), L/ r* s8 I0 x" I

    ' k# g2 o$ R6 ?- G/ T( w* q9 ~# 只使用部分数据, b% m0 l  C* f( w5 \$ B
    dat = pbc[1:312,] 1 H, ]) C8 v: r: j- d" n
    dat = dat[ dat$time > 2000 | (dat$time < 2000 & dat$status == 2), ]0 B1 S+ h6 x- D3 s( N

    , K2 }5 b. C, ^( F) V0 |. e9 rstr(dat) # 数据长这样, E7 i. Y0 K6 s
    1# Y! I. o' m% v: N. T+ w' K
    ## 'data.frame': 232 obs. of  20 variables:
    ! c  h, o; S- v8 [##  $ id      : int  1 2 3 4 6 8 9 10 11 12 ...
    " y. [+ a$ a6 H* e##  $ time    : int  400 4500 1012 1925 2503 2466 2400 51 3762 304 ...% G  r* I" [4 P& Q
    ##  $ status  : int  2 0 2 2 2 2 2 2 2 2 ...
      U( s+ \$ x/ f# M, q) C##  $ trt     : int  1 1 1 1 2 2 1 2 2 2 ...
    + N% T+ r2 b, r. c& f: k# L##  $ age     : num  58.8 56.4 70.1 54.7 66.3 ...
    # s5 i0 L" H' F6 q7 d% p# G, [##  $ sex     : Factor w/ 2 levels "m","f": 2 2 1 2 2 2 2 2 2 2 ...
    8 j+ W- Y  W$ D5 l: _7 E##  $ ascites : int  1 0 0 0 0 0 0 1 0 0 ...
    + D; k) U' k7 X- q##  $ hepato  : int  1 1 0 1 1 0 0 0 1 0 .... P* ~6 P  X0 q9 G: ]9 X' K
    ##  $ spiders : int  1 1 0 1 0 0 1 1 1 1 ...- \4 b$ U  O" w( J4 i5 u* P) |
    ##  $ edema   : num  1 0 0.5 0.5 0 0 0 1 0 0 ...
    * l! I* Z2 T* O##  $ bili    : num  14.5 1.1 1.4 1.8 0.8 0.3 3.2 12.6 1.4 3.6 ...
    * B  }: V0 M0 l0 t2 Y/ c# \##  $ chol    : int  261 302 176 244 248 280 562 200 259 236 ...
    6 I' T" H- M5 t3 ~' p. v$ g( P  O##  $ albumin : num  2.6 4.14 3.48 2.54 3.98 4 3.08 2.74 4.16 3.52 ...  ?$ p0 z* h1 o( p
    ##  $ copper  : int  156 54 210 64 50 52 79 140 46 94 ...
    , a) F# F" r" W( C% z! o& `##  $ alk.phos: num  1718 7395 516 6122 944 ...
    3 F6 i* g7 s) C7 R% q8 C##  $ ast     : num  137.9 113.5 96.1 60.6 93 ...
    3 b* z7 u& w# o# z. \* s##  $ trig    : int  172 88 55 92 63 189 88 143 79 95 ...9 V6 d* X1 }: j1 L; x7 B3 u
    ##  $ platelet: int  190 221 151 183 NA 373 251 302 258 71 ...7 T" B0 T9 u9 Y4 q$ G8 M
    ##  $ protime : num  12.2 10.6 12 10.3 11 11 11 11.5 12 13.6 ...
    , t: V* c5 D0 w5 y. y##  $ stage   : int  4 3 4 4 3 3 2 4 4 4 ...
    7 O: w) r1 M+ `
    $ L  j9 L9 C1 P3 k: Z8 G1
    " i& U# N, W" f1 ~# [4 r; |dim(dat) # 232 20
    + W% K( w2 m* x8 @/ r" O/ c- W1$ W8 s8 k6 c1 l" H
    ## [1] 232  20' G/ T$ ]! @1 {4 [+ R* r. h" B" n
    1
    7 B: O/ {3 E- I" C4 K: E  @然后就是准备计算NRI所需要的各个参数。9 {) n! K: K' d3 Y" m7 i

      q  u! N+ K' D" `9 |# 定义结局事件,0是存活,1是死亡! R' B5 L2 T0 A3 F; H
    event = ifelse(dat$time < 2000 & dat$status == 2, 1, 0)/ w: N, w: y3 B# X! R! X! @3 L9 x) y

    2 V2 _* {3 K1 e( v  }" E& P# 两个只由预测变量组成的矩阵
    , N2 L/ D& S# W. yz.std = as.matrix(subset(dat, select = c(age, bili, albumin)))+ c" R8 }7 n; A1 \. _
    z.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))
    3 Y* H. o+ t9 S7 D& H) T2 k6 c1 l( F0 m, f) N* J. \
    # 建立2个模型
    ) w' A/ ~0 M. ~1 O( amstd = glm(event ~ age + bili + albumin, family = binomial(), data = dat, x=TRUE)
    ' G% o2 e$ f+ T, q* xmnew = glm(event ~ age + bili + albumin + protime, family = binomial(), data = dat, x=TRUE)
    8 y" y4 k. e' t$ O6 {; w9 Y2 M% {( m9 K! ?
    # 取出模型预测概率' b9 C' t- I' t, A- ]
    p.std = mstd$fitted.values
    : }. \1 w/ y. i( N* @9 r1 Op.new = mnew$fitted.values% U1 W. U- o2 V, c) m
    ; B* r7 ~( Q* E$ q  Y; K; v
    1$ A) P( E+ p8 d0 r4 A
    然后就是计算NRI,对于二分类变量,使用nribin()函数,这个函数提供了3种参数使用组合,任选一种都可以计算出来(结果一样),以下3组参数任选1组即可。 mdl.std, mdl.new 或者 event, z.std, z.new 或者 event, p.std, p.new。. d( j0 c8 O% w3 k
    $ D% x" `3 m5 J
    # 这3种方法算出来都是一样的结果- a" i$ i9 }& {) F/ j1 ~/ _. ]
    & g4 G) R5 e: q- @" K2 q5 p
    # 两个模型1 U4 m  P$ \  D! B
    nribin(mdl.std = mstd, mdl.new = mnew, % ?$ }. ~) ^( ]
           cut = c(0.3,0.7),
    : v8 o% b! O5 O+ s. w7 J       niter = 500,
    4 k; c/ _! ?! b# b; b       updown = 'category')
    2 d4 u- i$ E% V9 z2 d! U/ g. r- ^" K# A9 A
    # 结果变量 + 两个只有预测变量的矩阵/ Y; l4 t: z' H/ U0 [
    nribin(event = event, z.std = z.std, z.new = z.new,
    + l' v) N" U3 s! D/ q! ]       cut = c(0.3,0.7),
    ; P! x$ U1 h* l* r4 {: V" i$ ?; u       niter = 500,
    # N5 Y' u4 m& e       updown = 'category')
    ( }) D- F$ j8 y( P5 ~8 H9 k  ]8 U4 Q% g: G2 `7 [
    ## 结果变量 + 两个模型得到的预测概率! _) D* \! W/ @6 n. G3 R
    nribin(event = event, p.std = p.std, p.new = p.new, " s/ C8 z& t5 B$ e$ F
           cut = c(0.3,0.7),
    ( P' T$ `1 d. K$ y7 H( n       niter = 500, 6 O' w( l  o% p/ ^, R. d
           updown = 'category')9 I& f; H9 \: e4 C5 I
    ) z* \4 @5 F9 U$ l
    1
    2 q7 x  v4 A8 n* p: \5 S  b( h其中,cut是判断风险高低的阈值,我们使用了0.3,0.7,代表0-0.3是低风险,0.3-0.7是中风险,0.7-1是高风险,这个阈值是自己设置的,大家根据经验或者文献设置即可。  B4 D9 z4 p9 ~8 a$ B" Y/ ^

      x, A: S  q, X- a! m+ Kniter是使用bootstrap法进行重抽样的次数,默认是1000,大家可以自己设置。  i. p* g# H5 n' Q* [- \
    + C; W+ \0 [" ^
    updown参数,当设置为category时,表示低、中、高风险这种方式;当设置为diff时,此时cut的取值只能设置1个,比如设置0.2,即表示当新模型预测的风险和旧模型相差20%时,认为是重新分类。# h4 |6 z) v8 g6 j! ~! \4 p

    * m0 U7 a9 v% d5 Y+ C3 V  _上面的代码运行后结果是这样的:! b$ ?* A* G7 ~% f+ o, ^
      ~9 d/ t0 Z& F% a3 E
    UP and DOWN calculation:
    0 N5 K1 Z; ]- ~, T& S* `9 Z  #of total, case, and control subjects at t0:  232 88 1446 H0 x/ e3 ]3 v' K
    ; R+ z/ N" d- x0 J, S
      Reclassification Table for all subjects:  Y& n( Q* k1 F% a3 F
            New
    ( y4 T5 X0 B) V: I8 V( P9 B9 _9 `Standard < 0.3 < 0.7 >= 0.7. `9 S& l0 S. l
      < 0.3    135     4      0' }7 U- ?  I9 U2 J1 l% x
      < 0.7      1    31      4
    6 S% U9 i+ Q: W7 \9 M3 Z% i  N! z  >= 0.7     0     2     55
    9 s+ @% t+ U  W# V; Q% W8 R
    & s/ z, r; X% d$ f& g7 Z  Reclassification Table for case:% X0 O5 q) W. O
            New
    1 U4 I' e& R/ Y3 N! O+ nStandard < 0.3 < 0.7 >= 0.77 s: P; A& x* I6 S3 B. M) n
      < 0.3     14     0      01 \+ b6 W% G3 R  w& G3 _2 t
      < 0.7      0    18      39 S+ ~7 r6 t1 X3 g% S( }
      >= 0.7     0     1     52
    & R( C! \- ~2 m: Q  ~* A; U
    ; f. k9 L7 d2 r2 {+ X* T' a  Reclassification Table for control:
    3 [) u0 p7 b4 [9 I$ O, h6 H& Y* Y; C        New7 F3 ]1 _6 M2 [
    Standard < 0.3 < 0.7 >= 0.77 R7 q, s) {7 P' {3 n, D  F
      < 0.3    121     4      0
    7 k; F: T" i( \+ t1 A/ I  < 0.7      1    13      1  A4 `9 p+ V3 [% L' ]/ `+ I
      >= 0.7     0     1      31 k! e4 _' `9 o8 D. b

    6 t2 \) F* X9 p( z& Q5 j: m' INRI estimation:6 E2 a% m0 r0 m) v1 l- k, B
    Point estimates:
    5 M4 L- E2 |. m% I% P4 K+ x  `: j                  Estimate; Z" O0 @* ], y" E! r5 |
    NRI            0.001893939
    ) f8 Q0 }, ~& x5 L' ^! W- DNRI+           0.022727273: o: h1 v! ]/ Q% L8 l; d% S7 M# h
    NRI-          -0.020833333, P8 J9 K& |& z9 |2 ^3 p1 D
    Pr(Up|Case)    0.034090909
    ! E5 [. ?4 Q6 e7 C! j8 ~Pr(Down|Case)  0.011363636
    - v# z( c6 Z# O" m# yPr(Down|Ctrl)  0.013888889) D( B9 Z2 @$ l7 _
    Pr(Up|Ctrl)    0.0347222223 x1 L- S! K6 Z# f: s2 M; }# X+ w
      a7 q1 G- P" l* Y5 a  l5 ?) s
    Now in bootstrap.." B- Z0 f# b4 @' [

    . G4 Q; W  \, B2 jPoint & Interval estimates:
    + ]9 r9 m5 E1 J# w                  Estimate   Std.Error        Lower       Upper
    ) H( r$ G6 X5 F5 }/ W' N; D8 MNRI            0.001893939 0.027816095 -0.053995513 0.055354449
    , _# H, u- }1 l/ m) J* d1 xNRI+           0.022727273 0.021564394 -0.019801980 0.065789474
    ! r1 ^; X! K6 n1 x5 G3 ~0 O* B# ONRI-          -0.020833333 0.017312438 -0.058823529 0.007518797; b$ t, h, R/ x1 B6 ~- g2 g
    Pr(Up|Case)    0.034090909 0.019007629  0.000000000 0.072164948
    + \6 y6 _: l# b* ~; xPr(Down|Case)  0.011363636 0.010924271  0.000000000 0.039603960: N# W$ {% Z, r0 {* v0 G1 s! E3 R
    Pr(Down|Ctrl)  0.013888889 0.009334685  0.000000000 0.0352112686 G2 _' r3 Y" s( Q! w
    Pr(Up|Ctrl)    0.034722222 0.014716046  0.006993007 0.066176471( G: {4 b6 A& H% K

    ' d; Z) b) @5 r* h. U  N1# v: n4 C( [; Z5 N3 F9 K: l# D: {
    首先是3个混淆矩阵,第一个是全体的,第2个是case(结局为1)组的,第3个是control(结局为2)组的,有了这3个矩阵,我们可以自己计算净重分类指数。
    1 y( H- T4 f. S! D0 |0 w$ O% z5 \: x+ f; p$ v6 t0 o0 m
    看case组:. X9 ?7 z/ }' e5 B4 U
    5 d( S2 M) G% J2 L6 B9 t1 {" Y
    净重分类指数 = ((0+3)-(0+1)) / 88 ≈ 0.022727273
    5 t# {0 H3 ~# Y# E. }- L% K
    & |, L  e/ {" j! ^7 q, B再看control组:
    ' s2 d" @* V; J5 q
    % z+ @2 ]% V, R' P净重分类指数 = ((1+1)-(4+1)) / 144 ≈ -0.020833333
    . w. G' a1 f$ o# m
    7 ?1 Z/ v* @9 L$ |' F相加净重分类指数 = case组净重分类指数 + control组净重分类指数 = 2/88 - 3/144 ≈ 0.000315657
    / r) _! z2 D8 G4 s/ o: D
    $ l$ f0 k3 _( a6 U再往下是不做bootstrap时得到的估计值,其中NRI就是绝对净重分类指数,NRI+是case组的净重分类指数,NRI-是control组的净重分类指数(和我们计算的一样哦),最后是做了500次bootstrap后得到的估计值,并且有标准误和可信区间。
    5 m1 U' H; Y/ Q7 r# m- V; t- s7 S7 b
    最后还会得到一张图:- y( m) l( Z% s) U+ Y
      y! }4 H3 p) W0 @0 Y9 q! G& r/ F
    这张图中的虚线对应的坐标,就是我们在cut中设置的阈值,这张图对应的是上面结果中的第一个混淆矩阵,反应的是总体的情况,case是结果为1的组,也就是发生结局的组,control是结果为0的组,也就是未发生结局的组。
    0 y6 m& S# Z9 a2 O" O7 k
    9 D& n" o  K4 c8 E. qP值没有直接给出,但是可以自己计算。' \/ {7 P. X- R

    ' d) Z4 I' ~# g1 a; i/ ]# 计算P值* G9 s$ Y( p  V( l. k
    z <- abs(0.001893939/0.027816095), a. t; [' X2 P. j& C% ]' P
    p <- (1 - pnorm(z))*20 O7 j5 E, `1 b" |' N' K
    p
    / j0 g9 a$ Z* U1
    - w" V0 n/ k+ L7 J$ |## [1] 0.9457157- o5 f. V( Z2 ?
    1
    & P) G8 T8 u( r' ]9 _PredictABEL包/ ?" R$ b- ?, L; ^
    #install.packages("PredictABEL") #安装R包' u- M* u* O/ L7 {$ ~' z- d
    library(PredictABEL)  
    4 f! q: x$ I4 A( C7 e. {7 A5 g- Q) ?- }) T
    # 取出模型预测概率,这个包只能用预测概率计算; t# t7 t/ A- L5 ~/ n' V, y
    p.std = mstd$fitted.values- \3 o6 S: s! B  U- c7 M
    p.new = mnew$fitted.values , x$ t5 a2 h* D+ p$ }0 d1 [! C' Z
    1
    % g  k8 X2 c' S/ x1 |6 v然后就是计算NRI:
    0 K+ {5 {" {) H: r. B% ]- O( ]! y- h5 B5 X) a" [5 f' D
    dat$event <- event
    ' L4 a2 O% d' [+ ]1 D/ q2 Z$ Q* g9 s% }
    reclassification(data = dat,
    2 }3 G9 K3 M- D& D! E                 cOutcome = 21, # 结果变量在哪一列2 g% d+ L- o  b& v" ~+ }0 T3 ~
                     predrisk1 = p.std,
    & I  Y) V$ X: B4 A: H. S                 predrisk2 = p.new,
    # V3 K3 N+ U; q! s* ]; s                 cutoff = c(0,0.3,0.7,1)
    5 Q1 p  K' j/ F                 )
    : f; P4 O% Q& g. k' l# \1 ~1+ D+ @! F; A' N, M/ d, q' R# {1 E+ u
    ##  _________________________________________
    : {) {+ ?1 O4 C7 Z" q##  
      Y% B0 O/ |5 O9 o##      Reclassification table    / ~, r, W! Q# M9 C. X: d0 \/ U
    ##  _________________________________________
    ' [3 T4 G- P/ O+ F% D# A4 i6 A## - ^/ d. U6 B% V2 c. A; x" ~" }: ^6 q
    ##  Outcome: absent 5 m" Q7 \5 [) ]" Z( c
    ##   
    7 K$ U( p6 e0 M* t, P6 i##              Updated Model
    / g7 ^, r0 }. Q/ E0 c- X## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified2 e2 h3 ~3 o: V  n; G" V0 c: }
    ##     [0,0.3)       121         4       0               3* G( k9 R; y9 P! F" t: ]
    ##     [0.3,0.7)       1        13       1              13
    ' p9 k. ]2 S, s# E- R8 n; O##     [0.7,1]         0         1       3              254 H7 X( W; X/ s+ ?. y7 c; D
    ##
    7 T+ ~! R8 z8 |5 R. D! W##    U( [( A7 u" s( T& K
    ##  Outcome: present
    ( \8 r: T- l. x2 z##   1 c' Z5 {( ?0 _/ w0 [
    ##              Updated Model
    # L0 b& h. q) {9 f; l. e## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
    , W- Q1 C4 ?9 _4 O##     [0,0.3)        14         0       0               0
      {; A- [* `: C1 e5 o7 `##     [0.3,0.7)       0        18       3              14, ?$ I* ^$ p5 f/ {- q
    ##     [0.7,1]         0         1      52               24 H1 R4 n) v% Z) v) r/ C( L/ ]4 B* W
    ##
    * p6 N% ?0 D: O% b" G0 r2 {* }1 q##  
    2 d3 H2 F+ G% z4 V##  Combined Data
    ( E! ^' N9 l) S! @##   
    ! _4 X( @  C" t: A+ A# }9 a##              Updated Model+ _& T  r2 ~7 L1 a* g/ ~; w1 q
    ## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
    * h7 v! {, K0 M( J4 ]- F##     [0,0.3)       135         4       0               3' R1 T1 ?  \" l, d7 c  u$ m, T
    ##     [0.3,0.7)       1        31       4              14
    9 K5 J( h/ l" ~# y##     [0.7,1]         0         2      55               4. @: {$ t4 Z3 g$ v4 b
    ##  _________________________________________' t; k9 U9 O  `+ s  u! V) K
    ##
    ( J5 P$ L* m: I1 t2 ?- k##  NRI(Categorical) [95% CI]: 0.0019 [ -0.0551 - 0.0589 ] ; p-value: 0.94806   C2 ^& p) L) W5 m$ K
    ##  NRI(Continuous) [95% CI]: 0.0391 [ -0.2238 - 0.3021 ] ; p-value: 0.77048 ; P* u  }7 {" }4 e
    ##  IDI [95% CI]: 0.0044 [ -0.0037 - 0.0126 ] ; p-value: 0.283967 ~9 K; `( ?$ A! Q. K' }

    ! ]7 t. B+ e$ w  m5 [3 ^1/ J5 J7 N) `1 m2 I. y" @, y
    结果得到的是相加净重分类指数,还给出了IDI和P值。两个包算是各有优劣吧,大家可以自由选择。
    " `& k/ l  {8 [  k/ K* h1 q+ N7 x. k' u! l
    生存分析的NRI8 c7 h$ V* }! u/ q5 h! @
    还是使用survival包中的pbc数据集用于演示,这次要构建cox回归模型,因此我们要使用time这一列了。
    " \6 e5 l' s8 R5 D" H1 Z" h1 I- V, u7 d9 D
    nricens包
    ( o; X+ Q; J4 X1 g) xlibrary(nricens)% n8 X4 o: o: \: A8 Q' `, `
    library(survival)5 y) C5 R2 b. Q. ]! F2 l7 W

    9 W* f8 s4 o4 u! I+ J0 X4 Odat <- pbc[1:312,]
    3 L6 K3 y( n8 ^/ }dat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡, D& M% o3 Z) K* d* D6 k
    1
    ( U$ V# Q, o  ~. q7 U3 Y然后准备所需参数:0 \2 Z( I; y( e* f

    8 W1 q; F8 g0 @# 两个只由预测变量组成的矩阵  K6 t! W$ k2 S* u) ^
    z.std = as.matrix(subset(dat, select = c(age, bili, albumin))). M5 @# ]9 B4 ?. J" y2 \' |1 n+ _
    z.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))( Q5 Q  t" @' ]$ `8 x( X' T
    $ ~$ y& D1 @2 ], \4 C0 B6 Q9 _
    # 建立2个cox模型
    ' Y: u1 a$ c: ?8 Ymstd <- coxph(Surv(time,status) ~ age + bili + albumin, data = dat, x=TRUE)1 U. P2 }+ U) S. z0 [8 }0 q
    mnew <- coxph(Surv(time,status) ~ age + bili + albumin + protime, data = dat, x=TRUE)/ a$ G9 T! Y5 y+ F% m

    . ]0 r( {0 V3 K( _  N# 计算在2000天的模型预测概率,这一步不要也行,看你使用哪些参数# S! z, @- i( D" L3 T  S  k* {
    p.std <- get.risk.coxph(mstd, t0=2000)
    0 a* l" V4 U% z0 dp.new <- get.risk.coxph(mnew, t0=2000); E4 r* n' j5 L1 L
    1
    # G9 o# o% ^2 J  K* Q& P计算NRI:, J( t) F$ C. V- U. B% S9 z
    / h2 ~8 X1 ?: A# g/ |
    nricens(mdl.std= mstd, mdl.new = mnew, ' Z) \$ r: j3 K! t, w3 i7 `
            t0 = 2000,
    , Z0 g8 i3 I9 \* f7 B  |        cut = c(0.3, 0.7),) L% @5 H2 Q3 L- a& O" ~3 M
            niter = 1000,
    ) x  a+ N+ R  C6 j        updown = 'category')1 ~2 ?9 d, u4 l: o$ u- p
      C, p, u2 H1 I4 V1 W
    UP and DOWN calculation:
    - L; R4 [( T5 `  #of total, case, and control subjects at t0:  312 88 144! N  ~, |9 h' L% h9 }1 F

    1 i, x0 u" x  t; e  Reclassification Table for all subjects:1 w( p$ t% O4 X6 t" M
            New$ t+ B" F4 P9 p% N) e4 b
    Standard < 0.3 < 0.7 >= 0.7
    2 d" `2 }/ L0 Q. M  < 0.3    202     7      0; l( z+ d$ M% E2 [% B) W* U
      < 0.7     13    53      6
    " w9 [8 T! K. I# B) E" k- s  >= 0.7     0     0     31, i, ~0 a& q# ^

    ) ]6 j1 i* F/ i: t) a% Q: i" I  Reclassification Table for case:
    6 I& }# |7 K! R& W; p/ B        New
    - e1 S0 l8 O+ M& `% U1 eStandard < 0.3 < 0.7 >= 0.7
    . ?+ l) n; m) W8 |- f- y  < 0.3     19     3      0
    2 w5 W) o2 N* K/ w$ p; A  < 0.7      3    32      4/ p8 c& c& C- S# L) s6 V* J
      >= 0.7     0     0     27
    7 X0 j& m9 M+ |6 y: a0 P% C( T4 F- l' Q$ k7 b4 b
      Reclassification Table for control:
    * [/ F3 [5 X% ?        New8 B: d9 {. y( A* E" R
    Standard < 0.3 < 0.7 >= 0.77 n' ~" k( W1 V5 D9 @
      < 0.3    126     3      0" n$ d7 b! |+ ]) H- W7 L
      < 0.7      5     7      29 P/ j: f6 X  j6 c3 M( e9 P" ?: N8 v
      >= 0.7     0     0      1
    - I" ^  d" g' |6 V% V  B6 F2 v# |; v2 V, K* t
    NRI estimation by KM estimator:# B* C4 W$ c5 E$ w

    ! N' F" X, w: q3 B& MPoint estimates:
    . M- B6 a5 [& S                Estimate
    ; E  Z0 j! W6 U/ p- ^7 ZNRI           0.05377635( v! j7 Y" ~, @. M: Q( a
    NRI+          0.03748660
    ( `, W7 X2 V! WNRI-          0.01628974
    - ?- p/ W2 A; w; B6 w1 P( k9 aPr(Up|Case)   0.07708938
    $ |6 M4 {% j" iPr(Down|Case) 0.039602785 Q0 w( F8 g' C3 W. o: {4 g
    Pr(Down|Ctrl) 0.04256352) u1 ?$ r8 m% r2 o7 i" h% Q
    Pr(Up|Ctrl)   0.02627378% }, R# b4 p2 Y# w% n. ]

    7 J8 _3 u0 Y9 T4 ]9 D; [8 bNow in bootstrap..8 K8 b, T) ~* S; v9 \! t3 o, g9 Y- w: ~

    2 n3 V5 i2 @. ]  l6 mPoint & Interval estimates:
    : P7 ?! K8 Q7 d" F4 l                Estimate        Lower      Upper
    & \( Z0 d* [  p4 e3 O: rNRI           0.05377635 -0.082230381 0.16058172
    9 ~; t% W+ c: `9 P/ Y+ PNRI+          0.03748660 -0.084245197 0.13231776  f' I6 B9 ~0 y# w3 |% s# L, }
    NRI-          0.01628974 -0.030861213 0.06753616! o6 o$ ?" u3 R
    Pr(Up|Case)   0.07708938  0.000000000 0.19102291
    - e8 K" h1 Q5 E/ vPr(Down|Case) 0.03960278  0.000000000 0.15236016
    7 T) Z- T# X: A$ RPr(Down|Ctrl) 0.04256352  0.004671535 0.09863170: d! J3 W: z, B# E
    Pr(Up|Ctrl)   0.02627378  0.006400463 0.05998424& g9 a8 F" _7 c$ z' F; _2 _$ O% X
    1 D; {) D7 h' q6 a% L
    1
    + U6 f: _6 D& m( d; w. W! G9 P# c2 a* s. Q4 b2 ]& R2 ?, C% T
    Snipaste_2022-05-20_21-49-38
    " ]+ i* J9 q$ w1 T, Q结果的解读和logistic的一模一样。& @' f* c  X$ H8 G

    8 h7 z2 I% R  ?2 M: q( usurvNRI包9 G# K: r6 a4 V4 u8 T- R/ S
    # 安装R包
    ) `, d/ [3 `1 y0 t! D8 v" hdevtools::install_github("mdbrown/survNRI")2 n% b% C: b( s' Y
    1
    $ t8 X# z( K' l0 \& r/ ?1 u加载R包并使用,还是用上面的pbc数据集。( O1 t+ T) Z* y; {# ~

    . @2 }7 F% _7 s. ^, q8 H- nlibrary(survNRI)4 w# z$ ^1 P% z+ ?9 G; M) d
    1' f2 F  b* T9 J+ J5 O9 T5 X
    ## Loading required package: MASS
    : I5 z/ U+ i7 `2 k7 m1
    % _$ D  q7 i% H0 J2 xlibrary(survival)$ e/ z4 b8 f/ p

    9 X$ c0 V1 [. p- ?8 v- H3 d) O" k# 使用部分数据
    4 A6 H& m0 m1 B4 s4 D2 {dat <- pbc[1:312,]* p( P  {$ F! M3 k9 y; F% S
    dat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡& i  @0 q; O" q; K

    - [2 ]% l3 V8 g# ~2 N' M7 e& t" Kres <- survNRI(time  = "time", event = "status", ! \- D, r# F4 f- X
            model1 = c("age", "bili", "albumin"), # 模型1的自变量
    1 f1 }( K, C4 S        model2 = c("age", "bili", "albumin", "protime"), # 模型2的自变量) O& P, L! m1 ?+ ?! t
            data = dat,
    ( }" i9 P* e+ J! ]( r# t* G. \        predict.time = 2000, # 预测的时间点
    1 ?  V& i; s3 j) k/ ~4 F3 c. V        method = "all",
    3 |9 Q$ R+ N" s  O0 B: A        bootMethod = "normal",  
    : d7 G- ^( T/ ~/ V9 }        bootstraps = 500, # P( G& r' I$ Q1 @# p
            alpha = .05)
    * h$ t6 F. ]5 I1 g: w6 d7 ?3 g
    1' l6 c; W2 B1 q7 G
    查看结果,$estimates给出了不同组的NRI以及总的NRI,包括了使用不同方法(KM/IPW/SmoothIPW/SEM/Combined)得到的结果;$CI给出了可信区间。, H7 b0 ^6 I- Q  ]" L, x- c

    ) z) g% i2 W1 Q$ I. mres) t9 w! N! j) v; ?  q; T- X
    1
    ; ~- C9 x, z% L' }- s## $estimates
    8 g1 ?# z! U+ T) U5 }6 k# E##            NRI.event NRI.nonevent       NRI2 p, V3 [0 U% z+ e1 q  ]. }, i) ]
    ## KM        0.20445422    0.3187408 0.5231951; F( q3 T5 ^. g  T1 i8 p* B& y
    ## IPW       0.22424434    0.3273544 0.55159874 O) J) c( T/ Q) F! y6 g. c
    ## SmoothIPW 0.19645006    0.3144263 0.5108763
    . @8 c8 h/ D8 N/ h" B, b## SEM       0.07478611    0.2632127 0.33799889 J: [5 h2 M4 F) \
    ## Combined  0.19633867    0.3143794 0.51071810 S5 N: p' v$ G4 @8 A8 z
    ## : I# e7 s! A) Z
    ## $CI
    $ p6 d1 l1 @. E* u& H% G## $CI$NRI.event. t1 c0 T1 @- I- F) T6 a
    ##                     KM         IPW   SmoothIPW        SEM   Combined
    ) a" @( W" m' K+ }# _8 K## lowerbound -0.03915924 -0.02185068 -0.04724202 -0.1162587 -0.0473723
    ) X9 g$ B& P' J% D4 j* l4 q& e" @## upperbound  0.44806768  0.47033936  0.44014214  0.2658309  0.4400496, O; A  N6 z4 e  Q7 j% G
    ##
    , }$ [' R9 l8 Y## $CI$NRI.nonevent
    " {" }5 ^, j" R6 h& o##                   KM       IPW SmoothIPW        SEM  Combined
    ; J- E/ v. a8 |* K/ S; F$ o( D## lowerbound 0.1317108 0.1396315 0.1286685 0.08638933 0.12864268 |. ?7 y, t6 Q3 [% V' p
    ## upperbound 0.7102251 0.7393216 0.6966341 0.51482212 0.6964549. U& O+ Q* ^+ a- b) a( a' U- E  Z3 X2 p
    ## ) a! ?* r, Y5 v! S" b& i$ r  g
    ## $CI$NRI0 E  o: |# e- }% g9 _& B3 L
    ##                     KM         IPW   SmoothIPW         SEM    Combined) c; T/ I2 ^6 l7 f* ?. X! g& F$ d
    ## lowerbound -0.05112533 -0.04569046 -0.05439863 -0.04132364 -0.054434099 w) c( i, m* e. O) c+ Q' K
    ## upperbound  0.89306122  0.92464359  0.87970125  0.64253510  0.87953153% F* m9 j3 {' C6 w: N7 y
    ##
    + x& \7 u8 c. u+ Z7 z##
    1 O0 r/ r0 z8 p' i" O* n& q## $bootMethod
    $ v" x" w+ ^$ w/ n4 S: Q3 A* u## [1] "normal"
    # J" s3 q) X* a' p% ~##
    " T/ l$ t6 N+ f! j## $predict.time' `; {# ?- J' a7 a! H3 {% Q! h8 {9 r9 a
    ## [1] 2000
    - p' B  X/ z3 @, _8 D4 R##
    7 z3 O$ z% o7 Z## $alpha/ R8 [9 [5 N" C/ M/ I' R5 K
    ## [1] 0.05' Z, r/ z5 a! a! [8 t2 U" W
    ##
    2 a- e- w: h5 `! e1 S7 ^7 p## attr(,"class"). E2 Y1 Z) E2 t4 z9 ~
    ## [1] "survNRI"0 L' m3 I! m6 ]6 L( V# W
    ' B. O) f5 p) b0 c0 b; s; y6 ?
    1; T' p6 I1 b! S" @9 u% G0 S* i1 L- a
    OK,这就是NRI的计算,除此之外,随机森林、决策树、lasso回归、SVM等,这些模型,都是可以计算的NRI的,后面会继续介绍。大家如果有问题欢迎在评论区留言。
    ' u3 l3 g/ m& Z! r7 m) Z* w. Y7 ?& M2 t6 L3 Y) w
    本文首发于公众号:医学和生信笔记. \4 R- K! f$ v8 x( h5 i" K1 e
    % i4 V3 y! r$ d- _. B& ]1 ?4 F
    “ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。( l9 b/ z8 K( D6 [4 i4 j& E& [
    本文由 mdnice 多平台发布
    ' [! P( g+ V+ u% n( ?————————————————
    6 Y8 G* u  M6 N- x2 q4 r/ I版权声明:本文为CSDN博主「阿越就是我」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    1 X' X( g9 E: [! ?: F$ d* \; n, ~原文链接:https://blog.csdn.net/Ayue0616/article/details/126768006" V9 D( U3 h& {' `" b
    / d: t9 y# x# D2 o

    , I/ u' r) J" a
    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-10-8 08:08 , Processed in 0.960076 second(s), 50 queries .

    回顶部