QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 826|回复: 0
打印 上一主题 下一主题

[其他资源] 净重新分类指数NRI的计算

[复制链接]
字体大小: 正常 放大
杨利霞        

5250

主题

81

听众

16万

积分

  • TA的每日心情
    开心
    2021-8-11 17:59
  • 签到天数: 17 天

    [LV.4]偶尔看看III

    网络挑战赛参赛者

    网络挑战赛参赛者

    自我介绍
    本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。

    群组2018美赛大象算法课程

    群组2018美赛护航培训课程

    群组2019年 数学中国站长建

    群组2019年数据分析师课程

    群组2018年大象老师国赛优

    跳转到指定楼层
    1#
    发表于 2022-9-12 18:43 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta
    % P2 m$ }. }8 j. }
    净重新分类指数NRI的计算: C1 a5 P: u" L- o  X
    “ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。
    3 M+ ~, L$ ^* ?# |* o8 qNRI,net reclassification index,净重新分类指数,是用来比较模型准确度的,这个概念有点难理解,但是非常重要,在临床研究中非常常见,是评价模型的一大利器!1 l# h9 c$ e; ]( J  e! Z9 u6 K+ u

    % B  F" D4 X+ _$ D# C在R语言中有很多包可以计算NRI,但是能同时计算logistic回归和cox回归的只有nricens包,PredictABEL可以计算logistic模型的净重分类指数,survNRI可以计算cox模型的净重分类指数。
    & K+ e9 w6 i5 v1 Q  b
    & B0 s3 B& k0 H( w" f) _; C$ L0 w% ologistic的NRI4 C- [( S- b" J5 m$ Q0 k* {
    nricens包$ U3 J0 g  _. |1 L7 S4 u6 |
    PredictABEL包
    ! q- j9 c# w( W4 @; I生存分析的NRI% {9 }& A, }' n2 _; ^& q# O7 j7 S
    nricens包3 h4 l+ |% |2 D$ D! D" Y+ z: n
    survNRI包
    ' Y4 }' X# q* ?+ w% ^% `logistic的NRI0 ?8 P" L. M' s1 {  a& ~
    nricens包
    ' }$ Z& j+ j! P7 Y#install.packages("nricens") # 安装R包
    , f5 G) k, i2 `3 o) jlibrary(nricens)
    : \, x- n+ X5 r) s, H- R1* F$ ?* y2 M# O# g* y$ v% l0 r
    ## Loading required package: survival  ]/ P4 _. L9 k" o0 i
    1- O6 ~' N' F3 G4 x. r* ]; a
    使用survival包中的pbc数据集用于演示,这是一份关于原发性硬化性胆管炎的数据,其实是一份用于生存分析的数据,是有时间变量的,但是这里我们用于演示logistic回归,只要不使用time这一列就可以了。
    & g: y9 O& s6 A! H# Z9 ]
    * Y) B- T3 G! t: ilibrary(survival)* r2 m6 w9 |& q, h
    5 J3 ^6 N- N) e; [: C5 s
    # 只使用部分数据, R9 \# G( C+ j. D4 g; i
    dat = pbc[1:312,] 7 k- n5 i! @0 a, |9 m
    dat = dat[ dat$time > 2000 | (dat$time < 2000 & dat$status == 2), ]! k1 c9 R8 F, V. r' L, B0 Q

    % |& X5 B4 b5 Ystr(dat) # 数据长这样+ c( g( I# e1 c! v* i
    1- z9 x" v1 K: h
    ## 'data.frame': 232 obs. of  20 variables:4 X% r4 O, g7 a; n0 Q: o* k0 `
    ##  $ id      : int  1 2 3 4 6 8 9 10 11 12 ...
    ; ^% E5 o! J8 L##  $ time    : int  400 4500 1012 1925 2503 2466 2400 51 3762 304 ...
    * J+ i* N' g% m; L; f##  $ status  : int  2 0 2 2 2 2 2 2 2 2 ...
    " V. q# t3 q5 l( p( z8 @1 {##  $ trt     : int  1 1 1 1 2 2 1 2 2 2 ...2 y2 U9 I4 Y: Z7 Q5 x- j2 F
    ##  $ age     : num  58.8 56.4 70.1 54.7 66.3 ...& b* |  p  Q0 o; R  |% p
    ##  $ sex     : Factor w/ 2 levels "m","f": 2 2 1 2 2 2 2 2 2 2 ...6 K& O# i/ N& F9 S0 M
    ##  $ ascites : int  1 0 0 0 0 0 0 1 0 0 ...( s3 o( \& u) [* l) ~, m8 l& Q5 j$ [
    ##  $ hepato  : int  1 1 0 1 1 0 0 0 1 0 ...+ E3 n* E% p# K  u: Z5 K' K& ]% G6 [% x
    ##  $ spiders : int  1 1 0 1 0 0 1 1 1 1 ...* e5 [- n" T( [/ g, O
    ##  $ edema   : num  1 0 0.5 0.5 0 0 0 1 0 0 ...
    * \  I5 L4 T" i) Q##  $ bili    : num  14.5 1.1 1.4 1.8 0.8 0.3 3.2 12.6 1.4 3.6 ...$ r7 ^- H% ~8 R$ Z6 H! K& L  a1 L
    ##  $ chol    : int  261 302 176 244 248 280 562 200 259 236 ...
      ~- ?$ j# _3 }% o1 L##  $ albumin : num  2.6 4.14 3.48 2.54 3.98 4 3.08 2.74 4.16 3.52 ..." d1 V+ E8 ?# V, H" G# Y
    ##  $ copper  : int  156 54 210 64 50 52 79 140 46 94 ...
    6 q% h, Z0 p# N, l0 R0 x0 T##  $ alk.phos: num  1718 7395 516 6122 944 ...! T0 m" L2 n. m
    ##  $ ast     : num  137.9 113.5 96.1 60.6 93 ...
    1 V& h4 i- |. m# n+ f! Y% w##  $ trig    : int  172 88 55 92 63 189 88 143 79 95 ...2 q8 c- O/ ]0 c, r
    ##  $ platelet: int  190 221 151 183 NA 373 251 302 258 71 ...0 O7 w$ \7 T7 d  @7 w9 k. s8 J
    ##  $ protime : num  12.2 10.6 12 10.3 11 11 11 11.5 12 13.6 ..." C& D" f8 g7 b
    ##  $ stage   : int  4 3 4 4 3 3 2 4 4 4 ...: J7 l+ @! |& y5 c% \
    + g* k1 G# h7 u& l8 L+ i
    14 s6 i. @9 t; n* _' T/ v- L
    dim(dat) # 232 208 D# ^- ?& f: `$ K9 k1 m0 G
    15 A1 n+ E" g: E7 `! Y( `* O& o" S8 x* _
    ## [1] 232  20! t: R( l1 D0 @" J) x3 ]
    1
    0 ?0 _) [& g8 i9 _  g然后就是准备计算NRI所需要的各个参数。/ [8 P# X( ]6 r$ y6 E8 G$ P" s

    4 t9 L$ z% |" q  |3 z# 定义结局事件,0是存活,1是死亡; W. g, A  z7 \% m3 O
    event = ifelse(dat$time < 2000 & dat$status == 2, 1, 0)
    ! {0 }+ B$ R) i9 U* P3 l# ?
    * W$ b, I/ b4 b1 ]! r. f# 两个只由预测变量组成的矩阵. @/ M' \) C/ u1 K
    z.std = as.matrix(subset(dat, select = c(age, bili, albumin)))
    ; h  w: k9 ~4 q5 Q5 N. t+ Uz.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))
    $ K$ V+ z6 M% r. b: n% C: F# ]2 u8 ]( ?' i
    # 建立2个模型
    ' c$ u( C) q6 |" c0 P/ pmstd = glm(event ~ age + bili + albumin, family = binomial(), data = dat, x=TRUE)
    6 w% n) X) V4 h" M- l% Gmnew = glm(event ~ age + bili + albumin + protime, family = binomial(), data = dat, x=TRUE)
    7 S& I9 X& h6 Y( ^
    " n* r2 R: C4 |9 x! `% v# 取出模型预测概率: j8 b7 k" Y# y* t1 M9 G+ \
    p.std = mstd$fitted.values
    ; \: u& @0 B6 ~; op.new = mnew$fitted.values0 Z( \% P/ R) t# X. j' J
    + i# |6 j7 w% V' T1 K1 |
    1. z: ?5 ?- W# G  ]& a0 f9 t
    然后就是计算NRI,对于二分类变量,使用nribin()函数,这个函数提供了3种参数使用组合,任选一种都可以计算出来(结果一样),以下3组参数任选1组即可。 mdl.std, mdl.new 或者 event, z.std, z.new 或者 event, p.std, p.new。8 |. D! b# h; V: u
    ( F% k0 A; s+ L
    # 这3种方法算出来都是一样的结果
    5 q: e+ Z! x+ d1 A3 l$ T3 }3 G2 t0 r  y7 z' G
    # 两个模型
    2 @" a. A) L9 ]nribin(mdl.std = mstd, mdl.new = mnew,
    " R  C8 L2 ?6 Q9 E8 u       cut = c(0.3,0.7),
    7 Y% d& |$ u; t' Y6 _$ \0 ~       niter = 500, " ?$ z" D7 ^% `- y1 m7 u0 k6 N; y
           updown = 'category')/ [- D  W6 D. B" b

    ' n: J" u6 k0 ?$ n: U# 结果变量 + 两个只有预测变量的矩阵6 ~4 d# e! j$ ~$ Q7 n9 h( w/ U
    nribin(event = event, z.std = z.std, z.new = z.new,
    : H& K1 U& ?- u& g% ]       cut = c(0.3,0.7),
    ! q/ j( [7 j2 ]! ?( H) g- C       niter = 500, % M: _# C5 t* h6 I& n, Y7 L" l
           updown = 'category')
    # a  P$ n2 d. U" s/ m9 C- K9 M( I8 H: V+ k
    ## 结果变量 + 两个模型得到的预测概率
    # [  |$ u0 B! ~5 D4 t* P" Vnribin(event = event, p.std = p.std, p.new = p.new, " r& F3 [8 _# L" D# h( m
           cut = c(0.3,0.7),
    $ n4 `5 e0 b, K* \0 \       niter = 500,
    . _5 [( t" U2 a       updown = 'category')
    # O% a: c' i. b  k4 z, D
    7 T; x' c# S  ~8 b- I2 a1
    + u+ x- i) _( u9 d# ?+ C* N" @其中,cut是判断风险高低的阈值,我们使用了0.3,0.7,代表0-0.3是低风险,0.3-0.7是中风险,0.7-1是高风险,这个阈值是自己设置的,大家根据经验或者文献设置即可。
    ' U' f  C! P$ Y: _7 n/ \* ~
    . n, S8 R( y0 }- initer是使用bootstrap法进行重抽样的次数,默认是1000,大家可以自己设置。
    1 g. H  U/ m0 k* |
    9 t2 {% I) m# O) A' oupdown参数,当设置为category时,表示低、中、高风险这种方式;当设置为diff时,此时cut的取值只能设置1个,比如设置0.2,即表示当新模型预测的风险和旧模型相差20%时,认为是重新分类。( ?6 ~4 A3 D, t/ {- H, J

    8 c7 @1 b; h1 ?2 Y上面的代码运行后结果是这样的:
    ( l7 ^. f& r  s1 c
    5 i$ r. X. H( v7 YUP and DOWN calculation:# w# a6 Q$ s  F! D! I: k
      #of total, case, and control subjects at t0:  232 88 144' k+ g5 U) e1 C8 {8 g
    " ?$ {% \0 W2 A/ M/ I0 Z
      Reclassification Table for all subjects:
    ; ~) e- ^1 E! g7 C( z        New
    2 h* O; b( l# |& Z0 H- l) vStandard < 0.3 < 0.7 >= 0.7
    " b* o3 A8 d' ^# K: [  < 0.3    135     4      0
    4 U0 R& M$ C! n$ t0 A" k  < 0.7      1    31      49 _6 H+ O: L( M5 |* c/ ?
      >= 0.7     0     2     55
    4 J; I& b- B" u3 ?4 ^! y$ e
    0 Q4 N6 ~+ {6 ?& ~, S* L  Reclassification Table for case:
    4 N6 b" N5 ~  F9 R0 ^  I$ `8 `        New
      B: g' C; ?: j6 A7 EStandard < 0.3 < 0.7 >= 0.76 k' }; {9 F, s
      < 0.3     14     0      0, |6 N% g1 J' Q5 |: `
      < 0.7      0    18      3
    ; _; G6 C1 s' W/ G' J* _  >= 0.7     0     1     520 x! [0 P) V  x
    * ]$ V, S2 k4 \: {
      Reclassification Table for control:- J8 @2 z; }0 g8 o& J9 D
            New
    ' p- q, c( X# X( n# }9 P6 {* cStandard < 0.3 < 0.7 >= 0.7* L+ T% m. w& |3 R2 B& Y! Z
      < 0.3    121     4      0
    " {- E+ U) t- Z& z" \  < 0.7      1    13      1, v2 E2 t3 c# k6 p2 W1 {* D
      >= 0.7     0     1      3
    9 @; Z: Z( c6 |1 L, u" M: |; c5 v, m- K
    NRI estimation:
    5 [4 Y; a( \- i$ b- p- d4 r5 jPoint estimates:
    0 G: Z& `# M; V2 d                  Estimate
    5 i) I( g9 K& b( O# oNRI            0.001893939
      ?1 n5 K0 |+ s- q. d/ INRI+           0.022727273" b4 ?/ x  |* r( u
    NRI-          -0.020833333
    2 K* u- p% `7 p# [: APr(Up|Case)    0.034090909# y' V6 o; f5 A5 l) w
    Pr(Down|Case)  0.0113636361 a) @9 o8 A2 y  k% u8 P
    Pr(Down|Ctrl)  0.013888889
    4 h8 B: Q% R, v3 h3 XPr(Up|Ctrl)    0.034722222+ s& z' r. b% q" j0 ^# ?
    2 b3 A) k0 A* K5 }4 k( R' a
    Now in bootstrap..  f4 N2 ?9 g- y
    1 r( W0 E3 ?5 U  p% \5 q" I
    Point & Interval estimates:
    " u7 d" W% I5 u# o7 B                  Estimate   Std.Error        Lower       Upper
    . X1 e8 j- u' h+ I( f  h' SNRI            0.001893939 0.027816095 -0.053995513 0.055354449
    / H3 U0 j) P: h: l3 @3 s  W/ ]" `NRI+           0.022727273 0.021564394 -0.019801980 0.065789474
    # j/ u$ B  f4 \0 S" P( @0 PNRI-          -0.020833333 0.017312438 -0.058823529 0.007518797
    7 x: |- x: V" j: |Pr(Up|Case)    0.034090909 0.019007629  0.000000000 0.072164948. T2 p% I0 y2 q5 n, U" v+ R
    Pr(Down|Case)  0.011363636 0.010924271  0.000000000 0.039603960
    ' R6 B" {5 }& R% B5 O9 ~Pr(Down|Ctrl)  0.013888889 0.009334685  0.000000000 0.0352112684 ?# {# Z' G/ e! ]# P! z! ^
    Pr(Up|Ctrl)    0.034722222 0.014716046  0.006993007 0.066176471
    : o9 u: r3 g# i: a& |. Y9 U# c- K1 Z2 Y6 ^  j9 [
    1+ Z0 @# x, w7 c  H: \4 a
    首先是3个混淆矩阵,第一个是全体的,第2个是case(结局为1)组的,第3个是control(结局为2)组的,有了这3个矩阵,我们可以自己计算净重分类指数。1 r" V  w+ C/ I2 z) K5 T* u3 ]
    + t- \# y% @& \
    看case组:( O7 g- w& Q7 N5 M8 g1 x

    * ~9 ~& Y8 x2 O! o净重分类指数 = ((0+3)-(0+1)) / 88 ≈ 0.0227272732 ^* I; D8 \3 w* U/ ?7 Q$ \( J9 L  u
    % L& A- S' k' b
    再看control组:
    9 B( V, y- `8 g8 J
    # y. d& C. O& t. V; y8 p9 `净重分类指数 = ((1+1)-(4+1)) / 144 ≈ -0.020833333
    ) ^3 Z) G' Y2 `  K$ I: @# [' b4 K9 W8 ]& n! T- {9 C" E( F
    相加净重分类指数 = case组净重分类指数 + control组净重分类指数 = 2/88 - 3/144 ≈ 0.000315657! Y! d0 X; C# {8 ]) x8 L$ c

    8 I, C; L7 \* n6 k( v, w; G, A再往下是不做bootstrap时得到的估计值,其中NRI就是绝对净重分类指数,NRI+是case组的净重分类指数,NRI-是control组的净重分类指数(和我们计算的一样哦),最后是做了500次bootstrap后得到的估计值,并且有标准误和可信区间。/ r$ p# }- h6 o6 `3 P; _! B# D

    7 l' w- P6 E3 ~% @最后还会得到一张图:
    2 L7 g* A  G5 f' K; }2 A/ ?
    1 l* C  N6 [9 l, z这张图中的虚线对应的坐标,就是我们在cut中设置的阈值,这张图对应的是上面结果中的第一个混淆矩阵,反应的是总体的情况,case是结果为1的组,也就是发生结局的组,control是结果为0的组,也就是未发生结局的组。
    6 G7 d1 \* D/ w+ o( k* c/ X2 W- Z. a- G
    P值没有直接给出,但是可以自己计算。
    9 F' \# l  E& y
    ! E. f. G- q, C( P- [3 Y# 计算P值1 ?1 {+ f4 K$ s8 h+ C
    z <- abs(0.001893939/0.027816095)
    ) P2 c/ A/ }* i2 N1 p7 {. lp <- (1 - pnorm(z))*2
    ) f4 U2 I$ Q; @# T1 Vp
    9 j+ X5 ], }7 K! A& U: v1
    & l( l- ?9 T' S$ B' Y6 g, c. Q## [1] 0.9457157  F" d$ u" `& S
    1, `" ]5 [3 a6 h3 L
    PredictABEL包
    / F1 b$ Q) y) v& m#install.packages("PredictABEL") #安装R包
    5 p/ N" @, S  J9 f# I/ l% _library(PredictABEL)  0 a& `1 w" M$ m  s; g6 \8 e: }
    & m9 a  d0 W4 P7 t
    # 取出模型预测概率,这个包只能用预测概率计算( I. M! W8 S9 S: p+ R0 `
    p.std = mstd$fitted.values
    8 N6 \# T6 H0 tp.new = mnew$fitted.values . W, g4 ?& {+ }
    1
    7 t/ }* e0 l2 b8 r; }2 d, x- L然后就是计算NRI:' |2 {9 o) \  M3 D1 R; h  ^
    3 o/ `! K/ Z* q, n
    dat$event <- event& R9 t- X+ W- Z* w
    " L: t' @* ?4 |2 ?' u
    reclassification(data = dat,
    3 m' Q6 v3 b3 c  j$ A1 z, o                 cOutcome = 21, # 结果变量在哪一列
    ) U# o3 ~; V& N7 Q: f2 x& N4 w                 predrisk1 = p.std,
    % N3 d; b. Z2 Y6 C- _8 ~                 predrisk2 = p.new,
    4 O& N& d6 ~0 l6 G) p  E: G4 S                 cutoff = c(0,0.3,0.7,1)
    * v& c2 `8 v% F" l  ~' z                 )6 w3 ~/ I4 Q0 B: V+ j
    16 h  m0 T* F( V6 k4 D' j- W0 _0 T
    ##  _________________________________________
    2 A( Z& k+ n# v' `! T5 o. Q  [##  
    ) L; `# h2 x: n##      Reclassification table    * V6 _, z) Z. \1 U( Y, B
    ##  _________________________________________8 ?0 _6 x! b$ C3 S
    ##
    $ x. Z) C$ e0 }##  Outcome: absent
    5 c+ p( ]0 g. z% `# T##   
    ; l! p& A- X8 j( `) Y##              Updated Model
    / v/ _  s8 \4 s3 c+ J6 J; C; ~8 T2 M## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified; p" S0 F% m8 R: i+ A' v
    ##     [0,0.3)       121         4       0               3  }/ X5 B' Z, ]0 p4 w  }  B  ~" h
    ##     [0.3,0.7)       1        13       1              13
    6 r( F& R/ A" d##     [0.7,1]         0         1       3              25
    9 D' |2 ?; h9 [% ]: M, I- e##
    " c$ j1 ?: N2 {! e0 L/ @##  
    , M  O% I7 @4 ?' U3 O0 L##  Outcome: present 4 w; y9 t( `/ J9 p
    ##   
    8 v- Z$ X% n7 E' Z: ?4 x* r##              Updated Model
    & k6 q3 c  y1 u+ m% v: U& p, f## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
    ) t7 b' q  J( u- x; y##     [0,0.3)        14         0       0               0
    $ |' g% i! ~) n5 L1 b( c- i1 a##     [0.3,0.7)       0        18       3              145 K/ a# D+ C) q
    ##     [0.7,1]         0         1      52               2$ Q' I0 b9 ]9 X
    ## + P5 U, ^/ Y( |' E+ _
    ##  4 }+ R. u- A* O& c/ F
    ##  Combined Data   u7 ]. `0 n! K" l8 R5 h( t
    ##   8 n4 K  ~* P1 g' g8 x5 u
    ##              Updated Model
    $ l0 T1 i) t$ F3 P: ~3 i) {## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified$ Y$ J7 N2 J3 a: K; ]* p
    ##     [0,0.3)       135         4       0               3* H: V; r4 j) |- B" P  L4 F9 P" V# r
    ##     [0.3,0.7)       1        31       4              14
    ' L) V+ ]% {( |) t##     [0.7,1]         0         2      55               42 Q! P5 Z  g( J4 A$ U
    ##  _________________________________________
    $ D0 I; d* C3 i& v  e$ }## 2 @& x. p  z4 ~  y: C. V. \
    ##  NRI(Categorical) [95% CI]: 0.0019 [ -0.0551 - 0.0589 ] ; p-value: 0.94806   t9 X9 T5 r7 ]" W, s  f
    ##  NRI(Continuous) [95% CI]: 0.0391 [ -0.2238 - 0.3021 ] ; p-value: 0.77048
      ~" e* I4 [7 S" W/ S# i) Z##  IDI [95% CI]: 0.0044 [ -0.0037 - 0.0126 ] ; p-value: 0.283968 l; E  U3 Q8 E  B+ j7 s  ^
    : N0 X# N) m' E
    1
    ' D( U' Z. v0 B: C$ b* h结果得到的是相加净重分类指数,还给出了IDI和P值。两个包算是各有优劣吧,大家可以自由选择。
    ' M) B8 _* Q6 A
    3 T/ y% X8 J& w; f% d' m生存分析的NRI
    + |- k; j9 a; V2 H8 i5 i- d" z还是使用survival包中的pbc数据集用于演示,这次要构建cox回归模型,因此我们要使用time这一列了。
      R8 b' v% R7 h! d/ n0 I) v; m
    ; Z, ]; Z5 K  e; Y; ^nricens包
    % l, L! N+ V* y6 U) Xlibrary(nricens)
    8 G) [8 J/ L9 nlibrary(survival)
    : p3 f2 C- Y9 ^5 J/ }: o
    ( _, B1 _2 W% d) H, t' zdat <- pbc[1:312,]
    + [# Y+ f  y# \- h( {) ?: Y" v8 odat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡& O& j0 z8 I) @8 t
    16 f- K6 F3 |# [, y, M, d+ p! C
    然后准备所需参数:/ i6 I) ~1 t" \1 Q) t
    0 ^3 P3 i# h- U, Q7 ?
    # 两个只由预测变量组成的矩阵
    : J. V: T* N3 j+ p) ]z.std = as.matrix(subset(dat, select = c(age, bili, albumin)))% v2 K. J$ V( ~, B- ~
    z.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))6 T2 a8 ]$ p0 m! o) G7 n

    # g9 d. v/ @/ {9 d# 建立2个cox模型
    9 g) m1 X2 F" i; t  v2 nmstd <- coxph(Surv(time,status) ~ age + bili + albumin, data = dat, x=TRUE)
    3 k  V" V4 ?. v/ G7 X1 W0 cmnew <- coxph(Surv(time,status) ~ age + bili + albumin + protime, data = dat, x=TRUE)/ n( i. a8 F4 Z8 O  F
    & {$ ?; G$ @  s3 j& K! g
    # 计算在2000天的模型预测概率,这一步不要也行,看你使用哪些参数' D* \$ K/ }: g8 q" z
    p.std <- get.risk.coxph(mstd, t0=2000)
    8 d% U! k% j# s* Q/ rp.new <- get.risk.coxph(mnew, t0=2000)5 G0 e9 I0 _2 {' p
    1
    % X( x5 z: b% ^5 O: T6 U3 O计算NRI:9 W5 L. i& J( R6 Q/ H

    5 k% g1 s( K% e$ G# J& x; znricens(mdl.std= mstd, mdl.new = mnew, - k( R+ g: D1 P" z8 @
            t0 = 2000,
    " n  f5 P2 c% X        cut = c(0.3, 0.7),
    " X0 g+ N1 I, _; c; [        niter = 1000, $ Y: O4 S  |8 A/ g
            updown = 'category')
    * }* P/ M! z) W  }4 {2 V! W
    # w4 e0 h; L' u) u1 q% TUP and DOWN calculation:
    + R8 i+ x# r8 m. G" h  #of total, case, and control subjects at t0:  312 88 144
    8 p* L! x, `9 {: g
      K" H+ F  V' i  t" ^  Reclassification Table for all subjects:2 N" h0 n% S  h$ ~: ?: c
            New% M4 d" D. {. r: k. q0 m/ Y
    Standard < 0.3 < 0.7 >= 0.7  [7 ^& o/ \$ n" u) _* N
      < 0.3    202     7      0' X0 s. T6 ^) Z7 T% g7 m; W# K
      < 0.7     13    53      6: u* B7 i9 b" L% l. i  c" ^
      >= 0.7     0     0     31$ k  K; j$ p* v. w7 Q4 z8 D
    4 h: V7 A. U2 N
      Reclassification Table for case:
    * i  i3 I+ T  F+ h: x        New4 f3 G' ~0 N- r/ v+ U# U
    Standard < 0.3 < 0.7 >= 0.75 `) V, ^) u: }* o6 {5 k
      < 0.3     19     3      0
    / n, [: X  l* H6 H: b& Q: Q  < 0.7      3    32      4
    # v& `: S$ P  p/ Z) p: v% O+ ]  >= 0.7     0     0     27" U0 f/ S# I8 J  G

    - N8 d4 L) t* t, ?  Reclassification Table for control:) I* W5 N$ O% S  f+ v/ K1 z
            New
    & n* Z4 \. t# X* [$ r( v- i# ?- YStandard < 0.3 < 0.7 >= 0.7
    5 s6 }& j- l' S  < 0.3    126     3      05 }7 y) Y( \$ K# {* g# P
      < 0.7      5     7      2( c+ P, ]1 `* |% l! u6 u: D- L1 A: h
      >= 0.7     0     0      1
    # W; q) H3 t/ i; _# f! L
    * a, W) P( m5 `NRI estimation by KM estimator:1 l' C# D' @. g7 N! B4 f
    ' X" R4 J7 i2 U
    Point estimates:* N% {/ H& K% P7 g4 N
                    Estimate
    7 L  _2 Q1 ]- ]. x5 x/ Q4 n# vNRI           0.053776358 S$ a( q2 c+ r9 _4 j6 x! E
    NRI+          0.03748660
    5 S% q- _" c2 J; }4 K, ]NRI-          0.01628974% i: e, T8 w" X. q
    Pr(Up|Case)   0.07708938
    ( S# |+ @# N  K" MPr(Down|Case) 0.039602786 q0 M. j5 p% p; ^! h) d; M' p+ I* p
    Pr(Down|Ctrl) 0.04256352+ w+ |- u% ~. g, l' `
    Pr(Up|Ctrl)   0.026273787 g- X0 {* B: @; G8 O  }
    3 A1 `  |, I3 `# M( y  K& f4 q
    Now in bootstrap.., ^; w. Q3 {4 ]& }
    % p% G5 p; I" r. e# }
    Point & Interval estimates:8 `0 m+ Z3 y0 P1 ~
                    Estimate        Lower      Upper1 ~. o' T' e; u& g  q" B
    NRI           0.05377635 -0.082230381 0.16058172. n3 M; x% D3 f5 s0 z: G
    NRI+          0.03748660 -0.084245197 0.13231776
    * \0 z( j. T9 N! s+ y- b3 pNRI-          0.01628974 -0.030861213 0.06753616" E0 v5 g. \5 @
    Pr(Up|Case)   0.07708938  0.000000000 0.19102291
    2 x2 a. S+ p1 o* m& Z6 b: RPr(Down|Case) 0.03960278  0.000000000 0.15236016- W6 R3 i, o  q6 B! X
    Pr(Down|Ctrl) 0.04256352  0.004671535 0.09863170% y+ f$ z0 n( j, s
    Pr(Up|Ctrl)   0.02627378  0.006400463 0.05998424
    $ O' Y" Y4 w3 R9 U) b0 R  J7 m4 N" _/ e+ e
    13 S% w6 Y' Y4 h6 j4 U2 C4 z7 j) n" E
    , W, _/ r6 e& o- f; [) T
    Snipaste_2022-05-20_21-49-381 |: C& Z7 N/ a
    结果的解读和logistic的一模一样。
    . V5 a) R+ X) U7 _
    ( q5 P  i$ {4 T6 Z9 |/ i3 gsurvNRI包. z/ a2 }" F( f$ y- v
    # 安装R包
    ) J8 k6 K# z: p: q4 ]0 u/ mdevtools::install_github("mdbrown/survNRI")0 [4 f3 u; ?: q: ~' @# p
    1
    7 c: E- P5 M7 r. H) ~# m- [4 [$ h加载R包并使用,还是用上面的pbc数据集。
    6 I5 h4 _6 N1 O6 Z" j/ D! h8 @$ `/ f! |) e8 e' E
    library(survNRI)/ B1 x/ T+ a$ M; K* K* `
    1
    9 h' o# S6 _3 Z4 z, d! k## Loading required package: MASS
      H( A: Q. L( w: ~1- ]  ?0 v$ U- K2 ^
    library(survival)
    2 m0 n" j8 b7 K# m
    ! F- s5 M9 {0 [# z# 使用部分数据- R# N+ Y0 P, B/ H% k1 n  g
    dat <- pbc[1:312,]
    . x2 G0 }- N8 e" h0 a' f: Ydat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡
    ! \3 x! K7 H, ~+ d9 v( v- x3 E  k; y0 q5 B1 {" i
    res <- survNRI(time  = "time", event = "status",
    3 ]* h+ V+ E, F3 c' A& V: ^3 u+ f/ M2 J        model1 = c("age", "bili", "albumin"), # 模型1的自变量" m' }% r( O2 D- F7 P8 t
            model2 = c("age", "bili", "albumin", "protime"), # 模型2的自变量
    . S  [- B4 p, L9 t- X        data = dat,
    4 m' W. V) L8 [( d0 b" `# }        predict.time = 2000, # 预测的时间点. d: }5 X# ?  ~8 k8 {& z+ w' O
            method = "all",
    ; _3 |- T9 k7 Q% ^5 P) c        bootMethod = "normal",  
    5 }  y0 g+ p5 u! @. r" ^/ J* u* P        bootstraps = 500,
    , F. Y6 B) i$ Y: S: @/ t        alpha = .05)1 Y- x% j! \( n# |

    0 z  y0 P9 W) O9 W! R& e: j1
    ' L5 N# C6 e+ d- ?6 x- x查看结果,$estimates给出了不同组的NRI以及总的NRI,包括了使用不同方法(KM/IPW/SmoothIPW/SEM/Combined)得到的结果;$CI给出了可信区间。
    5 w  I- q, k1 [! A+ n4 h! F" a$ u. h+ h  ~  ]/ h( R) R
    res6 L* A; F; e8 I- Q; t; s
    1( o" P  }" N. T+ W
    ## $estimates( K' |; [( t+ D0 N- K
    ##            NRI.event NRI.nonevent       NRI# p$ w  O# ?! ^$ x
    ## KM        0.20445422    0.3187408 0.5231951% ]+ Z; C  O) v: p
    ## IPW       0.22424434    0.3273544 0.55159873 v; @; H/ R' v+ ~+ n
    ## SmoothIPW 0.19645006    0.3144263 0.5108763
    1 c2 e% `0 R. j## SEM       0.07478611    0.2632127 0.3379988
    ! e0 t" N1 s( t, Q( E## Combined  0.19633867    0.3143794 0.51071812 p/ O- N* f6 k% s  |
    ## 6 K8 N, G5 y# S5 F  t5 ~* K
    ## $CI
    / W1 z+ _2 r" D, W$ d0 H## $CI$NRI.event
    ; _2 }. c9 }7 h( S##                     KM         IPW   SmoothIPW        SEM   Combined
    0 P8 d8 Q1 a" i; ~. a1 ^. f## lowerbound -0.03915924 -0.02185068 -0.04724202 -0.1162587 -0.0473723
    0 j) X' m* o: T  n/ t7 D## upperbound  0.44806768  0.47033936  0.44014214  0.2658309  0.4400496
    / n2 z3 q3 j2 k- ?+ B0 t+ W5 S$ a## 2 W! z, u) }) d% k& ]. C4 u) V# }/ n
    ## $CI$NRI.nonevent
    4 ~% E, U1 D+ ~* _( b4 ]##                   KM       IPW SmoothIPW        SEM  Combined6 v1 g0 L9 m0 I" M7 G
    ## lowerbound 0.1317108 0.1396315 0.1286685 0.08638933 0.1286426' k: O8 k; h+ K; O
    ## upperbound 0.7102251 0.7393216 0.6966341 0.51482212 0.6964549
    + S5 O3 Y; l9 ^##
    ; T2 S/ y( h  r% b. G+ E1 u## $CI$NRI
    " Q0 n2 y  S9 m  q' @/ \##                     KM         IPW   SmoothIPW         SEM    Combined
    5 E7 n5 H1 N5 s% G- Y## lowerbound -0.05112533 -0.04569046 -0.05439863 -0.04132364 -0.054434094 I; z- J3 P9 s: Z* e+ Q
    ## upperbound  0.89306122  0.92464359  0.87970125  0.64253510  0.87953153! m+ Q5 T5 O0 h8 \+ ~
    ##
    ; V: ?9 w8 J' b# K+ H# H0 p## 2 q% |2 Z# q# B( F0 T
    ## $bootMethod
    + I' m# H: Q/ v; o" }## [1] "normal"
    % [9 e- V4 \$ b3 T. A1 t: N- |## 3 G0 P6 Y( R( O
    ## $predict.time
    7 O) i! N1 m1 T6 z/ P, r  W## [1] 2000
    , y2 [- ~4 ]: h  S/ y) a! y4 M##
    ) I) u5 c% P) c. m3 i## $alpha
    / d+ d$ L! R' \7 Q  U- H+ z, H## [1] 0.056 G: f0 e$ Y# s: i. T
    ##
      k# h% u5 c2 Q& m  r* _- [* L## attr(,"class")* o# ~! G) i; f; R$ \
    ## [1] "survNRI"
    6 z4 }" t. }  x( s
    6 B4 H' i; {. U( z1# I8 Z: G4 p, p% ~* H
    OK,这就是NRI的计算,除此之外,随机森林、决策树、lasso回归、SVM等,这些模型,都是可以计算的NRI的,后面会继续介绍。大家如果有问题欢迎在评论区留言。- v+ t/ u/ e+ j( _" d: ^
    + f) F$ m$ {# N( D( y
    本文首发于公众号:医学和生信笔记
    % x0 o3 \  m2 u9 |2 L  k' J4 b/ e, |7 r1 H# I7 M# ?. ]* S
    “ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。
    & A% z# c& l1 L  E6 M6 ^本文由 mdnice 多平台发布. S! _8 R! |; f, \
    ————————————————) U) H# E' [! y1 Y5 @/ S: _. `
    版权声明:本文为CSDN博主「阿越就是我」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    / C5 A( j: Z& u7 Q原文链接:https://blog.csdn.net/Ayue0616/article/details/126768006- f( i# M, C5 y( c
    ( C1 `5 Z) t+ Q  j/ i  b
    1 e) Z2 z0 \$ n* q- @4 W% F( |" 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, 2024-5-24 01:03 , Processed in 0.293631 second(s), 50 queries .

    回顶部