QQ登录

只需要一步,快速开始

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

    3 N, S! `3 T) v# s9 h+ g净重新分类指数NRI的计算, w3 r- {8 O( Z
    “ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。
    ; x3 z1 b1 t$ c' o+ u# tNRI,net reclassification index,净重新分类指数,是用来比较模型准确度的,这个概念有点难理解,但是非常重要,在临床研究中非常常见,是评价模型的一大利器!1 O& e: d9 v7 t2 v
    , Y: B/ Y# R' \1 D/ m- W: ]4 J
    在R语言中有很多包可以计算NRI,但是能同时计算logistic回归和cox回归的只有nricens包,PredictABEL可以计算logistic模型的净重分类指数,survNRI可以计算cox模型的净重分类指数。
    # v+ i' i+ w* _( t% f
    / q: m/ k4 I: qlogistic的NRI
    . X5 ?( Y9 Y8 M) \/ enricens包& C4 O( E6 m: q# K- Z+ w
    PredictABEL包
      t- m0 i+ L# N) D& _% V8 v生存分析的NRI
    , o9 ~, T; @6 c# j) `nricens包- J% `( s' Y: u+ {! W3 y- Z
    survNRI包
    1 z5 {) ~- x) `; ]( c  a9 ?logistic的NRI
    # x* H2 D4 |+ B0 B, u. [9 U% Qnricens包
    $ ]: P; d0 n  p#install.packages("nricens") # 安装R包& r" a1 g  w$ X5 }8 Q3 w+ {1 v
    library(nricens)
    9 D2 {. R3 L# z) g' a+ ?  R1$ w/ {& m; y% h/ t# k5 {" b
    ## Loading required package: survival
    0 w0 E( d0 t% o1
    " ]- f8 `1 t+ @' Z% J. t" c使用survival包中的pbc数据集用于演示,这是一份关于原发性硬化性胆管炎的数据,其实是一份用于生存分析的数据,是有时间变量的,但是这里我们用于演示logistic回归,只要不使用time这一列就可以了。
    6 P$ w) K7 m9 X1 I/ C
    2 q$ C; [6 U: O) H/ q( @: Ylibrary(survival)
    ; B& H- E7 F( g! z8 Y/ g! p
    0 E" Q9 |$ {, l+ S# 只使用部分数据
    ( C" M0 y/ i5 j- x- G% [dat = pbc[1:312,] " `  ]. q" s" g' N6 Z/ D
    dat = dat[ dat$time > 2000 | (dat$time < 2000 & dat$status == 2), ]4 S  G6 m( m5 y1 R% v4 A2 n
    8 |7 }7 S( ]8 H) x* r$ O% n8 Z
    str(dat) # 数据长这样
    * ]0 q  r" E+ d7 f* V8 }; Q, T1& q. r7 P- V  E- p- [2 ]5 N1 q
    ## 'data.frame': 232 obs. of  20 variables:
    3 _. @+ g" t# s##  $ id      : int  1 2 3 4 6 8 9 10 11 12 ...
    ' H. {/ L' ^  O6 h4 k% T##  $ time    : int  400 4500 1012 1925 2503 2466 2400 51 3762 304 ...
    + j1 U& e" A" t$ W& ^! n##  $ status  : int  2 0 2 2 2 2 2 2 2 2 ...
    ) W& v8 M' A6 T: a& v4 }* m% i##  $ trt     : int  1 1 1 1 2 2 1 2 2 2 .../ l2 j, b  E6 Y
    ##  $ age     : num  58.8 56.4 70.1 54.7 66.3 ...& Z7 I; g3 u3 x4 z
    ##  $ sex     : Factor w/ 2 levels "m","f": 2 2 1 2 2 2 2 2 2 2 ...- ]6 Y- Q+ Q5 w1 M$ i; R* c5 [
    ##  $ ascites : int  1 0 0 0 0 0 0 1 0 0 ...4 H  f6 e' t* F! {( ^
    ##  $ hepato  : int  1 1 0 1 1 0 0 0 1 0 ...! |7 U( }# M0 o7 ^. w
    ##  $ spiders : int  1 1 0 1 0 0 1 1 1 1 ...
    % ~0 a; @5 Z9 h1 q* g* C* K##  $ edema   : num  1 0 0.5 0.5 0 0 0 1 0 0 ..., P/ [: f. j: \. L* P: D; Q
    ##  $ bili    : num  14.5 1.1 1.4 1.8 0.8 0.3 3.2 12.6 1.4 3.6 ...+ W3 d+ c/ I' W+ A
    ##  $ chol    : int  261 302 176 244 248 280 562 200 259 236 ...
    5 Z( d, u3 Q: p5 k  U, ]1 R6 [##  $ albumin : num  2.6 4.14 3.48 2.54 3.98 4 3.08 2.74 4.16 3.52 ...# w' u" m5 R& S" p
    ##  $ copper  : int  156 54 210 64 50 52 79 140 46 94 ...
    3 L. ~) A6 s7 i4 p  ?+ a##  $ alk.phos: num  1718 7395 516 6122 944 ...4 n( D! b  k4 t8 Z$ b9 y. o
    ##  $ ast     : num  137.9 113.5 96.1 60.6 93 ...& \/ J, d# S5 I  D
    ##  $ trig    : int  172 88 55 92 63 189 88 143 79 95 ...
    1 v  {. U: |7 E* `##  $ platelet: int  190 221 151 183 NA 373 251 302 258 71 ...
    ( V% z9 {  y% v$ U2 T* T9 @##  $ protime : num  12.2 10.6 12 10.3 11 11 11 11.5 12 13.6 ...9 |! U5 I7 K3 `$ a
    ##  $ stage   : int  4 3 4 4 3 3 2 4 4 4 ...2 S/ T& o6 ]: `1 _. c) b6 K8 d
    $ H% M; a, ?7 e! D1 N3 F9 h
    1" g+ p. ]% t! t+ i
    dim(dat) # 232 20
    . X# Y. G; c& b- {: d& T1 @1
    8 J- q2 I, @' y/ M2 {3 l- ^## [1] 232  207 u; c+ r; i  \3 q" X
    1
    6 T  x2 `' l+ ^4 V# d. A然后就是准备计算NRI所需要的各个参数。" e8 Y& N: p8 @# D

    % D" j7 P% v5 |. p+ U+ j# 定义结局事件,0是存活,1是死亡2 }0 p/ w0 c& U
    event = ifelse(dat$time < 2000 & dat$status == 2, 1, 0)
    : E3 Z! b  I" j# t5 n2 H7 x" [) q& X6 W( m* B
    # 两个只由预测变量组成的矩阵' s: |! m4 m* P! v: v* _
    z.std = as.matrix(subset(dat, select = c(age, bili, albumin)))& J7 O2 ^6 z4 z  N9 X4 L
    z.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))
    4 I7 S( k( }% C3 X1 Z% r3 q7 x. g
    ' o8 I/ n1 t3 d9 w  \# 建立2个模型3 e2 e/ I! ~8 t) W
    mstd = glm(event ~ age + bili + albumin, family = binomial(), data = dat, x=TRUE)
    0 z0 l2 {* i: J& l! S/ `mnew = glm(event ~ age + bili + albumin + protime, family = binomial(), data = dat, x=TRUE)
      C2 {8 P8 }% X5 ^4 C! g: F4 W6 }1 X5 I& n
    # 取出模型预测概率; }" K0 C- e# [: G* F( z
    p.std = mstd$fitted.values  y+ y; D9 E8 q2 m' ]- }
    p.new = mnew$fitted.values& e; `4 t9 p0 I2 |
    + I# y5 F: [8 j# ]3 w9 A7 O7 {
    14 O1 j# Z! [0 X6 ]/ O) X
    然后就是计算NRI,对于二分类变量,使用nribin()函数,这个函数提供了3种参数使用组合,任选一种都可以计算出来(结果一样),以下3组参数任选1组即可。 mdl.std, mdl.new 或者 event, z.std, z.new 或者 event, p.std, p.new。, r; [: D( w, _/ {
    & L8 H2 i4 `+ B1 t* e* I2 A! y
    # 这3种方法算出来都是一样的结果& [; a/ a  Y6 x! U3 b3 f
    % M/ K* ?4 n5 S
    # 两个模型- n* v1 j: k' Q- B) _) Y
    nribin(mdl.std = mstd, mdl.new = mnew,
    0 R. F/ C* {1 f* u# h; ?       cut = c(0.3,0.7), * D: Z8 |1 F' v
           niter = 500,
    ( [9 r4 ~% ?! k% K: S       updown = 'category')
    / m' L9 k- L7 p) o, R
    2 l5 v% f" W+ u+ l: G1 D! H2 |( g# 结果变量 + 两个只有预测变量的矩阵
    # q% C( e9 C- \4 u, R8 U3 u7 Ynribin(event = event, z.std = z.std, z.new = z.new,
    7 C/ m8 M2 ~% v) i  S. |/ j       cut = c(0.3,0.7),
    9 {8 {/ F2 N  Y6 N% [$ v% I       niter = 500,
    + p6 j% M0 _! j       updown = 'category')  d4 v" v- z0 r: r2 N9 M8 w* S
    * C3 o2 h. E* z& o) O. D' |% a) T
    ## 结果变量 + 两个模型得到的预测概率
    / v# A1 @( B7 k1 q2 r2 S1 Qnribin(event = event, p.std = p.std, p.new = p.new, 3 \$ ~* N7 B( p9 C. p" @( D
           cut = c(0.3,0.7),
    " {' M8 V8 L8 P) `7 A       niter = 500, 5 s7 M6 t1 X- X' _
           updown = 'category')! }; z# }( |4 [. |) S. w

    4 Z9 [% ~: ^: W. }" D# F1
    3 w! V9 g6 o; m其中,cut是判断风险高低的阈值,我们使用了0.3,0.7,代表0-0.3是低风险,0.3-0.7是中风险,0.7-1是高风险,这个阈值是自己设置的,大家根据经验或者文献设置即可。2 v* L! C# d, s! L) [
    ; X6 }& n. Y8 G  A# {
    niter是使用bootstrap法进行重抽样的次数,默认是1000,大家可以自己设置。& R; [& y6 b* R8 z
    % h& |, v- Q* p* s2 T# ~
    updown参数,当设置为category时,表示低、中、高风险这种方式;当设置为diff时,此时cut的取值只能设置1个,比如设置0.2,即表示当新模型预测的风险和旧模型相差20%时,认为是重新分类。
    % ~5 h" r( n4 |% s3 _4 e- v- g& J% G* |
    上面的代码运行后结果是这样的:
    * \( W$ b, f9 u. r9 k% G# j3 s
    ) v- t: k* s* q5 \+ X" tUP and DOWN calculation:
    1 z: ~0 a1 }# A  #of total, case, and control subjects at t0:  232 88 144# [. o6 @# B/ N+ q! Q

    % Z5 i* b, t1 y2 z  Reclassification Table for all subjects:
    9 m5 _" x) q+ ?! z5 J. F6 M        New
    0 a. u- e6 s/ q7 |( C- W& _Standard < 0.3 < 0.7 >= 0.7
    ) _/ r+ V0 V  P- B' w3 O  < 0.3    135     4      0
    # I. T8 E) D2 h( F9 ~8 \  < 0.7      1    31      4
    / S% L! ?" G8 F9 t/ z  M2 y  >= 0.7     0     2     553 M6 f: v, N! n

    " S+ Z. h1 G6 J( K/ }- k7 W* `  Reclassification Table for case:: w* @& g4 T! `& ~) f6 D- n. c: h! d
            New
    3 T. w* b1 V6 i0 w8 Q/ n5 f! \4 e/ hStandard < 0.3 < 0.7 >= 0.7
    3 E- M- |, ]7 X( \% S. U3 K* l  < 0.3     14     0      0
    1 y" Q' T; D7 z) e% s# J  Q  < 0.7      0    18      3
    $ I7 P/ {2 M9 I, L9 w$ P  >= 0.7     0     1     52
    ) l4 O8 X9 O* G: w$ p. N/ I5 c. G6 a9 H
      Reclassification Table for control:+ e( U3 D' t- P8 N2 J
            New: s% W# Y( d. x2 ?" p6 m4 a
    Standard < 0.3 < 0.7 >= 0.76 L* S2 S" K8 o$ X$ `% ^& U4 x
      < 0.3    121     4      0$ [4 K$ s$ Z' ]1 O5 _
      < 0.7      1    13      1
    % l) {. z7 D( ~  >= 0.7     0     1      3
    6 V% \1 }3 a$ w1 m
    $ t+ N1 p: S7 |( f  f3 l" D2 h! z/ m2 hNRI estimation:0 w2 n# H0 J7 E' i& v' p) [1 M) w
    Point estimates:" M' Z1 P1 j+ t. g' b# K' X
                      Estimate% W: [, ~( \; O+ k# u
    NRI            0.001893939
    - d6 i% F5 l' KNRI+           0.022727273* g) W, Q0 R* O5 F% @
    NRI-          -0.020833333
    - L/ F6 x9 }1 p% Z/ MPr(Up|Case)    0.034090909
    . L9 v7 A  V* Y& j. |Pr(Down|Case)  0.011363636
    % V. f+ q/ Z) v) ]6 J$ i* SPr(Down|Ctrl)  0.013888889. Y* |0 P( z( ?, g, q+ v
    Pr(Up|Ctrl)    0.034722222
    6 d" J5 \1 B% y5 h; e9 o1 X5 m/ {7 ?; m
    Now in bootstrap..
    1 T) t& j$ \3 m5 ^; p% m
    & w, w' x6 d: H. {; JPoint & Interval estimates:3 D; Z4 A" d4 b8 a9 R
                      Estimate   Std.Error        Lower       Upper" y( w/ O! F% |
    NRI            0.001893939 0.027816095 -0.053995513 0.055354449
    ( z3 G) R) \( x1 W4 Y9 ONRI+           0.022727273 0.021564394 -0.019801980 0.065789474
      ?0 I5 i/ _7 \: g0 yNRI-          -0.020833333 0.017312438 -0.058823529 0.007518797
    * G; W, ^! V1 L, \Pr(Up|Case)    0.034090909 0.019007629  0.000000000 0.072164948' z$ D! p5 p9 v: S: R) v  b
    Pr(Down|Case)  0.011363636 0.010924271  0.000000000 0.039603960
    * u; u' g+ x0 _Pr(Down|Ctrl)  0.013888889 0.009334685  0.000000000 0.035211268+ b' _8 D2 k- l" |$ X+ }) S: n
    Pr(Up|Ctrl)    0.034722222 0.014716046  0.006993007 0.0661764716 X- Z5 R4 {9 Z  T) h7 N

    : ?. h- F8 ~+ `' Z" [2 [$ F$ N1
    $ ?, y  ?2 t5 R' T. C' D首先是3个混淆矩阵,第一个是全体的,第2个是case(结局为1)组的,第3个是control(结局为2)组的,有了这3个矩阵,我们可以自己计算净重分类指数。
      b9 S' D" b' j/ `( P' j
    : c; Z+ t. t! t看case组:
    . I* @" K' q, H1 S. u/ u8 h* @  ]) c* `* Q( ]& }
    净重分类指数 = ((0+3)-(0+1)) / 88 ≈ 0.022727273: {3 p. T. E& Z6 y2 X; @5 u$ ^
    # F4 W9 r" r; p! ]+ }+ m
    再看control组:+ S$ e# t7 U3 C$ G

    / v: s' w* d( F: {; S净重分类指数 = ((1+1)-(4+1)) / 144 ≈ -0.020833333
    / h6 |4 \+ V4 n$ I2 N" p8 y
    / x6 s2 r- n, d9 p" v" ~相加净重分类指数 = case组净重分类指数 + control组净重分类指数 = 2/88 - 3/144 ≈ 0.000315657& H, _( G3 ?# Z

    - O! c# S, ?( Z, Z$ s再往下是不做bootstrap时得到的估计值,其中NRI就是绝对净重分类指数,NRI+是case组的净重分类指数,NRI-是control组的净重分类指数(和我们计算的一样哦),最后是做了500次bootstrap后得到的估计值,并且有标准误和可信区间。
    / {" n  s# k2 q: t. Y1 U( z) O* p
    最后还会得到一张图:
    6 t2 a2 m/ V2 k" |! c( B
    ! \# L) m' ^) N. ~: v+ y+ l这张图中的虚线对应的坐标,就是我们在cut中设置的阈值,这张图对应的是上面结果中的第一个混淆矩阵,反应的是总体的情况,case是结果为1的组,也就是发生结局的组,control是结果为0的组,也就是未发生结局的组。
    * r5 L& Q( R* p  g/ \7 _9 l" y6 a$ o- A# [6 [; O$ S3 R
    P值没有直接给出,但是可以自己计算。6 `& R- k1 [( r; Q/ p

    , l% E/ l3 ?- V% j" W5 I0 o9 E# 计算P值
    7 ^& Q6 S' E+ j9 H% e- `9 |$ Q) tz <- abs(0.001893939/0.027816095)
    1 n. ^: X" @/ pp <- (1 - pnorm(z))*2
    6 G) |% D$ e% \0 w3 Ep
    # {& {) X( _* l; x6 j( A; i1
    7 \+ W) z4 G1 H7 P4 x## [1] 0.9457157
    ; P8 @7 D1 e1 ?6 u! D16 M; j4 w! h5 w, h1 }9 W
    PredictABEL包
    ' o' {! E! |- ]2 N5 j1 h+ K#install.packages("PredictABEL") #安装R包
    : Y* x& R/ L3 L6 ulibrary(PredictABEL)  
    % x9 x7 p8 s0 s9 w/ q; z6 {: m5 S; P
    # 取出模型预测概率,这个包只能用预测概率计算$ s/ i3 E6 W" }& c7 `
    p.std = mstd$fitted.values
    ' A  {) v, _6 Q  a, t( D5 q% ap.new = mnew$fitted.values
    # [; u, }0 ~9 \" a7 T1
    7 A1 {$ V1 i5 W0 j# m( f1 J然后就是计算NRI:7 J' d+ f" U) I7 S
    - g; H) n4 |. e
    dat$event <- event- T$ a' O$ p8 M5 z3 e
    : y; O9 H) C% J8 E
    reclassification(data = dat,
    5 F" I' _$ L- ~9 x                 cOutcome = 21, # 结果变量在哪一列
    $ H5 F) m1 j$ S                 predrisk1 = p.std,
    2 ]7 L; k2 s: P9 r% g# d% j                 predrisk2 = p.new,
    6 H$ A8 O" r; G                 cutoff = c(0,0.3,0.7,1)  R7 o, F: V" h/ m/ k, ^" s
                     )
    " U+ e4 h  K- t3 `12 @! Z, _- \+ W' Z% z
    ##  _________________________________________7 p- P: s5 i  Y
    ##  
    % K  E; |9 }( C) ~) F, Y$ w##      Reclassification table   
    ! u6 o4 c: t& b+ Y$ C##  _________________________________________" J! k/ S& b+ o  Z7 v: X
    ##
    / h+ F  Q0 i6 ~. M0 Q5 b##  Outcome: absent
    ) |4 O: A# e$ d##   # C: X$ N& h: ]6 I1 ]& u
    ##              Updated Model# M* u( b1 [) E' S& z* i3 q( U9 P
    ## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified, b, N+ M! k. j4 L7 g8 W4 a
    ##     [0,0.3)       121         4       0               3
    ( w7 E( u0 i! S& }3 k" m##     [0.3,0.7)       1        13       1              13! J  k$ N3 g* H/ M9 z$ j* [% r
    ##     [0.7,1]         0         1       3              25
    ; w6 K" X: F% [0 N6 g##
    0 B9 p* N0 h( F* I##  . s& T* R) W6 f# \: b, M
    ##  Outcome: present
    ( r5 H4 u7 G9 `' G4 v& z##   
    2 ]- [% \; k/ I  O8 Y! d##              Updated Model8 G3 Q/ f6 \1 c4 r5 F
    ## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
    1 j4 t. q! T  i: e, k0 v2 V( L##     [0,0.3)        14         0       0               0* K$ L7 S% G# d6 t
    ##     [0.3,0.7)       0        18       3              14; p0 `& e3 ~9 h, h$ v( \
    ##     [0.7,1]         0         1      52               2
    ( ]7 z" l6 w  h: b6 L5 N- n& A##
    7 D# i$ t/ Z4 V& t##  
    4 U$ g. T" ^/ T* j. Y##  Combined Data
    " J2 X+ B/ y: u7 a" ]4 u6 @# o##   
    8 D/ d& B9 p9 N5 V6 `+ \##              Updated Model0 R6 [! Y9 n% b' J4 B/ S' w
    ## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified0 p" x/ i  K& V
    ##     [0,0.3)       135         4       0               3
    * l9 g/ h% m2 |/ G2 _/ Z##     [0.3,0.7)       1        31       4              14
      D+ f& ^9 Q! v$ l+ B$ [% v##     [0.7,1]         0         2      55               4
    ) k3 G# m* O% v##  _________________________________________
    . O* R' t" a6 \$ M, J/ q+ s## / t  w1 G/ c7 b
    ##  NRI(Categorical) [95% CI]: 0.0019 [ -0.0551 - 0.0589 ] ; p-value: 0.94806
      i& [6 W7 R# k6 i+ b, M##  NRI(Continuous) [95% CI]: 0.0391 [ -0.2238 - 0.3021 ] ; p-value: 0.77048
    % ]0 @9 i7 {$ F0 Q  S  r% d##  IDI [95% CI]: 0.0044 [ -0.0037 - 0.0126 ] ; p-value: 0.28396; W5 U: Y! q# J+ F9 D7 l- D$ o) \

    7 X% L, \2 \1 \: n1- C: z3 z6 d0 y- u3 Y& K
    结果得到的是相加净重分类指数,还给出了IDI和P值。两个包算是各有优劣吧,大家可以自由选择。
    ( _7 O# K9 F& ^, \' @& x  i# d2 f3 Z* F$ a! J
    生存分析的NRI
    % z: W. q$ E6 O" X$ e6 k0 e+ M" j还是使用survival包中的pbc数据集用于演示,这次要构建cox回归模型,因此我们要使用time这一列了。4 G* N8 E7 F  t' v& |# A! m

    & x# I/ t8 [( f  enricens包  j" @- G# T+ U2 {+ i" g
    library(nricens)! }9 |1 S6 O5 ]! i5 e' f- Q, s
    library(survival)2 w: ^5 f6 h  t0 }/ N3 }! ^
    / m1 O( q5 N: K. s/ d' i4 q
    dat <- pbc[1:312,]
    7 Q5 B( F% k2 i/ H# i; S; {dat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡2 N8 |' `2 ?1 l1 G
    1& |$ T+ @0 N# ^
    然后准备所需参数:! {# v5 _+ {& o9 j/ C

    * k, d* N( G1 L$ W$ o8 s# 两个只由预测变量组成的矩阵
    $ G$ l1 b! V# P! r% O) ^# Nz.std = as.matrix(subset(dat, select = c(age, bili, albumin)))* Y( S  T5 w$ F) P! K9 R) U2 [
    z.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))9 Z9 L: Z6 c, r4 a; F
    ; s; }  a2 a* H: H' i6 X* X
    # 建立2个cox模型" v. }' W0 j' _; Y9 ?
    mstd <- coxph(Surv(time,status) ~ age + bili + albumin, data = dat, x=TRUE)
    ! y2 ]5 S" Y1 D" d( z' Q( C3 r: mmnew <- coxph(Surv(time,status) ~ age + bili + albumin + protime, data = dat, x=TRUE). b' R2 b0 c1 a5 T; P

    1 _+ e" _0 h, s  w  c8 X# 计算在2000天的模型预测概率,这一步不要也行,看你使用哪些参数
    1 k' ~4 {. X" a3 s1 f1 ], J* D$ Fp.std <- get.risk.coxph(mstd, t0=2000)6 M% _) s, u. B5 R. r+ p+ c
    p.new <- get.risk.coxph(mnew, t0=2000)4 `9 O$ L6 v6 H7 T1 ]# J
    1
    $ a% U4 |! M6 x* q; r计算NRI:- d' V' p9 p( V6 s! ^

    / W) y& M3 ]- q; y7 @nricens(mdl.std= mstd, mdl.new = mnew,
    & V4 }9 _; r: w; v3 B0 ^' ^" U& p: r        t0 = 2000, 7 k+ r* j# e+ C4 q  G& ~/ Q
            cut = c(0.3, 0.7),* P1 N2 U1 M! ~% v' C
            niter = 1000, 3 \: S2 q% ~0 a( O7 m3 n
            updown = 'category')
    ( K+ _9 A- C, f
    2 O' l% q3 S8 N* h$ C% [* vUP and DOWN calculation:
    2 k7 V1 P' V1 E0 N  #of total, case, and control subjects at t0:  312 88 144$ U- [7 J$ H& r/ \6 k% W

    ! ?/ h+ t# q0 }* I) a  Reclassification Table for all subjects:
    4 \# @8 b( F- D0 @& R; \/ q        New7 f/ K5 H1 {+ R4 Q, l
    Standard < 0.3 < 0.7 >= 0.7& d9 X/ O2 U' \% ]
      < 0.3    202     7      0
    & I# z/ D$ x& K  < 0.7     13    53      6  z3 d  J. D8 m" [
      >= 0.7     0     0     31
    9 R% i% O6 F$ q+ \  ]1 S4 l9 P( V9 R
    , t4 m$ n9 V9 P3 [# ~8 V+ O  Reclassification Table for case:
      j: S. j5 ^- R# |) w        New
    / ]4 K7 o! h- c6 C% a. `$ t9 `Standard < 0.3 < 0.7 >= 0.7
    ) N3 B2 x9 X" N0 R  < 0.3     19     3      0
    & }) s7 A3 G: d  < 0.7      3    32      4* P1 Z- E- x/ `  k4 U, q8 D# {
      >= 0.7     0     0     27, r0 b! L- l6 N

    3 s4 b& ~( }3 J- w  l+ A6 E/ j  Reclassification Table for control:5 I4 q5 R( b- L$ Y" f- R, S) H
            New
    & Q1 g4 |0 D% [$ [% ^) K! [Standard < 0.3 < 0.7 >= 0.7/ }. l0 M6 ^- O! \) J! `; t
      < 0.3    126     3      0
    ' m- F/ h$ Z5 t  < 0.7      5     7      27 s, V: b  X. B7 Z) o* `
      >= 0.7     0     0      12 E4 \; E% z/ H2 P3 e
    1 @  y! }  B( s& o( d0 |* [
    NRI estimation by KM estimator:7 B0 K6 F, o; I: K0 r' t
    : N& q( s! y4 q- k' |3 |
    Point estimates:
    9 M* V! a0 G4 B, J                Estimate
    " u- {' X% ]; x. y% f9 FNRI           0.053776350 b: J" F& w9 M! L
    NRI+          0.03748660: V. ~6 ^  G$ o, ~# G! d
    NRI-          0.01628974
    8 c4 P+ [9 `( ]6 m  M- J9 w$ iPr(Up|Case)   0.07708938
    " W+ s! M* M0 HPr(Down|Case) 0.039602781 k5 N- l& E$ D9 I8 P8 D
    Pr(Down|Ctrl) 0.04256352
    / e- G9 r; a& y$ o6 C, Y5 W+ MPr(Up|Ctrl)   0.02627378- V: i; c6 e: z! d/ H+ U

    1 s; r/ _5 e3 Y) g& VNow in bootstrap..: t, J& W  a% A1 J/ u
    3 U$ j+ a, h* A1 t5 k1 [
    Point & Interval estimates:# b! L" X% @# N6 U: H8 ~; [& X; b2 V
                    Estimate        Lower      Upper
    , a" }5 A' {9 A0 `, dNRI           0.05377635 -0.082230381 0.16058172
    ) \. s5 ~9 y7 V0 E/ B9 n, TNRI+          0.03748660 -0.084245197 0.13231776/ f4 O: O' G' H: j) E
    NRI-          0.01628974 -0.030861213 0.06753616! r  l# \$ s' M. E& v
    Pr(Up|Case)   0.07708938  0.000000000 0.191022917 H9 I$ T9 d/ K( u8 J( \
    Pr(Down|Case) 0.03960278  0.000000000 0.15236016% ]: d" m/ i3 c* O, Z' E9 E- ^- v
    Pr(Down|Ctrl) 0.04256352  0.004671535 0.098631708 e7 ^2 j/ |% G+ m2 p
    Pr(Up|Ctrl)   0.02627378  0.006400463 0.05998424) z# x* n3 Y" _: l/ C1 s" U' g
    ( L$ j) H( j& I; v$ |3 G+ F
    11 @5 `9 P% M! E" n
    2 r3 K& s6 g9 K! p% p
    Snipaste_2022-05-20_21-49-38
    " a1 e5 F% B. ~# j/ ~" v结果的解读和logistic的一模一样。4 P/ H, c( P) M: [8 T

    4 J; Q3 V8 O9 x& h- O( e" P. F4 IsurvNRI包
    ! l' o8 Y' G# N# W+ J  Q# 安装R包9 o( A0 J# B, R% h9 s
    devtools::install_github("mdbrown/survNRI")' H5 q" H. h( J# X
    1
    & M! ^# Q9 |6 b( }# O! Z0 }; [1 d加载R包并使用,还是用上面的pbc数据集。
    ) X5 ]2 K; ~3 I1 P$ E- l7 S4 |! o/ A; X$ }, J
    library(survNRI)' S* R1 x& n' [0 X8 l: z+ p
    18 W  o7 }( Q) ]7 D. m; ?( Q; e! ]
    ## Loading required package: MASS
    3 x1 \" d$ V. O1
    - q" T' z  t5 Vlibrary(survival)
    , v) R8 J: ?( n5 p8 \# \3 w
    7 G( m3 c* v6 O( l# 使用部分数据6 u$ M& _6 @+ Z+ `  d; S- w5 H1 {- m
    dat <- pbc[1:312,]
    / X, n* ~2 S2 Y* V6 w; ^# adat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡
    . P, b; w8 }0 a; Y, b) @, r2 u& e# N5 Y# `7 C( y
    res <- survNRI(time  = "time", event = "status",
    1 T# G( n& V# ]) Z& F, g4 Q        model1 = c("age", "bili", "albumin"), # 模型1的自变量
    4 q9 x& p6 F+ u+ k& P8 }* S        model2 = c("age", "bili", "albumin", "protime"), # 模型2的自变量( U3 v  N7 r  @" ], x$ _- M" i. w- V
            data = dat,
    . J2 D  v' s0 x9 O        predict.time = 2000, # 预测的时间点
    / M: r) O& h& r& ^, ]- v        method = "all",
    5 }- i" h5 C+ h0 ]9 S5 o        bootMethod = "normal",  - [+ t3 f- [  `# f
            bootstraps = 500,
    5 o  N9 B3 ?. Q( G' o) p        alpha = .05)
    , u  X5 w! S' w7 `% c% l& y  E+ h3 ?/ D9 G: N8 G
    1$ E: E' U  f4 b2 y7 u3 g* ~
    查看结果,$estimates给出了不同组的NRI以及总的NRI,包括了使用不同方法(KM/IPW/SmoothIPW/SEM/Combined)得到的结果;$CI给出了可信区间。( Y8 m* i9 m$ P) C: {8 r0 N& V

    4 u) H- }" u9 N/ dres
    2 t" d2 L( _8 O& d1
    ; s9 ?" A! i! [% B: e2 [## $estimates7 a# e, `6 R# O& p# {
    ##            NRI.event NRI.nonevent       NRI
    8 a0 }  s# a3 k5 {5 m* p## KM        0.20445422    0.3187408 0.5231951* ?$ U4 w+ Y  K9 m- Q
    ## IPW       0.22424434    0.3273544 0.5515987# H$ @) V: |5 F' |) `# e
    ## SmoothIPW 0.19645006    0.3144263 0.5108763  \4 s& K9 G% i2 C, O5 v1 H% I
    ## SEM       0.07478611    0.2632127 0.3379988
    # [; m, I; n& U+ }8 p/ c. ^## Combined  0.19633867    0.3143794 0.5107181. f2 y9 E! A9 _& ?, J; r8 s( J! v5 \' m
    ## ' N- Z( E. ?/ h+ n
    ## $CI$ t- |) a9 T. s. A( ?( r  C: a
    ## $CI$NRI.event
    . l0 y* Z0 S  z##                     KM         IPW   SmoothIPW        SEM   Combined6 j/ H1 L2 g: L5 W1 `- E4 ~
    ## lowerbound -0.03915924 -0.02185068 -0.04724202 -0.1162587 -0.0473723
    " l0 p$ H- k  O2 X# Q  q. [- Q## upperbound  0.44806768  0.47033936  0.44014214  0.2658309  0.44004968 b9 @) j& q9 ?1 e; ^! B
    ##
    % I5 z; ^" L0 r+ i. N## $CI$NRI.nonevent4 H. ^' I8 ~) e! Q  n# z
    ##                   KM       IPW SmoothIPW        SEM  Combined- w2 s  q# r5 r
    ## lowerbound 0.1317108 0.1396315 0.1286685 0.08638933 0.1286426
    - D4 L. O( ]* |3 K! k7 I. c## upperbound 0.7102251 0.7393216 0.6966341 0.51482212 0.6964549+ b, P5 \5 e# d- S9 t/ D
    ## % Z  _7 K  O2 g: V
    ## $CI$NRI* F( _* |8 ?- V. R+ x$ Y
    ##                     KM         IPW   SmoothIPW         SEM    Combined
    1 S8 k; o  t4 L  W## lowerbound -0.05112533 -0.04569046 -0.05439863 -0.04132364 -0.05443409
    2 y0 ]8 Q4 ^% `; q" ^: n## upperbound  0.89306122  0.92464359  0.87970125  0.64253510  0.87953153
    $ I. A# G6 l+ p: U- a2 \##
    # Z. s& e5 d, h: d/ @## / B2 C4 Y$ q$ W6 I) R+ U0 s- j  V& c
    ## $bootMethod6 y- ~3 X8 D1 v" ^8 x& |! o
    ## [1] "normal"! b9 L( J. t/ C
    ## 2 R& g' ?' ?# g4 ]- V
    ## $predict.time
    " w$ L) z: ], b0 K: X/ h## [1] 2000
    $ E) G% Z. n, c' d; o$ o##
    8 p% S; g* r$ c## $alpha$ z9 x+ T% N- R7 t
    ## [1] 0.050 W% M: Y  ?) m7 o$ e; v
    ## * M: o  Z$ `/ S) [. X/ n( U
    ## attr(,"class")
    " n5 A$ X, h# }% M1 ~0 B## [1] "survNRI") i& ?" ?# _5 a

    3 O0 g0 b+ `. B& `, S9 b$ l15 d; x5 e5 L0 L: L3 A, S
    OK,这就是NRI的计算,除此之外,随机森林、决策树、lasso回归、SVM等,这些模型,都是可以计算的NRI的,后面会继续介绍。大家如果有问题欢迎在评论区留言。1 i6 f* _- U- a

    ' M/ m* G  n% h. ^2 N) g本文首发于公众号:医学和生信笔记
    . n& Q" e, f  M8 g) U+ [2 W7 C" A3 G- b' B7 _$ i
    “ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。2 K( E% ]" Z8 l( W8 d2 w
    本文由 mdnice 多平台发布; h2 w- H9 L( J5 J0 D7 d
    ————————————————
    ' }" i: R$ `" j版权声明:本文为CSDN博主「阿越就是我」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    3 }7 u+ D8 l2 |7 r. @原文链接:https://blog.csdn.net/Ayue0616/article/details/126768006
    1 {' x" }5 V& M3 l/ h
    ' {( ]" D9 k4 i, C7 {2 L" ]5 W( S& K7 {
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

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

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

    蒙公网安备 15010502000194号

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

    GMT+8, 2026-8-24 04:58 , Processed in 0.407869 second(s), 51 queries .

    回顶部