QQ登录

只需要一步,快速开始

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

    9 F/ C* K6 Y9 H" V+ _% W净重新分类指数NRI的计算
    1 N4 z5 G- s  c; @4 v# O“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。
    ; }8 d* b: _5 s( I! H1 z, c! u0 F2 wNRI,net reclassification index,净重新分类指数,是用来比较模型准确度的,这个概念有点难理解,但是非常重要,在临床研究中非常常见,是评价模型的一大利器!5 |# s+ `4 g$ I/ [! n1 b  Q% I

    2 u3 Y" _; n- T# I, n在R语言中有很多包可以计算NRI,但是能同时计算logistic回归和cox回归的只有nricens包,PredictABEL可以计算logistic模型的净重分类指数,survNRI可以计算cox模型的净重分类指数。3 {0 T: d4 E* ~+ \2 r6 M
    - `: L8 u3 R5 M2 Q7 Y' z
    logistic的NRI: K8 o9 y8 g  |8 `7 G% o! m
    nricens包
    " s! g6 F6 a- B' c& a; N0 o4 F5 b6 xPredictABEL包
    ' k1 {- Z2 J& `; h生存分析的NRI
    9 n+ h1 Z5 x* v5 K: ]nricens包
    % D# V! e6 _! w, v. b3 z2 ~survNRI包
    6 q* {2 H9 [0 x! N7 i. Klogistic的NRI
    ; ^5 ^& v/ `5 b- i! H7 Snricens包1 ~8 ^4 K/ I8 q. J. J
    #install.packages("nricens") # 安装R包
    # Y& t! D% j$ mlibrary(nricens)
    ( Q& C) B1 L2 `3 o/ B. a& O% |1: W' K( t( W/ X6 `
    ## Loading required package: survival
    2 \: k; i. S( O1; D6 n( {8 x: l! E; Q3 `
    使用survival包中的pbc数据集用于演示,这是一份关于原发性硬化性胆管炎的数据,其实是一份用于生存分析的数据,是有时间变量的,但是这里我们用于演示logistic回归,只要不使用time这一列就可以了。$ I+ @. e2 Q2 x; ~8 E. S3 e6 `
    % G0 W7 J- i4 z  [$ y
    library(survival)0 ?2 g, g; Q& p9 H6 V
    3 X1 o" G5 O' `9 i
    # 只使用部分数据
    , |$ r) {4 v: Q5 M; Pdat = pbc[1:312,] # N' s, ~* @: z* x
    dat = dat[ dat$time > 2000 | (dat$time < 2000 & dat$status == 2), ]* V& |* m" E7 ]9 ]! b

    ; `) N8 t3 M$ Y% u! Q) l8 dstr(dat) # 数据长这样5 ~7 C/ P" G/ u4 {
    10 W# E  u) A. D$ S& M3 a' u# K  c
    ## 'data.frame': 232 obs. of  20 variables:
    + \- L) {9 R! Z8 R##  $ id      : int  1 2 3 4 6 8 9 10 11 12 ...
    0 N; ?/ t0 [1 Q2 O/ G##  $ time    : int  400 4500 1012 1925 2503 2466 2400 51 3762 304 ...8 @5 Z# K% o' H: T) |" H5 V1 [( ~
    ##  $ status  : int  2 0 2 2 2 2 2 2 2 2 ...+ x4 [" B# v2 l+ F. x2 j8 q2 h
    ##  $ trt     : int  1 1 1 1 2 2 1 2 2 2 ...
    % Y3 K: f% P0 c, |/ D0 y##  $ age     : num  58.8 56.4 70.1 54.7 66.3 ...
    & I5 c! N# i) f##  $ sex     : Factor w/ 2 levels "m","f": 2 2 1 2 2 2 2 2 2 2 ...: V; ~9 U* [) ]0 N8 S
    ##  $ ascites : int  1 0 0 0 0 0 0 1 0 0 ...
    ! a5 x) |6 y& ]9 x: P% @& u$ r' P##  $ hepato  : int  1 1 0 1 1 0 0 0 1 0 ...
    % P7 Y" ?: P, r8 G& e##  $ spiders : int  1 1 0 1 0 0 1 1 1 1 ...# W7 O9 W9 E& Q% ]* B
    ##  $ edema   : num  1 0 0.5 0.5 0 0 0 1 0 0 ...
    # j. Y: i3 s2 \- F" o5 D; {##  $ bili    : num  14.5 1.1 1.4 1.8 0.8 0.3 3.2 12.6 1.4 3.6 ...6 x! q7 @( D# A; |9 b* t4 q& V0 [
    ##  $ chol    : int  261 302 176 244 248 280 562 200 259 236 ...: _9 H, _' ~( |+ B5 I
    ##  $ albumin : num  2.6 4.14 3.48 2.54 3.98 4 3.08 2.74 4.16 3.52 ..." U, Q) s' U% F' w* {' R, x1 C5 ~: D
    ##  $ copper  : int  156 54 210 64 50 52 79 140 46 94 ...
    5 Q6 p' c9 u! V##  $ alk.phos: num  1718 7395 516 6122 944 ...& U1 {6 \2 l% u1 R+ j
    ##  $ ast     : num  137.9 113.5 96.1 60.6 93 ..., J0 N4 u4 Y/ L/ t. ~" }& ^
    ##  $ trig    : int  172 88 55 92 63 189 88 143 79 95 ...
    . c0 G. j& z" F% Z( H##  $ platelet: int  190 221 151 183 NA 373 251 302 258 71 ...% K& `* Q9 X3 ~# ?: u
    ##  $ protime : num  12.2 10.6 12 10.3 11 11 11 11.5 12 13.6 ...
    9 |) n% ~9 `& _/ ^9 a##  $ stage   : int  4 3 4 4 3 3 2 4 4 4 ...
    8 W# Y4 y! g4 _$ H# r
    # V" R. I3 I% S0 l$ @+ Z) C1
    ) N  F  o. b. i- odim(dat) # 232 20; b: U( ~* {: _5 D! c
    12 m4 @4 e# _5 g( q4 L
    ## [1] 232  20- Y: c. c) ^% u* B1 H
    18 O+ K1 x& u; b( K/ h. M3 ~" r# {5 \  K
    然后就是准备计算NRI所需要的各个参数。
    - Z$ e) ^" Z! r$ U: R
    . |: W4 u2 y* g) V/ R# 定义结局事件,0是存活,1是死亡8 ^0 C  E& p- s
    event = ifelse(dat$time < 2000 & dat$status == 2, 1, 0)5 n! v- F& Z. z2 E$ h
    ' j7 Q5 w" s4 I2 J
    # 两个只由预测变量组成的矩阵
    5 f% {* m0 g: K" F* oz.std = as.matrix(subset(dat, select = c(age, bili, albumin)))
    ( b7 x# e& m( Nz.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))0 [. s: F1 `* @% N5 M: ^

      a& s! w: x4 ?% i# 建立2个模型; |/ L0 x/ i% L2 ^! p
    mstd = glm(event ~ age + bili + albumin, family = binomial(), data = dat, x=TRUE)
    " C- m  @: e$ L! B9 m  ~mnew = glm(event ~ age + bili + albumin + protime, family = binomial(), data = dat, x=TRUE)
    % ?, a4 K) T4 t$ m4 m
    # h! f+ A* L- S; C) o3 t4 E. M. z3 C3 |# 取出模型预测概率/ j3 ?+ s3 u+ \% |' M) q
    p.std = mstd$fitted.values
    ; p! c/ W2 T' Q: n7 u  Z; H! H) mp.new = mnew$fitted.values; Z/ l4 n8 z/ C

    8 W8 }6 e5 C/ L$ m) n; }& a16 |+ n, V/ ^" j
    然后就是计算NRI,对于二分类变量,使用nribin()函数,这个函数提供了3种参数使用组合,任选一种都可以计算出来(结果一样),以下3组参数任选1组即可。 mdl.std, mdl.new 或者 event, z.std, z.new 或者 event, p.std, p.new。
    # W2 {' Z1 L. E( ]- Y; {! |
    7 V8 Z# Y, z) s- ~: F9 @# 这3种方法算出来都是一样的结果$ f' {" _2 v# X

    4 {' a2 l  ?7 Z7 Z3 r7 A+ V# 两个模型* a7 q; Y' s) O! D7 h/ u
    nribin(mdl.std = mstd, mdl.new = mnew, , H8 n* u/ i1 M% H+ _
           cut = c(0.3,0.7), 7 v! M& G' E9 I# L4 w# W; {# V' L( A
           niter = 500, ( v& t7 m4 X2 M; l
           updown = 'category')
    2 Q! j: J) Y' [2 }( [& F
    2 g1 X4 e/ M9 w# 结果变量 + 两个只有预测变量的矩阵* R* a9 C6 y8 `9 _
    nribin(event = event, z.std = z.std, z.new = z.new,
    + ?3 E, W; w! u/ ]7 m% q+ E( l       cut = c(0.3,0.7),
    9 r7 _8 u2 v! G7 A! P* |# o       niter = 500,
    # X; K- n" @) D% g       updown = 'category')9 k7 S( l- c0 v/ J4 M

    2 X& B* ?! Z$ u1 u1 a2 c## 结果变量 + 两个模型得到的预测概率3 e& y# T  T* G) q
    nribin(event = event, p.std = p.std, p.new = p.new,
    6 y( z( g% S" P8 Z2 p+ u       cut = c(0.3,0.7),
    1 `$ k3 k0 S/ Y# }" C1 U( J5 T       niter = 500, 0 n6 K6 K  {9 D  I9 T' U
           updown = 'category')3 k% H1 c% z$ x+ |& z

    & `& f4 H0 j) z. Q0 g3 T8 m1* i# z8 e% U. U
    其中,cut是判断风险高低的阈值,我们使用了0.3,0.7,代表0-0.3是低风险,0.3-0.7是中风险,0.7-1是高风险,这个阈值是自己设置的,大家根据经验或者文献设置即可。
    % T5 `: v' r: Q# P- |8 y9 y" G! U  [- s) V! U
    niter是使用bootstrap法进行重抽样的次数,默认是1000,大家可以自己设置。7 l* S9 i& X6 ]0 X0 n2 P
    & R0 W; e8 B5 o' h0 f4 X. |
    updown参数,当设置为category时,表示低、中、高风险这种方式;当设置为diff时,此时cut的取值只能设置1个,比如设置0.2,即表示当新模型预测的风险和旧模型相差20%时,认为是重新分类。+ W+ I/ }9 Z# L9 u" A

    $ Y) D1 _( F$ }; m; n& l2 G上面的代码运行后结果是这样的:
    ! R2 v; \' g, o/ f. v* {$ Q3 U3 ]4 V8 x
    UP and DOWN calculation:
    : E1 ^5 S+ b( Z2 a+ B, J0 l  #of total, case, and control subjects at t0:  232 88 144
    & F# X" R$ L* o* c6 v) V- w+ L1 L/ }' B9 e2 Q2 i
      Reclassification Table for all subjects:6 P. |, [6 _9 J1 o+ Q+ H, v2 u
            New6 Z* p) @1 }0 l9 t4 B
    Standard < 0.3 < 0.7 >= 0.7
    / ^7 W4 V0 c! ]/ B  < 0.3    135     4      0* h$ {- v% i* _8 W
      < 0.7      1    31      4
    ' Q8 ?  u6 @% _6 q+ Y4 m  >= 0.7     0     2     55
    1 Z3 Q7 s! b0 ]" i' l: p# c4 k
    # X. g+ R+ f/ F1 M" l7 l, X  Reclassification Table for case:
    ( w/ M4 o. {1 l+ Z! S0 X8 ~        New/ C0 W- r! I/ E$ ~$ I  Y
    Standard < 0.3 < 0.7 >= 0.7
    : G  y; C. |2 u4 G. C  < 0.3     14     0      0
    ( b% @, H  ^0 ]$ K3 ]4 R  < 0.7      0    18      39 v# M8 U! _2 m, i
      >= 0.7     0     1     52
    / r# l4 B( U7 o
    ; _3 e( t: ^, B: k9 h2 q( z  Reclassification Table for control:+ v6 C, O# V/ h# ]
            New$ _% `8 {7 S. W/ o( Q
    Standard < 0.3 < 0.7 >= 0.7
    $ b; s  G# l# w$ i" J  < 0.3    121     4      06 o) }$ r* I1 Q, Z
      < 0.7      1    13      1. C$ B2 P4 m  J' \$ K
      >= 0.7     0     1      3
    / X8 C% r. y' m) c% n9 q3 x- D
    # ^% W: I4 [! T! Y" \NRI estimation:
    ! V" p3 M( y8 C9 }' h" q; sPoint estimates:
    # l5 Q7 j5 i9 s& b3 u* L                  Estimate
    ! |1 T. @) ^! W+ oNRI            0.001893939
    ( ]& p. M4 x# x4 F- M7 f( J8 jNRI+           0.022727273( T$ Q' P! r0 J
    NRI-          -0.020833333
    " _. g) c  E* M9 R, W0 {* t! vPr(Up|Case)    0.034090909
    3 G" f  I" z8 }Pr(Down|Case)  0.011363636
    , o6 W$ i' N7 H3 o9 }+ EPr(Down|Ctrl)  0.013888889
    # Y- i7 V+ O( I$ ~. }: H7 Y! T, v2 sPr(Up|Ctrl)    0.034722222
    5 q- Y& k' V, o1 _" b) n
    % O9 z" Z1 N1 N7 H8 s, Y  b9 ANow in bootstrap..
    . ~8 r  p7 B; A  H9 I) Z: Z4 A% r7 C. l7 t# {
    Point & Interval estimates:% r, j9 Q3 e! t5 |7 B
                      Estimate   Std.Error        Lower       Upper/ A/ O7 b1 n7 R7 t+ y4 ~7 D
    NRI            0.001893939 0.027816095 -0.053995513 0.055354449$ ~2 N5 b$ r4 x
    NRI+           0.022727273 0.021564394 -0.019801980 0.065789474
    2 [$ W: c9 Z) ?' I( `  m+ @& P& FNRI-          -0.020833333 0.017312438 -0.058823529 0.007518797
    8 Y; J$ S. ]& X+ K5 A5 c  v6 k' GPr(Up|Case)    0.034090909 0.019007629  0.000000000 0.072164948) d: m0 ~; y9 g1 O
    Pr(Down|Case)  0.011363636 0.010924271  0.000000000 0.039603960
    * o1 n& [) M8 H1 B; y! E# n4 uPr(Down|Ctrl)  0.013888889 0.009334685  0.000000000 0.035211268
    - o' G4 a1 f4 s5 d2 L& N4 V) t3 N/ f; uPr(Up|Ctrl)    0.034722222 0.014716046  0.006993007 0.066176471
    % @2 k1 F* V3 t, k  S: c7 \
    + B. w5 O, Q6 H9 p3 w2 M( ]- L10 C: y( T" F9 K9 r7 o( Z$ E9 p
    首先是3个混淆矩阵,第一个是全体的,第2个是case(结局为1)组的,第3个是control(结局为2)组的,有了这3个矩阵,我们可以自己计算净重分类指数。
    7 L2 @+ r% r$ q& O0 r
      Z+ `: f- H0 N看case组:( L% G" r9 I2 L  B

    6 H; a  E* X! {; _9 h净重分类指数 = ((0+3)-(0+1)) / 88 ≈ 0.022727273
    % o2 V- R" b0 O. h! G1 v3 d  O8 C: H& d( y/ y) W$ R
    再看control组:' I, {! \0 S8 e
    $ Y# T1 z, g" C" ?: f
    净重分类指数 = ((1+1)-(4+1)) / 144 ≈ -0.020833333- h  n) r' H2 U0 p: u

    1 Y$ v, k1 f! i( ?# ]5 s9 {, @相加净重分类指数 = case组净重分类指数 + control组净重分类指数 = 2/88 - 3/144 ≈ 0.000315657
    3 n& ]* c, q( c2 n+ \: w! P/ b8 B: w2 Y5 z1 w+ {0 M
    再往下是不做bootstrap时得到的估计值,其中NRI就是绝对净重分类指数,NRI+是case组的净重分类指数,NRI-是control组的净重分类指数(和我们计算的一样哦),最后是做了500次bootstrap后得到的估计值,并且有标准误和可信区间。
    0 T, L; E' n7 F" ~0 M$ q! \6 u2 e% n$ @! u* k+ ?! {9 Y% X
    最后还会得到一张图:6 y1 q- h; l; e  s! V# {; O. G

    $ I( v6 u: g$ K6 v& w" R这张图中的虚线对应的坐标,就是我们在cut中设置的阈值,这张图对应的是上面结果中的第一个混淆矩阵,反应的是总体的情况,case是结果为1的组,也就是发生结局的组,control是结果为0的组,也就是未发生结局的组。
    - W) u- Q+ r  O$ Z- _
    ' f5 }* C0 C& g" dP值没有直接给出,但是可以自己计算。5 Q. l8 z+ Y& x  ?' [) y2 X$ v

    5 t0 E! I, s! G, r, c" a/ l# 计算P值# j" \) o; R1 n! ^
    z <- abs(0.001893939/0.027816095)
    ( G! S( h% A/ T: X' Up <- (1 - pnorm(z))*20 }+ }5 E8 b) {' K% [7 x. t8 H) R
    p% z# W5 Y5 H- E9 p- ^
    1
    7 ~  g, `7 R; A7 M$ s6 C. n3 J## [1] 0.9457157
    9 M$ v+ _! [: P4 c" M& d1 @+ j# i1; A) E0 a9 N1 C0 ~1 e* [: S
    PredictABEL包
    5 {1 H4 ^  ~) x  @#install.packages("PredictABEL") #安装R包* F. I0 D7 `3 }" e7 ?8 j
    library(PredictABEL)  1 e8 F+ [0 M) @; V# p# C: u
    ( a/ L2 ^$ }% z4 L5 S! V4 }; I) N
    # 取出模型预测概率,这个包只能用预测概率计算, i! t, }+ M" X" }4 D  ~
    p.std = mstd$fitted.values, }, Q" B1 K' _. Y) F: G5 q" D6 |" o
    p.new = mnew$fitted.values
    5 {+ Y" d* e' |0 I9 k1
    " O, c& K, Y/ [9 U然后就是计算NRI:9 B3 y! N4 N/ W) P, ]0 o

    0 F% w  G* [+ F& Ddat$event <- event/ k8 N) |0 v2 K, P6 f; r
    7 |# Z. @* Z" y- E0 ?) }& r
    reclassification(data = dat,
    7 {' ]# k& t" p                 cOutcome = 21, # 结果变量在哪一列
    2 I7 o. P* p3 w( F1 Z. H" x                 predrisk1 = p.std,
    , X" l' t6 |! f; a9 M                 predrisk2 = p.new,4 n1 K6 W; b1 z# L( {
                     cutoff = c(0,0.3,0.7,1)( D# ]. X' J2 e9 ]- g  R
                     )/ I7 ]# w* q/ `; V+ T7 P
    1
    1 D7 ?( D1 |6 L# ]; V  |8 N##  _________________________________________+ Y7 k' T5 v9 o* z) ~
    ##  4 |* [0 O& S/ c( A3 S$ E  K, K
    ##      Reclassification table    ! e: v0 s: n% D! G
    ##  _________________________________________
      L& H% N% T5 Q##
    - H& C5 h' B' I4 O: T, _; M! s, t##  Outcome: absent 2 N) C" `7 n1 S0 ]8 l
    ##   8 V. J- k; _5 a  a, l
    ##              Updated Model
    0 k, M7 O! M9 x; X/ S## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified$ ]1 [2 [! a+ w" Y1 U
    ##     [0,0.3)       121         4       0               3
    ! z8 _+ b; c6 X3 ~##     [0.3,0.7)       1        13       1              13& Y9 V' a4 E4 W+ _: @4 U
    ##     [0.7,1]         0         1       3              25
    ; t5 N; o6 I, ]; b4 F1 Z+ m8 h##
    ) ~( a; M- x; B: j0 v##  
    4 M& M/ y6 r2 ^0 A& M##  Outcome: present " [: }  }3 |' q# a
    ##   
    * v$ Q6 J" n% F4 x% w1 t: U9 ?##              Updated Model) E/ ~2 D3 R* V" _) H% @" k) i9 Z
    ## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified- ~( o4 L1 Y0 b8 S' m
    ##     [0,0.3)        14         0       0               0  W' y+ v, }7 [) L
    ##     [0.3,0.7)       0        18       3              14
    : C% |; @2 y9 g. `; x##     [0.7,1]         0         1      52               25 S7 Y+ \; {& U8 w/ C, [
    ##
    & |9 _  l; D/ R* f##  + b, P" q* X2 F* Q, k
    ##  Combined Data
    / P. n5 f2 r8 c5 {& ~##   1 h# X+ r: K6 F% a9 a
    ##              Updated Model# n: ]# i6 S3 f+ d
    ## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
      o% C9 Y2 k; |; G  F- X+ K##     [0,0.3)       135         4       0               3
    % c  v5 w! x7 V4 J, X##     [0.3,0.7)       1        31       4              14
    # {% F, N0 e  b# B" r2 C" V5 z# J##     [0.7,1]         0         2      55               4$ u- G; P: T6 @; j; P# q- H
    ##  _________________________________________4 t; h. F4 ^, ~
    ##
    ; J; K% I4 A" k/ V& R% y##  NRI(Categorical) [95% CI]: 0.0019 [ -0.0551 - 0.0589 ] ; p-value: 0.94806 & ]% J0 E+ Q: ~1 z9 O& v  E+ P9 x
    ##  NRI(Continuous) [95% CI]: 0.0391 [ -0.2238 - 0.3021 ] ; p-value: 0.77048 8 z# {- u$ e- ~/ ?- |
    ##  IDI [95% CI]: 0.0044 [ -0.0037 - 0.0126 ] ; p-value: 0.28396
    " ?8 [% r4 O* W# ]
      c! z/ o% d5 ^' }$ B% Z/ b9 F* ~1: S) W" C' F7 V+ t
    结果得到的是相加净重分类指数,还给出了IDI和P值。两个包算是各有优劣吧,大家可以自由选择。
    9 r) u: p2 n# [# _' X: I; X5 @/ Q+ \1 }4 }% `: v4 q, q: }
    生存分析的NRI
    ( y4 o* n, W$ o9 y) I1 U还是使用survival包中的pbc数据集用于演示,这次要构建cox回归模型,因此我们要使用time这一列了。+ n4 b& S5 ]) f) k# H4 j, B

    7 A+ [% @6 i5 S! t" U- U+ A/ Xnricens包
    , p* h3 h" o( t! C- Qlibrary(nricens)6 N7 l  f' V0 a
    library(survival); D  V/ [/ J0 ^) F% n
    4 R8 o' i* q$ g/ K, k/ Y
    dat <- pbc[1:312,]$ A: V) U/ |9 |3 u; e2 X
    dat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡
    . v4 \; S7 O* y( c' i5 C5 X1/ h$ d) Z% R* ?# Z
    然后准备所需参数:3 x4 J/ B! s3 e8 f) s4 Y( c
    ( k- V3 h8 F5 r' x
    # 两个只由预测变量组成的矩阵7 p, m# e9 f  g) X  q9 W
    z.std = as.matrix(subset(dat, select = c(age, bili, albumin)))
    2 X5 |! f& N2 j9 z+ d' F9 u/ Ez.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))) _  {% I; t4 R; w! o: B) v: K
    5 V4 A2 E) R" I7 j. y: e, T
    # 建立2个cox模型
    ! }, `" W' H5 u5 _; _! J- z7 _mstd <- coxph(Surv(time,status) ~ age + bili + albumin, data = dat, x=TRUE)" @/ ~6 M& S" J$ R/ D
    mnew <- coxph(Surv(time,status) ~ age + bili + albumin + protime, data = dat, x=TRUE)
    & S9 `- X& j! J: ?) |
    " b$ I4 _2 F/ n, C) M# 计算在2000天的模型预测概率,这一步不要也行,看你使用哪些参数8 S$ @, n4 s$ a8 S
    p.std <- get.risk.coxph(mstd, t0=2000)2 {8 j* I; m! j' J9 r7 ~
    p.new <- get.risk.coxph(mnew, t0=2000)
    ' E9 q2 M" w/ W; n9 s/ F- {) e17 b0 @* V3 G" @& t
    计算NRI:. b) M7 g) v: }8 [
    - [: W! D, n( X, F* z" E1 N
    nricens(mdl.std= mstd, mdl.new = mnew, " C5 Q' k$ {- r# N+ S8 A( G. M; c: @
            t0 = 2000, 8 G! k( P: ~( E
            cut = c(0.3, 0.7),
    1 A( ]. Q: G; u$ @  `        niter = 1000,
    ) ]) S' V3 j$ D) r/ Z4 ]        updown = 'category')
    / a+ q, X* E: U" R' k; {- |
    ; K( _% J6 I  l3 }UP and DOWN calculation:
    # e# [; E  w- T6 J. q( e( Z2 x& I  #of total, case, and control subjects at t0:  312 88 144& [5 H' @0 U* o3 D) n( o
    % A1 K4 B  w( y. j
      Reclassification Table for all subjects:
      B4 T1 h, h% l9 o        New8 M% ?, i0 x- ^) |
    Standard < 0.3 < 0.7 >= 0.7
    % v# g  h* G6 w: x  < 0.3    202     7      0
    : k  X4 ^- u0 U5 w- v/ x  < 0.7     13    53      69 }* D  ~: y# _! Y4 d
      >= 0.7     0     0     31
    % x6 K+ w% W/ f7 ?0 e8 X5 l0 G2 W* {2 f
      Reclassification Table for case:
    % A& @' E: V5 L/ L6 T) A3 ]        New
    . Z1 k* p4 C# u$ \' YStandard < 0.3 < 0.7 >= 0.7
    + A0 Q  a$ |& Z1 N  < 0.3     19     3      04 k& U. @6 T8 w/ `
      < 0.7      3    32      4! l; e* B% ]! c; o
      >= 0.7     0     0     27  N& y1 {3 ?' R9 V
    : T1 g6 e; K+ s, a8 N2 b
      Reclassification Table for control:
    / h+ p1 q! F/ |! r) ?' M        New1 _1 E, w+ {6 E! _0 k8 p( w5 I% S0 F
    Standard < 0.3 < 0.7 >= 0.7
    3 K# f$ Z' L8 f  < 0.3    126     3      0/ h4 D1 ?; F7 _- ~) N
      < 0.7      5     7      2
    / w: K* U% u$ k3 R8 O" W  >= 0.7     0     0      1  f9 F0 n& A# t/ `
    ) @& `( |  u  P9 M% F
    NRI estimation by KM estimator:7 \3 U- }2 @) C8 G) t8 W
    0 l- @9 C4 g# ~
    Point estimates:
    1 B# o+ M$ M- N' v, `. J$ [                Estimate
    ) `: C( t7 Y3 Q% L6 r8 e& uNRI           0.053776351 M& ~, h' j( b  w3 O, {
    NRI+          0.03748660# e7 _5 ?/ u1 j6 [+ M
    NRI-          0.01628974
    2 H7 a' r+ N# L" Y# q' E6 ^Pr(Up|Case)   0.07708938
    % x3 [% ?5 r( @/ Z9 r( kPr(Down|Case) 0.03960278" b" b9 l4 D! V5 }6 D; e
    Pr(Down|Ctrl) 0.04256352* O' a& X# r: |" H$ @
    Pr(Up|Ctrl)   0.02627378
    . F6 h3 |. H  p4 x6 L' w7 x* C( j$ H/ l' f' p
    Now in bootstrap..& \0 D0 E/ |9 n9 `" K$ p5 q. h- F5 n5 U0 M
    6 a" U; a1 g8 K5 r) K
    Point & Interval estimates:
    7 H' S/ B; q; W$ H, l  G1 C4 P                Estimate        Lower      Upper' Y& ?9 r/ z* ]8 ?
    NRI           0.05377635 -0.082230381 0.16058172
    4 l' m- S6 F! s$ b/ @NRI+          0.03748660 -0.084245197 0.132317762 O0 {, i; ?* Y1 [
    NRI-          0.01628974 -0.030861213 0.06753616' e' z, A; n: {0 l: g; R9 _' l
    Pr(Up|Case)   0.07708938  0.000000000 0.191022916 Y3 b1 M8 Y: k# S9 t( L8 S
    Pr(Down|Case) 0.03960278  0.000000000 0.152360164 b/ b% r+ L( p. O
    Pr(Down|Ctrl) 0.04256352  0.004671535 0.09863170
    . H" |2 f8 f/ vPr(Up|Ctrl)   0.02627378  0.006400463 0.05998424
    4 ?/ c! G+ r7 t, ?7 G. ]
    5 f3 l5 ?4 U1 [1
    $ D+ d# ?8 o% p) s- d4 M6 ?2 @  A4 |. Y7 _$ R
    Snipaste_2022-05-20_21-49-38
    ! F2 F6 l1 i" |: H2 Q  j9 Y7 q# l% G结果的解读和logistic的一模一样。
    ( j2 l2 S' {  N
      y9 d  y% i% W8 RsurvNRI包4 C+ J' a/ [' a
    # 安装R包- `% E* T! [, [" @1 e( ?
    devtools::install_github("mdbrown/survNRI")2 C4 P3 V7 y1 q! T! G
    13 A' `' b- P9 `7 }
    加载R包并使用,还是用上面的pbc数据集。5 x- K3 `! Q  f6 z: S

    / D  _! R! t  l7 D: C& ulibrary(survNRI)
    0 q, w$ Y* K' N, _, Z# F% k2 v1) S& c9 ^. e! P$ @) \, F
    ## Loading required package: MASS9 K1 j# T1 z: |* Z+ \/ n4 }% I3 C8 m& U
    1
    ) C5 ^& w9 {8 T6 o( a5 `2 ^library(survival)' n! q8 Z! w# k/ \( f

    8 d& [: B6 Y1 ^3 l4 _# 使用部分数据( j7 C8 n& u2 f6 [4 H: p$ D
    dat <- pbc[1:312,]
    9 B. }. n( h9 U- O  M; adat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡$ {, k; @" t& ~% Y  H* h
    6 z1 j8 Q* }+ F0 v5 a' q& u
    res <- survNRI(time  = "time", event = "status",
    ) d) M2 y7 G. z" j5 U/ e! J        model1 = c("age", "bili", "albumin"), # 模型1的自变量
    / R; F% a" a% @/ Q$ ~        model2 = c("age", "bili", "albumin", "protime"), # 模型2的自变量0 k, N4 _% h' ^- g& l, m' T, `+ z
            data = dat,
    2 ]0 J" \/ K  ?3 R' f        predict.time = 2000, # 预测的时间点
    2 t1 h, o6 ~7 ^8 U& @/ s. J4 b$ |* ~        method = "all",
    8 {) d% q1 d: m! F, ^6 b# O        bootMethod = "normal",  # k8 J& s+ G/ }4 ?2 ^
            bootstraps = 500, ; G# I) _+ @0 t- l" o
            alpha = .05)
    8 K' w) H- d/ z6 {% y, O; p
    ' v% [" Z+ B0 `& Z1 K/ h- r13 e8 h/ q& @: Y
    查看结果,$estimates给出了不同组的NRI以及总的NRI,包括了使用不同方法(KM/IPW/SmoothIPW/SEM/Combined)得到的结果;$CI给出了可信区间。
    5 e* o3 M* i7 A3 A8 v6 U
    # d* S6 L& d+ c8 I. X; ?res1 M+ Z1 n9 x, R5 W) i
    17 L! H! L( |( a, H) l
    ## $estimates& b$ u# ~4 T9 A$ B5 v" J4 p
    ##            NRI.event NRI.nonevent       NRI. r% K4 z0 U9 d9 e. w
    ## KM        0.20445422    0.3187408 0.52319518 J7 J2 y  |2 U* z+ j) I8 e
    ## IPW       0.22424434    0.3273544 0.5515987
      ]7 A( h1 v% Y( {) g/ @- r* ^## SmoothIPW 0.19645006    0.3144263 0.51087636 t* q. |4 Q  g; E
    ## SEM       0.07478611    0.2632127 0.3379988( d& o* R& c  O
    ## Combined  0.19633867    0.3143794 0.5107181( \% |7 d, L+ }% h0 [6 b
    ##
    2 ]8 j) j3 H7 O! m## $CI
    - A0 W0 W8 x! E( v1 w7 v2 l## $CI$NRI.event
    / T5 _  |% f% x3 t* a1 H##                     KM         IPW   SmoothIPW        SEM   Combined: m1 ^, z" Y5 D, ?" H7 y
    ## lowerbound -0.03915924 -0.02185068 -0.04724202 -0.1162587 -0.0473723. a: `7 {' D0 R0 R0 `7 c
    ## upperbound  0.44806768  0.47033936  0.44014214  0.2658309  0.4400496% E2 \- `4 k# X  J# T( ~
    ##
    0 b+ K5 c9 }( _3 f% P/ Q2 I## $CI$NRI.nonevent) r5 M4 x- {6 V% O! X
    ##                   KM       IPW SmoothIPW        SEM  Combined
    % O# b2 @7 m, K## lowerbound 0.1317108 0.1396315 0.1286685 0.08638933 0.1286426+ |3 n0 M7 e9 [4 P% Y
    ## upperbound 0.7102251 0.7393216 0.6966341 0.51482212 0.6964549
    - ~) x% s9 W/ C4 F3 E6 I  Z##
    2 A+ }9 B, `0 L* J# _( U) {+ r## $CI$NRI, Z$ o# J" C9 `* z* v1 q
    ##                     KM         IPW   SmoothIPW         SEM    Combined
    2 D, Y% W  {  s% P, @, D% W4 }## lowerbound -0.05112533 -0.04569046 -0.05439863 -0.04132364 -0.054434096 R& H% O  a+ r
    ## upperbound  0.89306122  0.92464359  0.87970125  0.64253510  0.87953153
    ) k( z5 M2 ]0 ]& [5 D* x1 a## 4 V9 W5 ?; S- M4 k; C  w
    ##
    % g0 R2 p" W) p. B& u+ R) D## $bootMethod
    9 q; T# b5 `; D& H/ W8 c## [1] "normal"7 o; u- u! g, V: o; A. O
    ## # ~; x( ^: H1 ], u  [
    ## $predict.time. D* y& Q3 [4 w; j$ U6 @7 z9 z3 Z
    ## [1] 2000
    ! G* b9 Q& M$ E1 |4 h## # |" g+ f/ |3 e% I
    ## $alpha
    ; X3 W  q9 i. `## [1] 0.05: ~% H2 H& }! k
    ## * k8 ~( t  ]( X
    ## attr(,"class")8 n* A" G" Z8 e9 @  [0 `% T& p
    ## [1] "survNRI"% z4 |0 R6 y: e- \

    : G5 G3 s  Z2 r; f2 D3 z# w1 t# }, b1; T  G6 U! L- `8 L; A, Y' I
    OK,这就是NRI的计算,除此之外,随机森林、决策树、lasso回归、SVM等,这些模型,都是可以计算的NRI的,后面会继续介绍。大家如果有问题欢迎在评论区留言。' @* U7 D/ T$ G5 j- r: D

    % Q3 p+ ~; e3 R% Y& \$ {6 K本文首发于公众号:医学和生信笔记
    ! [4 R2 r1 |+ [1 ~3 Q! g1 o5 J1 w' E" Q
    “ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。
    4 L. b3 q% O4 x! g4 s$ G' A本文由 mdnice 多平台发布
    3 J/ @4 L* K7 Z( E5 f- E————————————————' y3 o0 H7 `( o: ~1 W% P8 P" f( ?: q; ]
    版权声明:本文为CSDN博主「阿越就是我」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    + |6 \7 y8 K6 c9 q6 P; m2 t原文链接:https://blog.csdn.net/Ayue0616/article/details/126768006
    ! B9 S9 K  [9 g; [# I$ Q: g5 t& f7 k/ E4 I$ \! A+ N$ _1 B
    3 o$ c5 q$ i0 b- l
    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-6-15 11:25 , Processed in 0.439285 second(s), 51 queries .

    回顶部