QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3020|回复: 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
    + A) r0 I6 E$ \- H
    净重新分类指数NRI的计算
    8 t6 n* c" q/ m, e4 T% m) Z“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。
    - _# }6 K. e, o5 \NRI,net reclassification index,净重新分类指数,是用来比较模型准确度的,这个概念有点难理解,但是非常重要,在临床研究中非常常见,是评价模型的一大利器!
    7 f4 ?) C  ^: U! _# \5 y) k' f0 J0 I$ ], k- i' X
    在R语言中有很多包可以计算NRI,但是能同时计算logistic回归和cox回归的只有nricens包,PredictABEL可以计算logistic模型的净重分类指数,survNRI可以计算cox模型的净重分类指数。7 A" p- X" Z. _) F

    8 ~! U* n1 b* f% C. q" ]0 vlogistic的NRI
    1 l6 D" D% e7 s: snricens包
    7 `$ S+ P0 y; u5 ]PredictABEL包
      Y5 q5 d8 Z* q+ V生存分析的NRI
    5 P. m# K1 G( U2 n$ O% L; T* Bnricens包
    2 q# k2 I& r- J' c* g# E. WsurvNRI包4 x& H6 K- T/ @8 k* J; o
    logistic的NRI
    - P7 _" ^$ Z" e& X: ^1 Q9 G) lnricens包
    % l( ?4 m  m1 d8 D# j+ ]  d- N#install.packages("nricens") # 安装R包! \/ x  S& p" Y# L5 x
    library(nricens)
    4 K" Z& B- a/ _( k2 i1- ?/ }: b. P1 l8 o5 D, u) d
    ## Loading required package: survival( F2 r: {5 f1 \4 ^$ m
    1
    4 p9 b, {5 v$ r2 L0 Q6 b1 W使用survival包中的pbc数据集用于演示,这是一份关于原发性硬化性胆管炎的数据,其实是一份用于生存分析的数据,是有时间变量的,但是这里我们用于演示logistic回归,只要不使用time这一列就可以了。' h: @$ {- F6 [7 D6 S; f% o

    ' R/ v8 x9 O7 w# z: P) jlibrary(survival)
    8 T9 P; R& f8 O8 w0 D/ A
    0 A6 B  m% _/ w$ {& `* r4 ^# 只使用部分数据
    : p% \/ R4 r% N" v: r8 Sdat = pbc[1:312,]
    6 U" ^: t2 b2 y4 W$ rdat = dat[ dat$time > 2000 | (dat$time < 2000 & dat$status == 2), ]
    ! O- b" T! N( K" e2 {/ C' f; B0 h
      h2 j$ ~" y! |6 K9 }/ xstr(dat) # 数据长这样9 S' n/ F3 E$ P
    1. p! D% N" k+ P: L6 n
    ## 'data.frame': 232 obs. of  20 variables:; y: [, M4 U$ O
    ##  $ id      : int  1 2 3 4 6 8 9 10 11 12 ...% ~. ]. e# x( L8 K+ J4 _- ?1 _5 T
    ##  $ time    : int  400 4500 1012 1925 2503 2466 2400 51 3762 304 ...4 q2 x/ [2 _+ O* s
    ##  $ status  : int  2 0 2 2 2 2 2 2 2 2 ...
    2 n9 @' K% t  L##  $ trt     : int  1 1 1 1 2 2 1 2 2 2 ...
    ) a3 Y6 b. j# n3 J- z# p##  $ age     : num  58.8 56.4 70.1 54.7 66.3 ...
    9 e& p9 P0 R+ x- x: H$ c2 L& X5 l- F##  $ sex     : Factor w/ 2 levels "m","f": 2 2 1 2 2 2 2 2 2 2 .../ f  i& W7 A% ]8 Z% x5 `1 c  Y
    ##  $ ascites : int  1 0 0 0 0 0 0 1 0 0 ...' c# ~9 a- L( n* w2 Y
    ##  $ hepato  : int  1 1 0 1 1 0 0 0 1 0 ...# ~" k8 G7 k) ^% Y
    ##  $ spiders : int  1 1 0 1 0 0 1 1 1 1 ..., V% u$ ~' Q8 R( ?) J" ^
    ##  $ edema   : num  1 0 0.5 0.5 0 0 0 1 0 0 ...
    & W$ k% y( i1 o9 j. a' I5 Q##  $ bili    : num  14.5 1.1 1.4 1.8 0.8 0.3 3.2 12.6 1.4 3.6 ...) t& `! f5 V  S* |; J6 `
    ##  $ chol    : int  261 302 176 244 248 280 562 200 259 236 ...
    % e% _8 t: U1 e3 M2 Z##  $ albumin : num  2.6 4.14 3.48 2.54 3.98 4 3.08 2.74 4.16 3.52 .... F1 u6 `2 j2 s2 ^8 o  h
    ##  $ copper  : int  156 54 210 64 50 52 79 140 46 94 ...
    # m0 ?7 Z) g2 s* v##  $ alk.phos: num  1718 7395 516 6122 944 ...$ V, m' A: a8 q0 y. |
    ##  $ ast     : num  137.9 113.5 96.1 60.6 93 ...
    3 `% f# f$ y8 i/ Q1 n; D##  $ trig    : int  172 88 55 92 63 189 88 143 79 95 ...
    - z# v3 r0 t: F+ q* b6 p##  $ platelet: int  190 221 151 183 NA 373 251 302 258 71 ...1 H( L4 ?2 u7 A& P) I2 n6 u1 v
    ##  $ protime : num  12.2 10.6 12 10.3 11 11 11 11.5 12 13.6 ...
      Q3 I6 ^3 E: _% P4 n7 S& f4 z0 d##  $ stage   : int  4 3 4 4 3 3 2 4 4 4 ...
    * |! x1 p9 l; P( O" ~5 |
    ! e  x+ K" `! |4 |7 C8 y13 e# M* H) B& ]/ i0 ]6 m
    dim(dat) # 232 20
    5 Q. A* \. R1 b3 @, F; r13 a2 ^9 ?3 l4 S
    ## [1] 232  202 }: S- s' Z( y7 p7 K/ t, r& {
    1
    : O* T4 Z" F+ r; j然后就是准备计算NRI所需要的各个参数。
    6 |4 E+ E: t. `9 r7 k
    " Y) H/ u% q* V; X8 Z. E0 d$ `# 定义结局事件,0是存活,1是死亡8 g+ f4 |2 V4 Y2 O) |
    event = ifelse(dat$time < 2000 & dat$status == 2, 1, 0)4 j" I2 y+ Q* x$ P1 {9 w
    1 T$ ]. `! u, ]" M$ I' D0 l
    # 两个只由预测变量组成的矩阵
    , H! d! g4 m' Mz.std = as.matrix(subset(dat, select = c(age, bili, albumin)))8 l2 V' Z- h, s
    z.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime))): F; s" Z. R2 o' c
    5 Z. l' S, G' n6 u8 p0 G$ q
    # 建立2个模型+ D4 \8 @' u0 K5 f
    mstd = glm(event ~ age + bili + albumin, family = binomial(), data = dat, x=TRUE)) a3 M2 X/ p6 m
    mnew = glm(event ~ age + bili + albumin + protime, family = binomial(), data = dat, x=TRUE)+ A( f" |- s6 T/ h9 c  u4 Q" m, l

    " z/ [7 S7 }- L8 X# 取出模型预测概率
    * c  h, l( b6 B1 U+ gp.std = mstd$fitted.values- X. f7 I+ e# }! ^% u
    p.new = mnew$fitted.values7 R. i, a/ W$ v6 W" \' ]+ M, B

    9 C7 t8 y) |! B5 f) U* a; x1 Z18 C! H  {& @1 l# C* A( v% f
    然后就是计算NRI,对于二分类变量,使用nribin()函数,这个函数提供了3种参数使用组合,任选一种都可以计算出来(结果一样),以下3组参数任选1组即可。 mdl.std, mdl.new 或者 event, z.std, z.new 或者 event, p.std, p.new。& Q  O1 A: O5 \+ X' s- y) p. p' M

    ' }7 m+ f  a9 Q# 这3种方法算出来都是一样的结果
    " }" G, j. W% z5 B
    / @5 U  s+ B( @# 两个模型
    , {8 h  K" l4 B' \6 M  ?  rnribin(mdl.std = mstd, mdl.new = mnew, 9 z# H6 O, e% r: P
           cut = c(0.3,0.7),
    & ^! I. u. Y0 J" \9 O6 h       niter = 500, $ t7 c( [, C1 ?: A3 H" N+ e/ v
           updown = 'category')
    * F* S2 Y0 j; `) x
    6 V- L! F9 K' W5 p$ Y0 q2 n- ?# 结果变量 + 两个只有预测变量的矩阵  S) k( h5 C: E" X8 M6 ~  y7 U
    nribin(event = event, z.std = z.std, z.new = z.new, + B2 g" J( h/ N% U
           cut = c(0.3,0.7),
    . i1 H0 k( x$ K3 k       niter = 500,
    4 t1 ^1 Z. Q) y8 d. @       updown = 'category')0 T* C" a9 ^: w3 {% G

    ; z) v& p4 R8 B6 M' @## 结果变量 + 两个模型得到的预测概率2 S5 I5 [  |: g+ O
    nribin(event = event, p.std = p.std, p.new = p.new,
    ( q$ |! q! Q2 w$ h( @* d0 _       cut = c(0.3,0.7),   N3 z; k0 h8 l) J6 S- c& k
           niter = 500, 1 p) B8 ]3 C: t0 Y4 T$ y; C
           updown = 'category')
    & A6 x$ z0 f) E/ R) I2 h. B: o" A( t5 r  ]* E. h. A
    1  M; R4 w% G& o2 ]  d4 n( B
    其中,cut是判断风险高低的阈值,我们使用了0.3,0.7,代表0-0.3是低风险,0.3-0.7是中风险,0.7-1是高风险,这个阈值是自己设置的,大家根据经验或者文献设置即可。1 o% a$ f# z5 f0 v% x# q
    / m! G, h$ K7 `) z3 \
    niter是使用bootstrap法进行重抽样的次数,默认是1000,大家可以自己设置。
    " |0 E% k: G7 n" q# D- y3 U6 @% }8 C2 s7 h8 Z4 M
    updown参数,当设置为category时,表示低、中、高风险这种方式;当设置为diff时,此时cut的取值只能设置1个,比如设置0.2,即表示当新模型预测的风险和旧模型相差20%时,认为是重新分类。: V+ B5 h/ x8 r; k" y
    % D7 J# ?& O+ y) u4 V8 o+ G
    上面的代码运行后结果是这样的:+ T7 Q7 W8 Y# W- p& n  s- ]
    7 k. w" Q& K  {% I, v$ ?" y$ i
    UP and DOWN calculation:
    # A- L. ]7 @" l  X; u  #of total, case, and control subjects at t0:  232 88 1440 S7 E7 T: C! q! P% H, X. p6 a' Y

    $ B" p2 q: U/ z/ [0 U" T3 V  Reclassification Table for all subjects:
    6 ?9 Q  `! N' l5 V2 D' S% P) b        New8 z* t1 r1 o' @! I- a
    Standard < 0.3 < 0.7 >= 0.7
    ; _1 v! Y0 m1 d$ Z' p  < 0.3    135     4      0
    / y/ T* f' K# w- W! {  < 0.7      1    31      4' A. Q/ z$ i. N# z
      >= 0.7     0     2     55
    . b, H2 ^4 X9 h) [# t% a& k2 I  F* C# T  w* e* S
      Reclassification Table for case:& e9 @7 R- D; f. J( l0 V
            New
    6 X# s* k8 R5 }' Z' QStandard < 0.3 < 0.7 >= 0.7/ d. {. H1 n' Z1 H3 J
      < 0.3     14     0      0
    9 G+ ^( I4 y! L; D6 q# T  < 0.7      0    18      3
    / Q# f2 u' w( P/ |. i0 D  >= 0.7     0     1     52/ N7 g- j/ f2 ^: l# R' S+ n
    ( S& \# X5 K) |5 ]- ]
      Reclassification Table for control:
    - e) o8 Z0 l. s& p) e! _9 D        New7 I  J# {  g+ ?0 m/ q, @  \0 e7 ~
    Standard < 0.3 < 0.7 >= 0.7* }7 C. w$ J% Q5 {% a
      < 0.3    121     4      0
    5 J; X2 s9 y, {& ~  < 0.7      1    13      1
    & A& O, k. m4 r- r5 L  ~  >= 0.7     0     1      3* w; _. K: n& y3 s! r' k
    ; w8 ]' |; }9 R; o, l, T
    NRI estimation:
    & @$ d1 j" c0 ]% tPoint estimates:: m9 f/ I8 u+ l& W
                      Estimate
    % R/ o8 S, P: J0 \NRI            0.0018939394 q4 ]0 B! r9 C; @7 y
    NRI+           0.022727273+ X+ g+ I! c2 D. q% y8 m
    NRI-          -0.020833333
    * ?/ A* ?2 e5 k& ~1 vPr(Up|Case)    0.034090909
      s' A5 X! r3 N  I. y6 a: p; gPr(Down|Case)  0.011363636, `" ]+ \' Q9 m) L
    Pr(Down|Ctrl)  0.013888889
    ' n" Z0 `. F. R  ]; t. [4 J" fPr(Up|Ctrl)    0.034722222
    % l( ^- b# o6 w0 G4 T4 v1 V4 x6 `3 k% x& g; D! J3 b; O; @# p
    Now in bootstrap..
    8 n. N) p! y' U+ F+ \7 K9 m3 t. o3 u$ S. k' W  j/ t
    Point & Interval estimates:) d6 d4 E$ u( c, e; [# d; C
                      Estimate   Std.Error        Lower       Upper
    - @4 L3 \/ b7 _1 x0 T8 zNRI            0.001893939 0.027816095 -0.053995513 0.055354449
    5 {3 b, U) `' F& T" O! ~7 Y+ z) }NRI+           0.022727273 0.021564394 -0.019801980 0.065789474
    . v  h2 o* X. w, X0 hNRI-          -0.020833333 0.017312438 -0.058823529 0.007518797
    5 T0 Q% ~( y* _9 N% f( D& `7 }Pr(Up|Case)    0.034090909 0.019007629  0.000000000 0.072164948
    % r6 x* Q6 f7 H7 NPr(Down|Case)  0.011363636 0.010924271  0.000000000 0.039603960
    1 Y7 I) z! R* u/ u9 D, DPr(Down|Ctrl)  0.013888889 0.009334685  0.000000000 0.0352112686 f. V. ?9 D/ {6 V; H. q+ O5 R
    Pr(Up|Ctrl)    0.034722222 0.014716046  0.006993007 0.066176471
    ' y+ A) N# F5 T- x+ G8 {" O; z1 o5 R" @  h! F. g; G: A6 ~  c, K% Y
    1
    , X% H+ G6 e0 ^& m  P- z8 c3 V首先是3个混淆矩阵,第一个是全体的,第2个是case(结局为1)组的,第3个是control(结局为2)组的,有了这3个矩阵,我们可以自己计算净重分类指数。
    $ f  u9 B& d8 e! x- N& s; {: b: [* O
    看case组:( e0 @& l4 i4 a

    $ y, Z9 f! `! x( Z5 w净重分类指数 = ((0+3)-(0+1)) / 88 ≈ 0.022727273
    ; u9 I3 B4 |2 f4 w+ Y# g$ s: H( Y' T5 R; h; _) s$ `; r
    再看control组:
    ; C" V4 O; H8 w7 N5 r
    $ L7 \$ S' S: a+ @5 n. z8 j净重分类指数 = ((1+1)-(4+1)) / 144 ≈ -0.020833333. }! G( @9 d  k

    3 w- h: ]7 R; u( ^3 `  |  b! |% \7 e相加净重分类指数 = case组净重分类指数 + control组净重分类指数 = 2/88 - 3/144 ≈ 0.000315657' y* ~( v- o5 g0 |& o/ L
    ( m1 m- O7 T8 Y3 b( s- |. I
    再往下是不做bootstrap时得到的估计值,其中NRI就是绝对净重分类指数,NRI+是case组的净重分类指数,NRI-是control组的净重分类指数(和我们计算的一样哦),最后是做了500次bootstrap后得到的估计值,并且有标准误和可信区间。
    ' b6 q5 p( F8 t9 X! d" r7 r9 O  K. J; n1 |- x- p; x
    最后还会得到一张图:
    + f/ N# a& ~9 j: |) c( W) {, e' p) D9 F9 E9 P
    这张图中的虚线对应的坐标,就是我们在cut中设置的阈值,这张图对应的是上面结果中的第一个混淆矩阵,反应的是总体的情况,case是结果为1的组,也就是发生结局的组,control是结果为0的组,也就是未发生结局的组。/ e0 y8 e0 N9 q* N& m
    ' W9 E3 ^4 K6 S$ _9 X
    P值没有直接给出,但是可以自己计算。
    + [9 h) n6 l  s' S* T6 S
    , i& l. T  R; y. b# 计算P值
    : r: C# m9 w/ e5 d8 ^3 w, _& Uz <- abs(0.001893939/0.027816095)8 V  j' G8 [; g' {& G# M* [
    p <- (1 - pnorm(z))*2
    - D$ u2 P4 A+ P4 lp
    3 @" k3 Q8 G! l' H! n; P1
    & t0 u9 j" M2 p9 W## [1] 0.9457157+ m9 ~# D" M- p3 O8 q9 I
    1, F2 K! r3 R5 ]$ k6 ^
    PredictABEL包3 F2 p( o) L/ Q" B; T5 `- `
    #install.packages("PredictABEL") #安装R包6 h4 L* p2 s# H9 w
    library(PredictABEL)  
    ! _+ A! f$ h, P6 C
    + q) j, r9 @- a* D* i# 取出模型预测概率,这个包只能用预测概率计算
    ; e3 n- M* ?) C( o5 cp.std = mstd$fitted.values3 Q6 e! `3 a/ |$ {7 i* V5 L
    p.new = mnew$fitted.values
    ) f( m2 ~- `- ~, ?' ~: W" e1
    ! Y1 @3 O" \3 v/ Y然后就是计算NRI:$ E! p5 F, D+ D2 Y, |: u+ c5 j

    # V" [# o3 T5 }dat$event <- event  Z; I. ]5 V) n0 s

    : U! m1 L, e5 v4 ~/ Dreclassification(data = dat,, X# `: m9 C& j! F6 p8 g' P4 \
                     cOutcome = 21, # 结果变量在哪一列' O0 m9 t1 R; s6 B# d
                     predrisk1 = p.std,
    " j# j* X' c7 X5 P- s7 c                 predrisk2 = p.new,
    : v+ v* j4 G% s9 z: E0 G% P0 p                 cutoff = c(0,0.3,0.7,1)
    % m6 z( j  [2 P4 K, ]9 w' C9 W                 )0 v$ z/ z- o) \" w+ o4 T
    1) C) m: q7 h' F" ]
    ##  _________________________________________% {) C- x% l! d! l9 V
    ##  . x  e/ h0 b) D3 A2 T
    ##      Reclassification table   
    + ^; i* {/ H- {' P. g1 g##  _________________________________________2 `0 F5 y, r' z$ U% ]5 E, L
    ##
    ! @3 z2 X: v0 {2 l# K" ]( q6 T( ]##  Outcome: absent 0 J( }& N& m% m  z% x: E) q
    ##   : r8 Z: u; r9 I* M! ]
    ##              Updated Model- W( C3 `5 M& j$ c
    ## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
      X7 m7 i8 ]9 Q##     [0,0.3)       121         4       0               36 K; G. R& ^  H' W& O8 f0 X. v
    ##     [0.3,0.7)       1        13       1              137 c+ Q  X$ x. P# w4 h" ]
    ##     [0.7,1]         0         1       3              258 o/ d' d- ^$ j$ S8 q
    ##
    7 |3 Y1 O: p$ a, y2 k; e* m, q$ \##  * O4 @- g2 \( K7 x9 E* [
    ##  Outcome: present % c+ {6 B$ o8 W" ^9 {) _% D! z
    ##     E. G- R) i2 A* f8 \
    ##              Updated Model; A0 x  _, @, S" Y9 z
    ## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified3 R/ \% k5 {4 J; g
    ##     [0,0.3)        14         0       0               0% |, L6 r2 g$ g7 U2 E1 o
    ##     [0.3,0.7)       0        18       3              14( D* o& W/ l; s: I' K
    ##     [0.7,1]         0         1      52               2
    $ k. x" d" H9 }2 t8 H* k5 s##
    1 `. r: p/ w; E6 z# A##  
    $ Q0 Y1 b. e; G' R8 r##  Combined Data 9 m: R8 }: A& }7 x
    ##   
    $ j: |  O# H" a& M& S* d, |# @##              Updated Model
    - P8 |, M6 V+ }# R# ~3 O2 n5 n## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified6 j  k, S! u& A- Z, T: Y1 N  I
    ##     [0,0.3)       135         4       0               33 d( c* M2 U5 M1 i: B
    ##     [0.3,0.7)       1        31       4              14
    % r) z7 B" G- `6 K##     [0.7,1]         0         2      55               4" ^% j8 k5 t9 j
    ##  _________________________________________! I: Q5 a4 a% c  b; G; }
    ##
    ( _! S( A) C6 G7 u% p7 z- n##  NRI(Categorical) [95% CI]: 0.0019 [ -0.0551 - 0.0589 ] ; p-value: 0.94806 2 I; Z9 k& S7 c6 X# t4 H; D/ }
    ##  NRI(Continuous) [95% CI]: 0.0391 [ -0.2238 - 0.3021 ] ; p-value: 0.77048
    ) e7 o* w; p8 O##  IDI [95% CI]: 0.0044 [ -0.0037 - 0.0126 ] ; p-value: 0.28396
    + M7 [+ i! |7 a/ H$ w5 ~% [3 Y
    : b8 y  g7 ^7 u) A& D3 Z1  C5 R6 P% |7 A6 f3 I* m0 V! a/ }6 Y
    结果得到的是相加净重分类指数,还给出了IDI和P值。两个包算是各有优劣吧,大家可以自由选择。& `& e. X; g* D4 w7 g; K

    . M- q) D% H( @# j; O; Y3 C生存分析的NRI) x( y. Z0 I/ w- v& i8 y% z
    还是使用survival包中的pbc数据集用于演示,这次要构建cox回归模型,因此我们要使用time这一列了。" B! _" u' c4 A4 T% l$ {
    + Z( Y' T: ?) ]1 n/ ]
    nricens包7 }8 N) y" w7 }2 m; R9 B
    library(nricens)7 E2 ~* f* D, j) q! ?% l0 `7 K
    library(survival)
    3 y" `1 t0 D7 [2 t9 ~. Q8 u
    ! {9 d& ]& H! O+ ddat <- pbc[1:312,]* e, p! z7 C9 M( d) S* b9 W) ?
    dat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡6 \7 G5 D; r; X0 G5 w2 G5 x( o1 u
    1
    % x$ ^( @2 U/ E3 X" ~$ [, g, B6 G然后准备所需参数:' M' U% y' Z. J' G8 x2 K7 U  c" k
    # N5 x$ W( m  o# Z) a
    # 两个只由预测变量组成的矩阵
    0 r* `4 j- H1 R6 E3 L" Z- {z.std = as.matrix(subset(dat, select = c(age, bili, albumin)))1 K- L0 F6 X, b
    z.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))1 B/ B# S. U1 H, k' U+ V, k+ |6 r

    * V* h) M9 u+ \; u; U. c3 O' a# 建立2个cox模型
    ' Q8 P9 P  d! O0 w" ymstd <- coxph(Surv(time,status) ~ age + bili + albumin, data = dat, x=TRUE)
    , Y! z: z3 X) |; c" Z" a8 k0 w. Q* emnew <- coxph(Surv(time,status) ~ age + bili + albumin + protime, data = dat, x=TRUE)
    / g1 I' E% W5 @% b0 B/ J: f$ e) H$ e* {, o; \- h
    # 计算在2000天的模型预测概率,这一步不要也行,看你使用哪些参数* w! G6 |$ D/ s) n# f% j
    p.std <- get.risk.coxph(mstd, t0=2000)+ b  R; x3 {" K; \0 P6 w
    p.new <- get.risk.coxph(mnew, t0=2000)% _  F$ f4 F' T, a; i
    1) p* z8 E$ q1 `( A! I4 ]; Z
    计算NRI:2 t$ K; A: C& s2 w5 P( V$ m

      F9 g6 O. v! m6 @nricens(mdl.std= mstd, mdl.new = mnew,
    7 z& [" x% N+ k0 l2 n, ~        t0 = 2000,
    - W  n2 e- @. |. @        cut = c(0.3, 0.7),
    $ ~& }5 o7 z; m; y" ]        niter = 1000,
    : |" w2 U+ k! l9 @6 v        updown = 'category')# L; ~! w( {4 W3 S1 p& l3 S
    # S0 W( V5 B2 R5 O  f
    UP and DOWN calculation:
    # T" j2 q+ [6 u+ F, e. R! u  A  #of total, case, and control subjects at t0:  312 88 1441 O# U" k) \9 ?4 r9 l( t+ k

    5 h' B6 Y9 W$ u  Reclassification Table for all subjects:- N) Q9 @8 W* ~8 I  k' J
            New
    ( `! F# i. n2 u* PStandard < 0.3 < 0.7 >= 0.7
    : q, i5 q# j* Z- s1 }0 V  < 0.3    202     7      0
    7 u6 k6 l- o8 N( ?" O" `: y% @  < 0.7     13    53      6
    ; D! U) K0 {- ^1 F: y5 U  >= 0.7     0     0     31' A* @" a$ C4 h6 H; P; C9 r

    9 ~/ G; G9 R6 h8 m! ]' M) u. T' T  Reclassification Table for case:8 ?) \' l- M* f: U+ q4 J* e
            New% ?+ Z8 B" c6 N/ W" K% G9 D+ i+ I
    Standard < 0.3 < 0.7 >= 0.7
    , k0 O# Z. Y, M6 G2 q  < 0.3     19     3      0- j) a* X$ i7 i( J% t) d$ j
      < 0.7      3    32      4
    - e  k( F% O5 A3 P5 c) G4 `9 M) Q! v& q  >= 0.7     0     0     27
    ( C. F. l- {) D4 u
    , F5 @) q, ]: v$ M) _/ ~  Reclassification Table for control:. }9 m8 K) }( }
            New8 Q' L6 d+ q" t! m  {
    Standard < 0.3 < 0.7 >= 0.7
    ) n! o8 b& p% z7 P" ?( G  < 0.3    126     3      0
    " N2 m: @5 S6 a" ^2 G8 e! G  < 0.7      5     7      2& S3 `) s8 [" a- K! C$ T
      >= 0.7     0     0      18 C1 e$ N5 p2 G4 U
    6 T8 N$ `+ V  E- t! I) @- D
    NRI estimation by KM estimator:
    1 o! K! u3 a# t) M7 f2 N2 C& F' D4 l- Z1 K$ q& S
    Point estimates:0 C8 c4 }1 R3 H$ @  d$ {
                    Estimate
    / Q( W. |. u: Z! QNRI           0.05377635
    $ Z, j9 R# L  Y) BNRI+          0.03748660$ E  E+ R, \3 t8 X
    NRI-          0.016289740 x- w7 i7 T/ T5 I  d6 ^/ U2 i
    Pr(Up|Case)   0.07708938( A/ h1 a/ X9 M; C& f+ a
    Pr(Down|Case) 0.03960278. u& E" [& `1 m# u$ w2 k7 y6 s
    Pr(Down|Ctrl) 0.04256352( b1 o3 u+ @) T' h
    Pr(Up|Ctrl)   0.02627378
    ' s+ N! m9 k+ Q
    . e) Z8 u: g% {7 nNow in bootstrap..5 Y( R/ T  e9 g0 ]
    . g/ A3 N" ~8 Z8 o" p8 C9 v, u
    Point & Interval estimates:
    - Y! d8 |7 Z: @2 E8 c8 d& @" [                Estimate        Lower      Upper; o6 C9 I; @2 l0 P2 J! S
    NRI           0.05377635 -0.082230381 0.16058172# i2 x0 K& x) V7 [6 E6 q' L
    NRI+          0.03748660 -0.084245197 0.13231776
    ) ]- [% {" c" X- yNRI-          0.01628974 -0.030861213 0.06753616
    ( r8 D, j/ I# ?2 Q) y$ v3 vPr(Up|Case)   0.07708938  0.000000000 0.191022913 e! h2 u/ x  ?, s8 L0 Z
    Pr(Down|Case) 0.03960278  0.000000000 0.15236016
    : I, S, D: O, {, A$ ~Pr(Down|Ctrl) 0.04256352  0.004671535 0.098631701 y( U7 `! e. t  H. o% W+ N
    Pr(Up|Ctrl)   0.02627378  0.006400463 0.05998424& ^/ t" P" i( @4 C
      M" i8 w* [1 s+ q8 z+ P
    1
    - W3 L4 j$ m/ s6 v* N9 A1 L* u  L
    Snipaste_2022-05-20_21-49-38
    8 h! L: u% D! w  s2 b结果的解读和logistic的一模一样。* a$ y2 V; i) ~+ U' e$ M

    0 V6 i5 m' Z4 x9 ]" UsurvNRI包9 k$ z) C2 {8 l, M) C' B# ~
    # 安装R包& P8 g, v9 b9 S
    devtools::install_github("mdbrown/survNRI")# @( }8 J% J7 |/ f  h: s* {
    1# A5 ^2 F2 ~# h: {
    加载R包并使用,还是用上面的pbc数据集。; @9 D, ^: d( J4 Z2 _* J
    ' Q; E* m: W- {/ ^% b" m; Z. R
    library(survNRI)- e& p5 W& E0 P6 h
    1
    + X7 |4 |& t. r. g1 C) [## Loading required package: MASS, S# ?  `& u9 q/ [1 y/ D* I, @0 P
    1: b$ b) G" M0 d: @
    library(survival)! T; |* O3 Z: p. {" b/ j
    / p" Q, `: i1 ~& k: ?
    # 使用部分数据4 a. k" _4 C9 C& U$ S+ }& d! J
    dat <- pbc[1:312,]
    ( V- p$ p3 i0 w4 S+ t/ Gdat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡
    - b+ |; z. b! T% V9 `
    0 i) U( V# ?6 J9 `res <- survNRI(time  = "time", event = "status",
    , u* S5 a" C  S7 q        model1 = c("age", "bili", "albumin"), # 模型1的自变量2 `7 Q- d  i8 p1 ~$ [1 g8 n
            model2 = c("age", "bili", "albumin", "protime"), # 模型2的自变量
    " E# I6 f. G4 w2 ^0 f: L        data = dat, ) W3 X- G' \+ y2 W) Z
            predict.time = 2000, # 预测的时间点6 X. {8 ]& N8 `( t/ M/ [" u- _
            method = "all", * K2 ]# |+ w: J4 N
            bootMethod = "normal",  
    / T& g% D$ \' G) B* B( l0 n8 M        bootstraps = 500, ' V- |' p; G/ L
            alpha = .05), C. c- E  F+ [, b
    , G4 i" w' N$ Y
    19 W( N8 A& C. h) b9 n* L! w  S7 f6 ^) t
    查看结果,$estimates给出了不同组的NRI以及总的NRI,包括了使用不同方法(KM/IPW/SmoothIPW/SEM/Combined)得到的结果;$CI给出了可信区间。
    - W. [3 S! X4 _1 f7 x1 h5 ], ^. q" w
    res4 e+ [: O7 K7 `
    1* A' [0 ?  k+ D& s: c/ J% O3 ~/ N7 @
    ## $estimates
    + Q4 c  L) K8 c6 Y##            NRI.event NRI.nonevent       NRI
      I! |. E! r3 J5 M/ G## KM        0.20445422    0.3187408 0.5231951
    3 }1 O1 C/ K9 e+ K3 w- [## IPW       0.22424434    0.3273544 0.5515987
    ! W+ I- i" h5 @+ i7 L## SmoothIPW 0.19645006    0.3144263 0.5108763# V# O4 E4 Y9 X' z
    ## SEM       0.07478611    0.2632127 0.3379988" a6 g9 G$ l2 R* d! E& \( `) e
    ## Combined  0.19633867    0.3143794 0.5107181
    6 ~( O) C  x5 T5 s/ Y5 h##
    ( w8 ^* G! U/ q' h1 ?7 \## $CI
    1 C3 r6 T/ E$ e" t! I! f  G8 t## $CI$NRI.event9 H& _5 F+ x* K% C4 R" ]5 r
    ##                     KM         IPW   SmoothIPW        SEM   Combined( u/ Z1 o, R5 e5 M# S
    ## lowerbound -0.03915924 -0.02185068 -0.04724202 -0.1162587 -0.0473723
    ( J, b4 r4 Z/ R9 s' g$ d* M## upperbound  0.44806768  0.47033936  0.44014214  0.2658309  0.4400496% F9 k' T& n, _, s: l. E. u
    ##
    2 w  N2 d- k# r/ G$ B; S## $CI$NRI.nonevent2 |+ ~8 P8 f+ V6 r# M
    ##                   KM       IPW SmoothIPW        SEM  Combined) K" G+ P& u; z4 z: C9 G
    ## lowerbound 0.1317108 0.1396315 0.1286685 0.08638933 0.1286426
    . f& D2 ?7 L% L. {, a  Z## upperbound 0.7102251 0.7393216 0.6966341 0.51482212 0.69645497 B% V- I6 D" n5 ]
    ##
    8 |& {7 N1 t1 t+ U" s## $CI$NRI7 i9 X9 R6 s: U# D. y
    ##                     KM         IPW   SmoothIPW         SEM    Combined5 F- R" H7 P- v) {/ x4 t
    ## lowerbound -0.05112533 -0.04569046 -0.05439863 -0.04132364 -0.05443409
    ( D1 c+ K) p# O6 N, n% w& V## upperbound  0.89306122  0.92464359  0.87970125  0.64253510  0.87953153! j9 M- A+ h  B- _8 D! J3 Z
    ## - D, }" o. Q2 T6 a/ M% n' c6 V
    ##
    ( O+ b7 [0 x9 q+ F## $bootMethod
    : M. O- k1 T, o2 B( j## [1] "normal": E$ s' D2 Z1 n4 p) H
    ##
    , d5 t, x+ p3 _* q* @# H## $predict.time
    & y9 P7 p9 v- u4 e. H( Z( j## [1] 20000 a/ j2 ~( j& t9 T! v
    ##
    7 j7 N8 Y5 t; A+ Y9 _0 d8 E- F, b## $alpha
    . V" P  ?. y- J, Q; I## [1] 0.05
    : s, X6 n3 r: T$ p2 K2 M## . C; A. H& {# w0 O" ?0 h! N/ n% T
    ## attr(,"class")1 y! U6 |; {* b* @/ R; m
    ## [1] "survNRI"* M* \% ^9 |: m
    - u+ z, ?, }- N5 O* u
    1; R/ L5 s1 \: {! |
    OK,这就是NRI的计算,除此之外,随机森林、决策树、lasso回归、SVM等,这些模型,都是可以计算的NRI的,后面会继续介绍。大家如果有问题欢迎在评论区留言。' W& O2 D1 i9 c8 Y, x: v; X

    4 b$ j3 q1 l8 R$ K. }4 @7 ?/ ^+ g3 W本文首发于公众号:医学和生信笔记2 t5 M! k4 x: x8 |* h1 l
    : X; g+ U( i& F8 ^0 l( g+ A- b( W
    “ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。
    3 f  h; C  T4 P# H, v本文由 mdnice 多平台发布
    - @3 v' G7 n& }5 Y7 q, I4 I————————————————
    " F5 D$ q6 ?4 \- y# ]! Z0 D! @版权声明:本文为CSDN博主「阿越就是我」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    ' F/ H% I3 R( M$ t, p+ O9 ~6 S3 i原文链接:https://blog.csdn.net/Ayue0616/article/details/126768006
    3 p7 C3 j2 e% ^2 c$ [9 x; @% Y0 p) I- l1 b; z2 @- K0 ]
    " T+ L" @8 j* E0 {9 U% U
    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-4-10 10:40 , Processed in 0.412897 second(s), 51 queries .

    回顶部