QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3069|回复: 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
    ! u& O, s. A* S# P! R
    净重新分类指数NRI的计算: }9 O: U1 N- c" r$ N& A# t
    “ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。7 V3 \3 G' ~# m3 l( ~
    NRI,net reclassification index,净重新分类指数,是用来比较模型准确度的,这个概念有点难理解,但是非常重要,在临床研究中非常常见,是评价模型的一大利器!# K+ |7 R8 o  s! ~' q
    ) q5 t& @4 s+ A' M! {
    在R语言中有很多包可以计算NRI,但是能同时计算logistic回归和cox回归的只有nricens包,PredictABEL可以计算logistic模型的净重分类指数,survNRI可以计算cox模型的净重分类指数。+ Q7 B( n  h' [" J: t  ?8 F5 u
    ' l+ d$ U* Y6 S. c, o- ~) Q4 I
    logistic的NRI
    $ R2 O8 Z, G: M: p/ w! {- j: d6 ^nricens包
    $ i# P0 K$ J5 v1 EPredictABEL包9 I/ D2 ^8 |. z0 s! ]
    生存分析的NRI0 s* s) p% }% c# b0 |4 A
    nricens包1 j5 u; Q2 h/ ~! Y/ q% j
    survNRI包
    ) H+ y9 T$ R$ s3 G. A. n- ~4 j. M/ [9 [logistic的NRI
      j6 t. j* }4 G2 M% c) Rnricens包
    3 f8 p$ r( n% U; \4 o9 Q* L#install.packages("nricens") # 安装R包
    1 h% w9 K$ M- R- r  W5 klibrary(nricens)& d/ J! B2 u3 z- y8 _; r6 y
    1( D* `2 w; w$ [; @6 g
    ## Loading required package: survival. C% L3 _7 R6 y+ |. e3 N. A# A% J! c
    1
    ; F% m4 t& X' G. Y7 i$ ^( K0 u! `使用survival包中的pbc数据集用于演示,这是一份关于原发性硬化性胆管炎的数据,其实是一份用于生存分析的数据,是有时间变量的,但是这里我们用于演示logistic回归,只要不使用time这一列就可以了。1 [  |+ [7 ^/ Q6 v8 r
    - w! |2 @) @: J6 O9 m: E( \  `
    library(survival)
    & U" @/ z) H; }( u# y6 L
    1 I2 r' G0 p. ^/ X- ?0 ?% x9 \# 只使用部分数据, y$ j0 Q. Q3 E" `$ Q
    dat = pbc[1:312,]
    0 g# b( v. ^; ~6 y4 I' l- K5 bdat = dat[ dat$time > 2000 | (dat$time < 2000 & dat$status == 2), ]
    * L; E# k$ \* B  y! Y. D
    4 T5 d6 {, n( ~3 N- F# x- G1 C( O; a& Vstr(dat) # 数据长这样
      @' T! ?9 X: f  V1
    ( D5 x# u: y6 S- L## 'data.frame': 232 obs. of  20 variables:
    2 Z2 h' U, U. U1 F1 D##  $ id      : int  1 2 3 4 6 8 9 10 11 12 ...
    3 B2 ^+ O( o9 X4 O##  $ time    : int  400 4500 1012 1925 2503 2466 2400 51 3762 304 ...
    7 s* ^# X! K$ G3 v% F4 ^" P: d" ^) t##  $ status  : int  2 0 2 2 2 2 2 2 2 2 ...
    1 P3 ~8 `+ ^/ D5 q# F7 u##  $ trt     : int  1 1 1 1 2 2 1 2 2 2 ...' v" ?, v- b2 A' J& a
    ##  $ age     : num  58.8 56.4 70.1 54.7 66.3 ...
    # q' n' ?* g5 p# j3 t8 p##  $ sex     : Factor w/ 2 levels "m","f": 2 2 1 2 2 2 2 2 2 2 ...
    . {. {% R) V+ Y: t##  $ ascites : int  1 0 0 0 0 0 0 1 0 0 ...
    ( ^- |4 T) I+ F) z##  $ hepato  : int  1 1 0 1 1 0 0 0 1 0 ...) ^# n) P3 i' D+ w, W
    ##  $ spiders : int  1 1 0 1 0 0 1 1 1 1 ...6 ~4 Z4 J. L8 r* d
    ##  $ edema   : num  1 0 0.5 0.5 0 0 0 1 0 0 ...7 W- y5 P# a* k* r' n2 I
    ##  $ bili    : num  14.5 1.1 1.4 1.8 0.8 0.3 3.2 12.6 1.4 3.6 ...: @5 A9 {7 Z* |. N3 g& U
    ##  $ chol    : int  261 302 176 244 248 280 562 200 259 236 ...
    - C+ r1 l" ?& d  E##  $ albumin : num  2.6 4.14 3.48 2.54 3.98 4 3.08 2.74 4.16 3.52 ...
    1 d% p& _/ M$ G8 B##  $ copper  : int  156 54 210 64 50 52 79 140 46 94 ...
    0 J+ [9 R" D% A% u0 n6 }4 u##  $ alk.phos: num  1718 7395 516 6122 944 ...% W0 c6 A/ c4 W8 Y$ p
    ##  $ ast     : num  137.9 113.5 96.1 60.6 93 ...
    6 f1 v$ l" R/ n4 e1 [##  $ trig    : int  172 88 55 92 63 189 88 143 79 95 ...
    9 D7 g' i- N- Y! N& Y6 E##  $ platelet: int  190 221 151 183 NA 373 251 302 258 71 ...! f, K/ n* g( [  w$ ^+ O" l' |* i
    ##  $ protime : num  12.2 10.6 12 10.3 11 11 11 11.5 12 13.6 ...) ^- R* P3 m3 z$ K+ N) }4 J
    ##  $ stage   : int  4 3 4 4 3 3 2 4 4 4 ...
    7 I$ V+ Q* ~: R2 Y0 n* w4 O2 m
    3 x7 g% Q/ V% l% O1. [* g' n' }# L  ?5 [/ b  l
    dim(dat) # 232 20
    : q1 |, K: r# k& U* V2 O0 u1  n: w5 C2 b7 F& v' K  U
    ## [1] 232  20
    4 a4 g5 E+ D+ F- b; L1
    , Y( a5 [# g( c. w然后就是准备计算NRI所需要的各个参数。
    % @6 _2 \$ W5 M3 e& H* C
    0 Y. s$ u3 b) |; m" c: v# 定义结局事件,0是存活,1是死亡
    $ F/ P* p, q0 g. |% Y! Q; zevent = ifelse(dat$time < 2000 & dat$status == 2, 1, 0)
      R6 \0 t  u8 n* k2 T3 X6 ?- t9 Q
    " ]4 B3 z0 @2 K8 o; q, C1 Z" Q# 两个只由预测变量组成的矩阵9 v5 b7 v% A6 O( {2 m2 C
    z.std = as.matrix(subset(dat, select = c(age, bili, albumin)))
    2 \  t# k# w" ~' \& mz.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))* e) N3 \( C8 h8 K3 F
    / l: R  o" i& Q( b" N8 z# F+ W7 x
    # 建立2个模型
    0 z0 @3 u/ ~7 P4 smstd = glm(event ~ age + bili + albumin, family = binomial(), data = dat, x=TRUE). s8 Z2 A* A& |# J( y: F% d( i, ?
    mnew = glm(event ~ age + bili + albumin + protime, family = binomial(), data = dat, x=TRUE)$ f* J$ N; L0 Q; c# e( s

    ' T' y8 U# y/ m# 取出模型预测概率
    , d  b9 ^! O* {p.std = mstd$fitted.values; O- v* i* j+ i' H& o3 |
    p.new = mnew$fitted.values
    & F- l! u6 I) S, c' z5 C! i7 |+ M" h6 i
    10 r9 q* {2 J8 ^
    然后就是计算NRI,对于二分类变量,使用nribin()函数,这个函数提供了3种参数使用组合,任选一种都可以计算出来(结果一样),以下3组参数任选1组即可。 mdl.std, mdl.new 或者 event, z.std, z.new 或者 event, p.std, p.new。
    % Q0 q# O6 G6 q$ Q1 F& M9 C7 Q7 V3 |
    # 这3种方法算出来都是一样的结果
    0 {  x( T% V5 y+ c" L. B; P; C9 m( {' |5 {" f# T2 A2 @
    # 两个模型; [4 T. R0 ]; ~
    nribin(mdl.std = mstd, mdl.new = mnew,
    , _; ~: n% L( |, N       cut = c(0.3,0.7),
    " r7 x$ A) O$ B$ ]* p5 n$ [       niter = 500, ; X6 ~  D! [, c$ \4 S; Q# D1 I$ L
           updown = 'category')
    0 \* m5 L" v; T% L  [6 U8 `7 n; o- ~) d4 T
    # 结果变量 + 两个只有预测变量的矩阵
    # u; ~' w  L: Z2 D& Inribin(event = event, z.std = z.std, z.new = z.new, # G  L3 a- B3 T! U; v
           cut = c(0.3,0.7), + |4 ~. W9 }# y
           niter = 500, . r9 |6 n; h, ]! v+ f
           updown = 'category'), J6 H# ^: n7 i2 j( X: b9 R4 X( z
    ; r& P6 Y- Z$ U8 {# Z  {: U
    ## 结果变量 + 两个模型得到的预测概率
    8 f2 z% Z4 t) _* K+ _- _9 a. wnribin(event = event, p.std = p.std, p.new = p.new, 6 y9 B# G1 ~) p' T  Y* G
           cut = c(0.3,0.7),
    / _/ f- h3 @0 A+ p$ Y8 z       niter = 500,
    3 y" M6 _  i, B5 _1 E8 h$ q. k       updown = 'category')
      \) _( a0 p! F8 i" v+ v6 U
    / ?( t0 v& m8 q; c+ s( E1
    % O$ M& N% N: C& ]7 X7 @其中,cut是判断风险高低的阈值,我们使用了0.3,0.7,代表0-0.3是低风险,0.3-0.7是中风险,0.7-1是高风险,这个阈值是自己设置的,大家根据经验或者文献设置即可。( l+ b8 @) e- {, y7 w# U
    1 A  F+ L8 @; M! C+ f6 I/ U: U
    niter是使用bootstrap法进行重抽样的次数,默认是1000,大家可以自己设置。
    : F4 `' ~9 w8 N2 o( E5 c' s$ `  T' i- X4 W# M/ [: ^& i- X& y
    updown参数,当设置为category时,表示低、中、高风险这种方式;当设置为diff时,此时cut的取值只能设置1个,比如设置0.2,即表示当新模型预测的风险和旧模型相差20%时,认为是重新分类。2 a( m8 V) w+ {7 N4 S2 J9 a
    7 \$ H4 U. l6 p0 V9 X0 ~, _
    上面的代码运行后结果是这样的:
    " V1 ?4 d- v% F! Y4 r6 z, y; y, f5 e2 {0 M9 y. b
    UP and DOWN calculation:
    + Z" K1 n3 c2 N3 Y' ?- B  #of total, case, and control subjects at t0:  232 88 144
    * z3 |( E! X8 c. M& v5 x
    $ m6 D! x, f$ N& O0 z3 i1 d* g  Reclassification Table for all subjects:: H  V# R, Q" T0 k  p6 `
            New+ X" _) Q1 l, [2 w. M
    Standard < 0.3 < 0.7 >= 0.7
    6 |, @* w) H  i  q  < 0.3    135     4      0- T) ^# M9 [2 V3 j- q* C
      < 0.7      1    31      4
    8 A. E8 g7 q) }( T2 d  >= 0.7     0     2     55+ y) G5 h. L6 B) ]

    ; \6 v% _; t1 }2 |/ m  Reclassification Table for case:/ W& s4 y) b# q3 H, T
            New
    6 s* t, M7 ]% w% A3 {5 z. s$ {Standard < 0.3 < 0.7 >= 0.7! N) Q9 h# A' c8 C& C  W
      < 0.3     14     0      0
    " F4 X3 i: c. @, u, c: I  < 0.7      0    18      3
    3 c' b" d6 Z' {  >= 0.7     0     1     52
    + U5 W' F% U" ]6 ^+ A& d2 T& d+ ~& u/ T0 o% |/ G! X1 c
      Reclassification Table for control:
    & P+ i: i4 S; f7 {9 ]1 J8 S2 K        New
    ) ^* x  k" w, ^* M+ F# mStandard < 0.3 < 0.7 >= 0.7
    5 K) A2 b7 u2 ~$ P2 o4 e  < 0.3    121     4      00 f" b8 i& V, s
      < 0.7      1    13      1
    5 Z# J/ e4 Y  i  >= 0.7     0     1      31 M3 ^) g- E' Q- J0 J4 [

    9 L$ v9 l$ _/ B# bNRI estimation:
    ' o: ?8 z% k; }0 q3 N; FPoint estimates:( U) t+ w7 O1 F- y
                      Estimate( X8 G4 t5 T) V& T* J. i2 u: P
    NRI            0.001893939
    0 f% a: m/ j9 DNRI+           0.022727273
    * D  P# {! B% @! HNRI-          -0.020833333- D5 Q$ ~; w$ ~
    Pr(Up|Case)    0.034090909& m5 u1 r0 \5 E' r: R" }8 ?7 B
    Pr(Down|Case)  0.011363636
    0 S/ `. |* J7 D* Z. EPr(Down|Ctrl)  0.013888889* c5 M4 e$ o8 ?' g1 m! Z" d
    Pr(Up|Ctrl)    0.034722222; X% O; E2 E! R6 Y' S  V
    $ v" A8 [( ]. p& s' v
    Now in bootstrap..2 {% V( I, c; v# s# h3 x& B* B) H

    " p- C  q- A- ?( u! s3 a" w7 t. fPoint & Interval estimates:! y* j( {: A" p* Y
                      Estimate   Std.Error        Lower       Upper
    1 i; J2 W& d9 I% o$ c' }! D) pNRI            0.001893939 0.027816095 -0.053995513 0.055354449# N' @. K7 [7 ], C. x
    NRI+           0.022727273 0.021564394 -0.019801980 0.065789474$ r8 ^9 y* m% p4 M+ B
    NRI-          -0.020833333 0.017312438 -0.058823529 0.007518797
    1 B& K9 u& x+ D4 N4 D! OPr(Up|Case)    0.034090909 0.019007629  0.000000000 0.072164948
    2 p/ t$ @# {+ l. f5 UPr(Down|Case)  0.011363636 0.010924271  0.000000000 0.039603960
    ! b+ I5 L0 }: d. OPr(Down|Ctrl)  0.013888889 0.009334685  0.000000000 0.035211268
    6 |: G+ r% E% EPr(Up|Ctrl)    0.034722222 0.014716046  0.006993007 0.0661764718 A# e. M9 R4 q5 Z

    ! S+ X1 j0 N; n0 d11 k# S8 d4 c" [. m) R4 N" w
    首先是3个混淆矩阵,第一个是全体的,第2个是case(结局为1)组的,第3个是control(结局为2)组的,有了这3个矩阵,我们可以自己计算净重分类指数。
    . o3 q5 u8 I1 a% Z
    / G  e' q0 U7 e& R# @看case组:
    - s9 x: x& t0 {- `
    + V; S0 c6 K7 u& p  |净重分类指数 = ((0+3)-(0+1)) / 88 ≈ 0.022727273, c' H# u& R# U6 }& c6 V2 x& Y

    ( J$ u, Q  ]* ]再看control组:
    ( v- u/ V9 n( \) R5 i, H2 [. }4 r, w
    净重分类指数 = ((1+1)-(4+1)) / 144 ≈ -0.020833333+ y& B$ X5 v# e4 x. h% h# h) n9 ^
    $ [7 l) X4 G; g+ w9 n
    相加净重分类指数 = case组净重分类指数 + control组净重分类指数 = 2/88 - 3/144 ≈ 0.0003156575 v; M$ A3 r, g( r
    / K# t# v( U0 k9 Z1 c; _8 K
    再往下是不做bootstrap时得到的估计值,其中NRI就是绝对净重分类指数,NRI+是case组的净重分类指数,NRI-是control组的净重分类指数(和我们计算的一样哦),最后是做了500次bootstrap后得到的估计值,并且有标准误和可信区间。( k0 B7 g' o  O% J% v

    3 d0 }( g6 Q2 K最后还会得到一张图:# m1 F" M8 M% g7 ~' R
    . H; K0 h9 w+ x) Z  \, w
    这张图中的虚线对应的坐标,就是我们在cut中设置的阈值,这张图对应的是上面结果中的第一个混淆矩阵,反应的是总体的情况,case是结果为1的组,也就是发生结局的组,control是结果为0的组,也就是未发生结局的组。
    . `) t$ h4 t. r5 u6 m7 x3 Y* J
    5 x& {% P9 q1 m: LP值没有直接给出,但是可以自己计算。* w4 D+ L: F. ]

    4 u. ]: P" ~% H& H1 S3 [5 B# 计算P值$ _4 t* J( M0 E0 Z5 s$ m
    z <- abs(0.001893939/0.027816095)
    5 J: X2 E9 b8 @+ f0 k' W2 @p <- (1 - pnorm(z))*2* {8 D0 K+ c. s: f
    p
    + {3 L. ]! p+ o8 B$ b1& o3 |. _# l3 \$ ^! i8 G9 o
    ## [1] 0.9457157
    1 L1 _3 ~9 T( [( e" V14 W: l" _& H7 d$ s# _& o4 K
    PredictABEL包9 K# `9 E1 x1 |6 T' G& ]9 }
    #install.packages("PredictABEL") #安装R包9 u! Y1 X2 u4 n- n# w: ?) t
    library(PredictABEL)  2 Y4 Y' m9 }6 e, i# o8 }' b$ @! D# [
    & U& X3 f- f3 y
    # 取出模型预测概率,这个包只能用预测概率计算
    - x# }* C3 j: m" v) Pp.std = mstd$fitted.values
    ! [; V+ ?8 ~' G" ~- }& s  P* Mp.new = mnew$fitted.values
    ( b( ^; m3 S6 X& o* p1 O: a% ~, y1* z1 o; A6 v; G2 H. l+ N
    然后就是计算NRI:1 |% V2 F9 q% }, {9 v; {! r
    5 a7 p: \6 _- M& n9 R
    dat$event <- event& u. s+ @% A, a3 V" m$ B$ i2 t* S6 z
    8 B7 n$ N1 j1 x4 I, a, ~
    reclassification(data = dat,
    2 a/ x2 L1 ]7 S: q                 cOutcome = 21, # 结果变量在哪一列; _5 }: d9 f3 u: |. W4 R
                     predrisk1 = p.std,1 ?% W8 x8 B% W  P5 _% N% `+ T, [
                     predrisk2 = p.new,# y" L7 p0 N1 T* Q3 H4 _' m6 @
                     cutoff = c(0,0.3,0.7,1)0 B  i5 S0 e5 a: [
                     )
    ; J1 ~! c, D; ?6 U$ ?1
    ) ?/ M) [( U9 ~+ y( X##  _________________________________________6 V1 E: P. H8 s) h! z! Q
    ##  " S+ x" R  a4 Q, w0 R
    ##      Reclassification table   
    2 T' |6 b9 r0 e( ^/ @# @4 E8 N0 u+ Y##  _________________________________________0 u9 f3 I- G/ Z) [7 G1 }9 j/ K0 Z
    ##
    # m1 A0 z7 Y( E& S* {##  Outcome: absent
    ( z/ @- f" N8 [8 M3 U##   9 Y. e4 l+ g, n/ D. |+ s  E/ H) J
    ##              Updated Model. e. b* ^$ R% D8 Q, F6 c
    ## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
    : R/ ?- R( w3 {, @  B/ G##     [0,0.3)       121         4       0               3
    & o9 t- D- h5 l$ Q  Y" d1 x, ]##     [0.3,0.7)       1        13       1              13( K. Y. K0 N# k
    ##     [0.7,1]         0         1       3              25
    ! W8 c/ U) s# u- K1 P$ `/ `+ ?- [* {## 5 L  Y- x+ y# h5 e# b5 d8 b
    ##  % U; r/ Z' ?& q  l% _9 a  |: g
    ##  Outcome: present
    & Y  N3 D+ y& K  p+ Y: F##   
    : }& [; W1 z( ~" f##              Updated Model- M3 S9 K& I/ |9 z
    ## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
    % T7 w5 i; p. `' S( m##     [0,0.3)        14         0       0               0
    & ^! d; p% o, _# h: {/ p/ g' a; ?##     [0.3,0.7)       0        18       3              14( D4 S1 a' {/ a# Z; ?
    ##     [0.7,1]         0         1      52               2
    4 U5 E9 X' `7 U9 x& q## 2 f( }2 V1 n/ A0 `3 P7 R2 e1 M7 ]
    ##  3 r2 n& m$ E. m; E
    ##  Combined Data
    ! l% ]: e5 ^# M##   
    # p2 `5 \( P1 I7 n; O9 b##              Updated Model
    + a0 H0 R* D2 Y3 y9 j) t## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
    - H7 n5 [; V+ S- p6 q3 Z7 Z##     [0,0.3)       135         4       0               3
    8 G$ X  H# X# s4 J##     [0.3,0.7)       1        31       4              14
    ( N7 |) r2 ?- C6 n) W9 D##     [0.7,1]         0         2      55               46 a; ?! O- o! y4 m
    ##  _________________________________________
    9 l" s* u5 F7 U' G## $ q7 H0 n' Y/ D+ H& V) T
    ##  NRI(Categorical) [95% CI]: 0.0019 [ -0.0551 - 0.0589 ] ; p-value: 0.94806 1 C2 Y& m) W+ H( Q: h1 H$ g* _
    ##  NRI(Continuous) [95% CI]: 0.0391 [ -0.2238 - 0.3021 ] ; p-value: 0.77048
    8 Q) y+ H& j0 ?  L& O8 }7 U##  IDI [95% CI]: 0.0044 [ -0.0037 - 0.0126 ] ; p-value: 0.28396
    " Z" h. Y& P# H7 i9 H
    + r# B7 E' v$ F" W/ }1
    8 r; x( Y; Z* [! j结果得到的是相加净重分类指数,还给出了IDI和P值。两个包算是各有优劣吧,大家可以自由选择。
      B, f& i1 ~* N
    " D4 t, H7 Q, [2 O生存分析的NRI
    7 O7 O1 a! z! g" i& Q4 B" _8 f  T/ k; z还是使用survival包中的pbc数据集用于演示,这次要构建cox回归模型,因此我们要使用time这一列了。1 ^. z  m: K& ?( W8 }" D/ h% f  L

    ' O  a! Y6 p' J8 v' a% Gnricens包
    + N2 w% x* I0 A4 Y/ m6 E) xlibrary(nricens)
    ' l. D: P6 J% L* ~8 H5 zlibrary(survival)
    . P% C/ V8 i# E" @
    - X0 J5 H: K$ |dat <- pbc[1:312,]
    & c. n5 h) B4 v/ [) s) O1 C) x& m3 cdat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡* r& Y2 [6 N- R6 P% i; x, O
    1
    - b, _- L4 ~1 R! _# j2 _: L$ o/ `7 _: _然后准备所需参数:
    $ a7 H- u$ v6 O9 A& L# x1 x4 k  f6 J' t, l& [, z
    # 两个只由预测变量组成的矩阵7 G  ~' W: P, F
    z.std = as.matrix(subset(dat, select = c(age, bili, albumin)))- S  E7 ~+ [  v  o/ ]* i$ b- y
    z.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))
    2 t' M- V5 P, k  y! D1 x! `1 r6 }- \
    # 建立2个cox模型
    1 j5 G: S* t) f  w+ Xmstd <- coxph(Surv(time,status) ~ age + bili + albumin, data = dat, x=TRUE)! L5 u; N& q" @' B2 ~6 I; X. d6 M3 Z: j
    mnew <- coxph(Surv(time,status) ~ age + bili + albumin + protime, data = dat, x=TRUE)
    + i( \9 L; \9 G* j( D/ ^8 F' F; B1 T1 F/ e' O5 T
    # 计算在2000天的模型预测概率,这一步不要也行,看你使用哪些参数: N$ \: c/ D' A# c  k
    p.std <- get.risk.coxph(mstd, t0=2000)! V! b& k6 g% t& j0 I2 Z
    p.new <- get.risk.coxph(mnew, t0=2000)/ F3 [- {! G7 `0 K4 J" i
    1
    - g8 c" A# X3 y3 B) X8 b1 ], o1 V计算NRI:7 Q, i- D& x, O* u2 }/ M

    * [# C5 w5 \- ~8 V: ]* m! G) znricens(mdl.std= mstd, mdl.new = mnew,
    # p( d" {/ p. q; x: C) l5 Z7 T        t0 = 2000,
    6 {' W7 o! M2 `& F        cut = c(0.3, 0.7),
    , b1 |; r2 R  g# E        niter = 1000, : m7 ]6 R& ?7 i& v
            updown = 'category'): V" z( ^: p6 ]
    2 N! a9 S: ^8 n
    UP and DOWN calculation:
    # ?$ I; R- ~, ~2 @. }8 N  #of total, case, and control subjects at t0:  312 88 1440 z& W% H1 N) `7 E9 R9 g

    ) c2 D( }9 J: O5 G6 j; g4 q  Reclassification Table for all subjects:
    5 u( q" T# \  i        New
    & V, v) E/ |2 b+ e) w% HStandard < 0.3 < 0.7 >= 0.79 u, v) S* G3 ^% G  {* R2 ^6 i) e
      < 0.3    202     7      0
    7 v9 x' p5 j4 [2 U3 X; I7 M  < 0.7     13    53      6
    ) w0 Z) P: A- @' [3 Z' k  >= 0.7     0     0     31+ U4 r0 Z4 d  E5 M5 S  V  R

    . |0 B) L9 [1 [& ~  Reclassification Table for case:% ]4 d* b2 J2 ?! ?+ T; r/ L
            New
    - `  b) O6 ]( K5 a0 K( g2 ]Standard < 0.3 < 0.7 >= 0.7
    + u  g* c( Q/ J. O. O  < 0.3     19     3      0
    6 `- u! J5 c# n( n% a& s  < 0.7      3    32      4
    - t8 o# m& K7 C6 z' o& P  >= 0.7     0     0     27& {4 I/ c) z! ^- E9 V5 k
    " Z) t" M9 c2 ?
      Reclassification Table for control:
    ( U- f2 G$ k) \& C        New
    2 r" d. J* l2 u) H" ?Standard < 0.3 < 0.7 >= 0.7
    " m/ ^* S7 n9 `+ K6 q/ Q! {  < 0.3    126     3      0
    3 C, n; o6 Z9 B$ J  < 0.7      5     7      2
      q; @! i3 |/ W, _, y/ i  >= 0.7     0     0      1
    ; |  U7 S+ A4 Q0 G: W2 A& ]
    + f' X( d9 V- l, C4 fNRI estimation by KM estimator:
    * D) d8 n; U% T1 r' i* o! i$ F; X4 }0 M
    Point estimates:+ k( C3 M0 o8 m. B( I
                    Estimate
    & `$ b; @* z) ~. ?4 [2 aNRI           0.05377635
    1 }; ^: g$ f/ R) k# qNRI+          0.03748660
    ( E% r; T. m- a( K3 kNRI-          0.01628974
    : t" E$ y' s' [" X/ d% OPr(Up|Case)   0.077089380 ]" N2 Q! i" z3 x/ _
    Pr(Down|Case) 0.03960278
    2 Z% U6 m) w; ]' F" q8 V. Q3 q" wPr(Down|Ctrl) 0.04256352: u+ T. `0 x% C2 x4 m( P
    Pr(Up|Ctrl)   0.02627378
    9 L* k+ E$ q/ j, w2 v! j9 G$ c& H% a7 A% d+ D2 U% T* o
    Now in bootstrap..
    + |) X5 c5 z) q8 |( n
    ; a# ^* Z5 ^% d2 E+ iPoint & Interval estimates:1 e1 d  K8 }- w0 d! F0 V1 }" T
                    Estimate        Lower      Upper
    ' F, D1 Z& _: d0 ^, k) lNRI           0.05377635 -0.082230381 0.16058172
    8 Z1 x, `/ }9 F; w1 E+ E- eNRI+          0.03748660 -0.084245197 0.13231776# j) p  W2 E" Y# e- m" c3 Z
    NRI-          0.01628974 -0.030861213 0.06753616
    * ^7 \. h' E; D$ VPr(Up|Case)   0.07708938  0.000000000 0.19102291
    - b+ o- b( N1 m. p8 q! R' n* EPr(Down|Case) 0.03960278  0.000000000 0.15236016: H: e6 T# e; Y0 S; {0 T# j' b
    Pr(Down|Ctrl) 0.04256352  0.004671535 0.09863170
    * w9 p+ p; O6 U- Q" u1 sPr(Up|Ctrl)   0.02627378  0.006400463 0.059984247 T# u+ ?. e9 [

    2 \# Z0 k' X! o5 n2 Z" b4 W1
    % d- z, P0 K! e; F! ~! G0 [4 M9 L4 Z$ k9 ~
    Snipaste_2022-05-20_21-49-38
    ! y, M1 u" C: p; Q' g5 k! ^结果的解读和logistic的一模一样。% w  R3 a, y& S9 B/ W  y
    " q3 a1 U/ I0 ^; @( [# q* t# o: V
    survNRI包
    % A+ }& l7 V' i! C( W) W  G% m7 k# 安装R包; o( Y. ~! V- R( g
    devtools::install_github("mdbrown/survNRI")
    7 |- _: n( d* f! N! ?( v8 }18 \0 {  y3 t( b4 ?
    加载R包并使用,还是用上面的pbc数据集。4 ~& y$ o  m  i
    & _% _! B  C! C2 u& l
    library(survNRI)
    / t% t, ?- B" p/ Y* s1$ w5 o" x# O' X. I1 {% u; O9 p* a
    ## Loading required package: MASS1 @( D; w- E# s- t9 ~' M
    10 ?4 F5 m5 h+ [& d3 |
    library(survival)
    " j* V# y: o# H6 e' L
    - Y9 a/ k1 K8 z/ a* \! Z2 r, ^# 使用部分数据
    / R0 W, j( Y% C% O# zdat <- pbc[1:312,]
    4 }, Q1 p. T1 x+ ~) J2 Odat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡
    & @0 ?$ b3 y' o% e
    % U9 M9 Z. }- M* w8 m% k% Nres <- survNRI(time  = "time", event = "status",
    0 M' J2 {: c% k& q& H. h  q2 ]4 J0 a* T        model1 = c("age", "bili", "albumin"), # 模型1的自变量
    : ]* T3 r, h) |1 ^        model2 = c("age", "bili", "albumin", "protime"), # 模型2的自变量' v1 D1 W% u* @3 f, H# ]
            data = dat, ; H3 n1 o/ S2 }" N
            predict.time = 2000, # 预测的时间点; J; M$ C/ z' r* f1 ]: U; M
            method = "all", % A# J; ~( X; P# A6 Q% ]( ?
            bootMethod = "normal",    [0 y+ ~- N8 g- H" A7 l
            bootstraps = 500,
    + _+ Q% |* C! G, v        alpha = .05)
    . I2 s; h) v5 ^! L! k: V7 C
    & x4 g. H5 _5 x14 p1 m- j) l" R6 g1 w
    查看结果,$estimates给出了不同组的NRI以及总的NRI,包括了使用不同方法(KM/IPW/SmoothIPW/SEM/Combined)得到的结果;$CI给出了可信区间。
    , E, \% A- z: t  X5 t9 z! Z" ~/ E1 p, x7 X( }, n+ `
    res) ?! o' ?) G2 v7 A! T" R$ o
    1
      }& l. T; X1 z! T## $estimates" w9 K! }4 y+ C0 B. |2 c& _
    ##            NRI.event NRI.nonevent       NRI
    9 W' f% y% \6 s5 B## KM        0.20445422    0.3187408 0.5231951
    . R3 ~# }7 s% f+ z## IPW       0.22424434    0.3273544 0.5515987$ z$ G' [3 F( R, k; o8 [7 E
    ## SmoothIPW 0.19645006    0.3144263 0.5108763: L; L! P( j0 J9 u( x; `" k& Z
    ## SEM       0.07478611    0.2632127 0.3379988
    # O: H" I2 j; X9 `# e: {6 \1 m$ M## Combined  0.19633867    0.3143794 0.5107181
    ! |% T2 k) Z, s( N6 U! ~## 0 W# e0 ]" U8 D4 B3 O3 Q
    ## $CI
    ' [5 f0 a1 M9 c. e, l## $CI$NRI.event
    3 M( i+ C% a7 G: f0 H; W##                     KM         IPW   SmoothIPW        SEM   Combined  W0 B/ H( _& }' Q  }+ S- F- e
    ## lowerbound -0.03915924 -0.02185068 -0.04724202 -0.1162587 -0.04737231 Z7 W4 F2 Z1 j6 P  Y, E
    ## upperbound  0.44806768  0.47033936  0.44014214  0.2658309  0.4400496
    - _5 c# [" h- M##
    ' G; k: c& ~8 N3 Q# V## $CI$NRI.nonevent
    ( J1 y9 @0 `9 O##                   KM       IPW SmoothIPW        SEM  Combined
    6 y; O1 y" r" F## lowerbound 0.1317108 0.1396315 0.1286685 0.08638933 0.1286426
    0 c, Z/ [9 k) K( f, a## upperbound 0.7102251 0.7393216 0.6966341 0.51482212 0.6964549
    % a2 Y6 T3 O1 w& ]3 @" E# p& P## 8 K2 x* `# {* m: V- ?4 x
    ## $CI$NRI7 E: w, l; `/ X
    ##                     KM         IPW   SmoothIPW         SEM    Combined
    * c) s' k, s! k. @8 G" |7 [  d## lowerbound -0.05112533 -0.04569046 -0.05439863 -0.04132364 -0.05443409( O0 }$ ^7 E# m; [4 t
    ## upperbound  0.89306122  0.92464359  0.87970125  0.64253510  0.87953153
    " R( H( i+ w( B$ }##
    1 ?4 s! D# R1 d. c! v0 {6 `. d##
    # j) [" e6 D, w+ g3 o4 q## $bootMethod% I& c) }% ~9 ]: F- V
    ## [1] "normal"3 s8 R6 T8 x) e/ U6 R
    ## 3 ?' {; ~( K# `; ?6 M
    ## $predict.time0 X# o! p8 K8 k
    ## [1] 2000: O' v) z" V. L, \
    ## : [3 H1 ]2 V+ n) g2 m2 e- g
    ## $alpha6 n, d# t2 n9 H5 \* j0 p) f. `
    ## [1] 0.055 V  n. u1 K4 H0 t: b
    ##
    7 j5 W: y& I8 R" _## attr(,"class")
      e! q* J( S9 y. a# h+ A1 T7 t% K## [1] "survNRI", W- s' M- B5 I% v6 t
    0 B& Y9 F2 q6 I7 {1 w/ A
    1* r+ y! \- U7 w- O: P
    OK,这就是NRI的计算,除此之外,随机森林、决策树、lasso回归、SVM等,这些模型,都是可以计算的NRI的,后面会继续介绍。大家如果有问题欢迎在评论区留言。
    - @/ C5 f& Y; N# ^! @& u, c; W: l, X* ?+ Z
    本文首发于公众号:医学和生信笔记+ x/ B( a( l* s- p, P& S
    $ `$ p8 ~1 i; |
    “ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。$ e+ Y3 z4 T5 V3 N/ J3 ~$ i
    本文由 mdnice 多平台发布
    . I; r; T, L. T* t# n1 a$ O# P( G————————————————
    ! V( u6 f. d6 ^+ a6 J8 _- @. a版权声明:本文为CSDN博主「阿越就是我」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    + D# N4 ]: C' c2 P+ a. y1 Y* u5 I+ C原文链接:https://blog.csdn.net/Ayue0616/article/details/126768006
    ) e3 z  w% T6 U# _" J, Q5 B8 q( L/ c5 S/ f$ e( J) p

    + R+ J6 a1 D. B$ p4 K+ ^
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

    关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

    手机版|Archiver| |繁體中文 手机客户端  

    蒙公网安备 15010502000194号

    Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

    GMT+8, 2026-7-9 22:19 , Processed in 0.481934 second(s), 51 queries .

    回顶部