QQ登录

只需要一步,快速开始

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

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

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

5273

主题

81

听众

17万

积分

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

    [LV.4]偶尔看看III

    网络挑战赛参赛者

    网络挑战赛参赛者

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

    群组2018美赛大象算法课程

    群组2018美赛护航培训课程

    群组2019年 数学中国站长建

    群组2019年数据分析师课程

    群组2018年大象老师国赛优

    跳转到指定楼层
    1#
    发表于 2022-9-12 18:43 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta
    6 k  X' K6 @' ]3 F
    净重新分类指数NRI的计算& {  C4 c" Z  t* _+ _
    “ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。3 ]( m* ?+ u9 T' }2 g
    NRI,net reclassification index,净重新分类指数,是用来比较模型准确度的,这个概念有点难理解,但是非常重要,在临床研究中非常常见,是评价模型的一大利器!$ @) F2 }9 {- d0 M
    * l  w: @5 E' F9 F
    在R语言中有很多包可以计算NRI,但是能同时计算logistic回归和cox回归的只有nricens包,PredictABEL可以计算logistic模型的净重分类指数,survNRI可以计算cox模型的净重分类指数。
    / H# i0 Z+ @+ E$ U2 m/ |0 P0 T# c) w
    logistic的NRI( [$ }+ m( M5 d5 s
    nricens包
    * u: y* P' m0 @# f5 [PredictABEL包! `- l6 e% @: g& S/ i
    生存分析的NRI
    % `) s! }8 b3 p# g' xnricens包
    2 M% r8 i6 N' zsurvNRI包- _& l1 D" B; |# K2 U7 x
    logistic的NRI# ?6 x4 |' C* w0 @; L
    nricens包
    3 `# S7 m* u& f$ N#install.packages("nricens") # 安装R包
    4 Z2 W$ x; l" G  h. dlibrary(nricens)
    * c  F4 s* q, G7 T* n" c9 J; W1
    3 p" I! g- E* a, ^, h+ q" r$ ?% _) q; N## Loading required package: survival  N2 Z! \8 r1 N0 A3 H
    1" y3 m# @- B. L% n8 _
    使用survival包中的pbc数据集用于演示,这是一份关于原发性硬化性胆管炎的数据,其实是一份用于生存分析的数据,是有时间变量的,但是这里我们用于演示logistic回归,只要不使用time这一列就可以了。
    5 V( R, u, z9 H9 t  O
    " `; w, L/ e: T. p+ }library(survival)
    3 d4 f1 F- C( J- D  a# Y/ `6 ]: ?# t  Z5 t. m
    # 只使用部分数据
    & B% A7 Q8 S: odat = pbc[1:312,]
    " v$ u! ~( X2 w6 r4 l3 u2 ^. Y  {dat = dat[ dat$time > 2000 | (dat$time < 2000 & dat$status == 2), ]6 B4 B0 K  l! w* v& a( c6 |( u
    % N5 m9 d3 s4 a+ D7 T, {1 p
    str(dat) # 数据长这样
    ! P) ^. G6 v; P% {18 @" ]8 k9 a6 j
    ## 'data.frame': 232 obs. of  20 variables:
    - T: t& a* C( e: ^& w##  $ id      : int  1 2 3 4 6 8 9 10 11 12 ...! X. D8 j6 [9 |. k* @
    ##  $ time    : int  400 4500 1012 1925 2503 2466 2400 51 3762 304 .... @6 c/ o+ m  T/ d5 w
    ##  $ status  : int  2 0 2 2 2 2 2 2 2 2 ...
    1 P- e, a& j# n) T( s3 @9 W##  $ trt     : int  1 1 1 1 2 2 1 2 2 2 ...# A' V5 Z4 a; u7 C1 u" l' ~
    ##  $ age     : num  58.8 56.4 70.1 54.7 66.3 ...
    % l8 C# ^/ r, o##  $ sex     : Factor w/ 2 levels "m","f": 2 2 1 2 2 2 2 2 2 2 ...
    : L( m% {# F8 d- ^##  $ ascites : int  1 0 0 0 0 0 0 1 0 0 ..., f5 N$ q. e5 Z3 ]+ n+ w8 ^3 \; L$ i1 X
    ##  $ hepato  : int  1 1 0 1 1 0 0 0 1 0 ...# k; {! a4 ]# s8 {% p0 H
    ##  $ spiders : int  1 1 0 1 0 0 1 1 1 1 ...
    # U, T  U7 h4 t' F! k* {& S$ X##  $ edema   : num  1 0 0.5 0.5 0 0 0 1 0 0 ...
      M: r6 c" r+ |8 {##  $ bili    : num  14.5 1.1 1.4 1.8 0.8 0.3 3.2 12.6 1.4 3.6 ...8 K, |: e, Y- S7 k5 I5 C
    ##  $ chol    : int  261 302 176 244 248 280 562 200 259 236 ...
    & E9 ~+ J% K3 J7 l8 }##  $ albumin : num  2.6 4.14 3.48 2.54 3.98 4 3.08 2.74 4.16 3.52 ...
    / G- s/ K; Y* d: C: N##  $ copper  : int  156 54 210 64 50 52 79 140 46 94 ..., j- e! s8 t7 D% n$ W) E
    ##  $ alk.phos: num  1718 7395 516 6122 944 ...
    3 ^8 O: s: s9 ~##  $ ast     : num  137.9 113.5 96.1 60.6 93 ...
    / s  a9 Y2 z* o  h+ Y# ~+ C##  $ trig    : int  172 88 55 92 63 189 88 143 79 95 ...' r- a, q3 u* L( F9 y6 k/ O
    ##  $ platelet: int  190 221 151 183 NA 373 251 302 258 71 ...4 v, Y1 T+ V+ v
    ##  $ protime : num  12.2 10.6 12 10.3 11 11 11 11.5 12 13.6 ...
    : E$ L" v, @7 B" K. g3 V##  $ stage   : int  4 3 4 4 3 3 2 4 4 4 ...6 s% j$ u* j% N! a: j7 Z& N" _) V! C
    2 [; o2 h5 R- n, K
    1
    ) L2 ^+ `; o9 q. rdim(dat) # 232 201 h/ b& Y( T7 m- S3 A- M/ E! v# M
    17 i, `& i! l$ Z2 \4 P3 V( Y
    ## [1] 232  20
    ; X% j( m* b) E5 P( ]1( f/ C" U3 a) v) s% E. U
    然后就是准备计算NRI所需要的各个参数。0 g1 O6 ^: a: e2 N$ @# [+ ]/ C
    2 I: R% g0 ~; S* A$ L! Q
    # 定义结局事件,0是存活,1是死亡
    % ~0 r0 T7 L% @% O$ n9 Levent = ifelse(dat$time < 2000 & dat$status == 2, 1, 0)9 t: M: G+ I( }
    7 W8 X4 I7 y* }6 @8 k9 v5 @  B
    # 两个只由预测变量组成的矩阵& E* ^2 i8 z# Z$ _2 g9 K- U* V3 ~
    z.std = as.matrix(subset(dat, select = c(age, bili, albumin)))
    ! j* k: r5 }; s. V2 S# Sz.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))8 d$ ]& N, n9 p% N

    ; _8 A! W3 q6 P' p* b+ [; I8 h6 i' p# 建立2个模型
    ! N* M! [4 B7 `/ Mmstd = glm(event ~ age + bili + albumin, family = binomial(), data = dat, x=TRUE)
    7 B6 _% z# I  H! R' V& s3 Jmnew = glm(event ~ age + bili + albumin + protime, family = binomial(), data = dat, x=TRUE)
    ' N0 q8 o8 i6 }* c" n; b! w  l: |: Y
    # 取出模型预测概率
    , m: C, G& @1 K5 F. A# W% ep.std = mstd$fitted.values5 E  n, H3 C5 Q; i4 P3 I
    p.new = mnew$fitted.values& W& ]' }$ |* M& k, V7 {' p7 b6 ]5 v
    % Y5 j2 m5 ~& o
    1
    5 L7 x6 y5 U* C# ^: u' T- H然后就是计算NRI,对于二分类变量,使用nribin()函数,这个函数提供了3种参数使用组合,任选一种都可以计算出来(结果一样),以下3组参数任选1组即可。 mdl.std, mdl.new 或者 event, z.std, z.new 或者 event, p.std, p.new。
    % t/ L7 {0 u& u- x" s( ^- b( k
    & _1 r/ L7 Z% c/ U0 b) I# 这3种方法算出来都是一样的结果; u2 a, n, @" O1 H5 G* X7 `
    . n% i( j. T1 P' D! J
    # 两个模型
    ! R( h5 l9 i& i+ wnribin(mdl.std = mstd, mdl.new = mnew, 0 ~1 ?5 Q$ y2 o2 [
           cut = c(0.3,0.7),
    # r! r, G5 A! I! I  f" _; [0 L       niter = 500, % Y- Y+ E7 f  O  B( _! L% y
           updown = 'category')  H: W  w0 r. R8 b+ M8 J
    6 T$ r# K* j' W% [, |6 l) n
    # 结果变量 + 两个只有预测变量的矩阵
    1 l) a& o. E9 s6 f2 z- |nribin(event = event, z.std = z.std, z.new = z.new, 6 M5 n1 O4 G% o! g2 ^6 z
           cut = c(0.3,0.7),
    * X7 X+ n1 r& H; H: D" ]8 X       niter = 500, 9 z9 L# U$ N, [- p0 U
           updown = 'category')4 m) S0 d/ e' X4 w& ]. U+ o2 r( J, O) D
    8 y  e1 ^$ v6 \1 F% C) e
    ## 结果变量 + 两个模型得到的预测概率. D4 Z0 p4 j- F8 B: r+ [
    nribin(event = event, p.std = p.std, p.new = p.new, % ?2 x& k7 Y6 E* `7 D# |
           cut = c(0.3,0.7), % L7 F+ X( Z7 l9 D& b9 G
           niter = 500,
    4 e* M' |! v/ K4 ^4 p) \$ [       updown = 'category'), k5 Q: J/ f9 N; K+ m, j9 E

    ! B' I2 M* s9 @& p' \2 G1) v, D5 Q; Y/ K- m( z
    其中,cut是判断风险高低的阈值,我们使用了0.3,0.7,代表0-0.3是低风险,0.3-0.7是中风险,0.7-1是高风险,这个阈值是自己设置的,大家根据经验或者文献设置即可。
    % T, S' ^  e5 F6 \+ H
    3 m4 \$ [# I7 p  \* ~niter是使用bootstrap法进行重抽样的次数,默认是1000,大家可以自己设置。
    + ^4 f. [* y  Z! B) m% L6 Q; j9 W6 y  t1 ]& {$ C
    updown参数,当设置为category时,表示低、中、高风险这种方式;当设置为diff时,此时cut的取值只能设置1个,比如设置0.2,即表示当新模型预测的风险和旧模型相差20%时,认为是重新分类。, t! v- W7 o: ^4 d, ?
    & {: A+ K8 F! x
    上面的代码运行后结果是这样的:. Q6 u* \- B. G! K/ r# H0 Y
    + ]! M  P' ]) R8 R+ g, t
    UP and DOWN calculation:* V% ~7 F& p2 P3 ^
      #of total, case, and control subjects at t0:  232 88 144; B# b1 R& n3 r& W. @+ A8 `
    7 s- L, _$ j3 R1 V, y+ X" o* v& D
      Reclassification Table for all subjects:
    7 a& g) R1 K9 }0 E6 O- l        New# d+ G) b0 S  k/ ]5 `
    Standard < 0.3 < 0.7 >= 0.7) u8 P* j0 [* k1 s) J' d2 v
      < 0.3    135     4      0
    ( n' R4 M3 }& X3 E7 l/ L$ H4 P  < 0.7      1    31      4
    - e) G+ k! i6 O( K  >= 0.7     0     2     55
    / ^" u9 _" l8 P- Y' P% x. B* e# A2 y# M' x* A
      Reclassification Table for case:9 A( Z) D8 R8 M
            New
    ( S2 \9 V- J$ i7 L7 ?Standard < 0.3 < 0.7 >= 0.7* C1 d  f; a6 ?. @) r. o
      < 0.3     14     0      01 b- X% V' x( g" Q
      < 0.7      0    18      3
    ) z. e- ]7 e; u' Y- E  >= 0.7     0     1     52: ^! d6 K2 Z" p; K: n
    * w- z3 s% R/ R& X5 g
      Reclassification Table for control:; N9 g% z4 O3 q% @! L4 B2 O9 R; O/ u
            New% F5 r4 C' U' A0 |" e3 J) ?9 f- Y
    Standard < 0.3 < 0.7 >= 0.7
      |  B' B. o) ]# H  < 0.3    121     4      0
    4 j4 t- t" L# h, k  < 0.7      1    13      1
    . h: Y, f8 {" F1 c5 w: M9 P! H  >= 0.7     0     1      3" v" a/ A9 p) k' y' A- j

    3 }5 j$ ^8 |3 b: Q6 H! h9 j, v8 wNRI estimation:
    # ~* {2 [6 k" [: p% e2 w) o: u+ }Point estimates:: q, \7 D, s; k
                      Estimate6 S0 J( J4 q! e3 J
    NRI            0.001893939% ?7 l+ o; ~& P+ ^
    NRI+           0.0227272730 x# ]. M) }/ a& A* m$ ?
    NRI-          -0.020833333# D- m% s9 {2 L5 ^( g5 e% z  v
    Pr(Up|Case)    0.034090909
      m* p" j2 S1 d6 U# C9 jPr(Down|Case)  0.011363636
    4 l0 C3 q% D$ _$ R0 Q" LPr(Down|Ctrl)  0.013888889* l# ?8 C6 _+ h* ]5 g0 Z: U% |
    Pr(Up|Ctrl)    0.034722222; |" W  T* R$ ^* j
    # i5 H! Z7 X0 C& L5 \
    Now in bootstrap..
    " W3 ]- f, s6 o# H2 \+ E' U6 g2 t1 H; @3 K. g
    Point & Interval estimates:
      y( E/ i8 i: R* K$ f" |( J                  Estimate   Std.Error        Lower       Upper( N7 i, n8 \# O- H
    NRI            0.001893939 0.027816095 -0.053995513 0.055354449$ B5 [2 U4 i/ r6 p& m
    NRI+           0.022727273 0.021564394 -0.019801980 0.065789474
    : T: Q0 M# W, {9 @NRI-          -0.020833333 0.017312438 -0.058823529 0.007518797. F& N7 E  w# M* k) C
    Pr(Up|Case)    0.034090909 0.019007629  0.000000000 0.072164948/ U* z  s' Z; r) H. q, Q
    Pr(Down|Case)  0.011363636 0.010924271  0.000000000 0.039603960
    ( C+ Z' w# b9 I, b; {Pr(Down|Ctrl)  0.013888889 0.009334685  0.000000000 0.035211268
      H7 L+ d, h3 l5 f# rPr(Up|Ctrl)    0.034722222 0.014716046  0.006993007 0.066176471
    # k0 r  A" g" Z7 B, H6 v
    " l- x% Z' B3 T! L12 I" w: g$ \: J6 ^
    首先是3个混淆矩阵,第一个是全体的,第2个是case(结局为1)组的,第3个是control(结局为2)组的,有了这3个矩阵,我们可以自己计算净重分类指数。2 j7 W# L8 v1 Y# n) g" F
    & s8 p2 {! B9 E4 Y" t4 }
    看case组:7 H, j( |& ~  y( w. f$ b6 T* q
    8 p' J. A3 p$ j9 q( q
    净重分类指数 = ((0+3)-(0+1)) / 88 ≈ 0.022727273; d( E: R! E6 q- B, f
    ' o$ S1 v9 A9 Q6 e! x0 F* i
    再看control组:
    " F- D6 G( c5 Q) y  N+ O, \
    , B2 ^6 {* \! w/ @! b* Z. W净重分类指数 = ((1+1)-(4+1)) / 144 ≈ -0.020833333% M! E' B9 \7 c+ n- Z$ S$ U$ w8 D

    . v5 M3 C9 o6 Q0 ^9 ]  \% o9 f2 |相加净重分类指数 = case组净重分类指数 + control组净重分类指数 = 2/88 - 3/144 ≈ 0.000315657* K' d9 r( w3 O3 w, V4 k
    $ K; K9 k" v9 L1 b: Q
    再往下是不做bootstrap时得到的估计值,其中NRI就是绝对净重分类指数,NRI+是case组的净重分类指数,NRI-是control组的净重分类指数(和我们计算的一样哦),最后是做了500次bootstrap后得到的估计值,并且有标准误和可信区间。
    # a& F& x( u: f( n# P- }0 ]3 g0 P0 ~5 {+ o& M
    最后还会得到一张图:  K3 n5 i0 d' b
    ; t4 J9 u$ {2 D# [3 U2 f
    这张图中的虚线对应的坐标,就是我们在cut中设置的阈值,这张图对应的是上面结果中的第一个混淆矩阵,反应的是总体的情况,case是结果为1的组,也就是发生结局的组,control是结果为0的组,也就是未发生结局的组。
    4 ]2 q$ w$ F0 u" g. D( x7 w' `( p3 d. x# N/ L# Y0 E5 ~, p
    P值没有直接给出,但是可以自己计算。% }) l% I& ]. L/ z4 f
    9 c9 J: v/ ^1 P$ u/ p
    # 计算P值
    " m8 ]3 _) P/ m6 l1 N. ]z <- abs(0.001893939/0.027816095)
    ! J+ h; N- C7 |) Q, \p <- (1 - pnorm(z))*2
    7 M% ?( u' Y7 ap) ~3 `. b) j- j
    1
    8 v6 E0 }4 D/ x- R/ v' }## [1] 0.9457157( ~- Q# l" M# a% ^" Y. }% d) t0 k
    1
    * v% [7 s$ ?0 o/ ]* [( u$ _PredictABEL包
    ; w% Q6 ], P* |6 b) {5 ^8 g#install.packages("PredictABEL") #安装R包
    $ \8 y8 W5 }" C  S$ X( rlibrary(PredictABEL)  5 B( V7 q9 w" V9 M( U! X  j! o, e
    , E5 B6 L5 @$ t7 o( x5 U) {
    # 取出模型预测概率,这个包只能用预测概率计算  o, y# n# e0 }0 T, W
    p.std = mstd$fitted.values# |3 _! z1 h2 N! L$ g3 L
    p.new = mnew$fitted.values
    & b' R; R0 P+ O( \1* c/ l" q7 R9 K+ U! \; r2 u0 |
    然后就是计算NRI:
    0 ]6 s. M5 I; _9 W2 _1 ^! H
    ! N: x: A9 N5 X2 e' w; [dat$event <- event! v/ _0 S# b' r! G1 H9 D

    3 b  M) c2 O9 w8 R5 E. j- ~& A. Q5 Greclassification(data = dat,# H& l# b+ Z8 Z3 x+ g7 ?! l
                     cOutcome = 21, # 结果变量在哪一列
    9 z9 h5 e. H  {3 O: c                 predrisk1 = p.std,( m, b" y: v  ?4 {/ q8 }0 ?
                     predrisk2 = p.new,$ T$ Q' d% o( b! B5 B
                     cutoff = c(0,0.3,0.7,1): h0 w5 Y: Z) A* b8 R+ ?
                     )
    ! e- e* k" [5 b- s6 K, Q$ p/ V1, B) ^" B  H3 l2 p. ~7 |5 f
    ##  _________________________________________
    - k2 t' K# S) H, b( o6 J) S  I##  2 }8 w& N' X; |7 n" f& b6 n
    ##      Reclassification table    2 Q/ x, r5 @( K% f( T! Z
    ##  _________________________________________4 j7 G" F$ D5 y0 y
    ## ) T* q3 [: A6 r
    ##  Outcome: absent $ p8 u; }" |8 v: k9 f0 q! W
    ##     P+ b/ D! J' ~5 ~- p
    ##              Updated Model
    6 _6 K* h, O/ T1 [* T1 b## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified& R) P3 ^2 ~7 q) K$ }7 Z; M
    ##     [0,0.3)       121         4       0               3% O# J3 A8 f/ O/ D. u4 r9 a
    ##     [0.3,0.7)       1        13       1              13
    + O3 l5 P, |  @6 K2 l! ^8 H( d##     [0.7,1]         0         1       3              25
    ! G2 ]; M( C  p# J% j/ w6 {7 ]##
    6 y  f. b" A- p, A5 f% H  l##  
    4 N1 y9 i4 J! v; p: V1 U##  Outcome: present : Q$ Z3 g) g6 \" T$ o! v/ [
    ##   ( U, c) L  G; Q% K4 @' a
    ##              Updated Model
    * a: c# s! q  |6 ?* [; u$ @. e## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
    ( C$ k: z3 l9 ^+ |7 b" L" _0 f##     [0,0.3)        14         0       0               0
    . ]  a4 m2 l8 L' S+ G% ?6 ?; R7 E##     [0.3,0.7)       0        18       3              14- C5 C/ {) c  b. J; b) f# ^  v
    ##     [0.7,1]         0         1      52               2
    6 q& `: b% Z- s2 ^( {## 2 W0 i7 x9 y1 p! b/ ^2 v+ X: i2 W
    ##  
    - C0 l* A* W6 a9 m2 u8 Y##  Combined Data - e! ~4 ~- _0 s7 r0 ~! }6 f. N
    ##   
    7 l' Z9 B; D) X$ d##              Updated Model6 ?6 Y# @, B2 E
    ## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
    - |# X* D+ V9 t##     [0,0.3)       135         4       0               3
    ) b+ u; W# ]8 i3 u: A! @" m##     [0.3,0.7)       1        31       4              148 T: c8 M% W" ]- g  B- s
    ##     [0.7,1]         0         2      55               4
    5 ^4 ^; N. z7 Q3 p; a9 D##  _________________________________________0 x- ?. P! i& j( u
    ##
    5 R6 x$ I9 I# n##  NRI(Categorical) [95% CI]: 0.0019 [ -0.0551 - 0.0589 ] ; p-value: 0.94806
    4 d: l( W: n) I" z) |7 u##  NRI(Continuous) [95% CI]: 0.0391 [ -0.2238 - 0.3021 ] ; p-value: 0.77048 2 F0 v* D0 }+ u
    ##  IDI [95% CI]: 0.0044 [ -0.0037 - 0.0126 ] ; p-value: 0.283964 O, m# b5 g4 N( Q7 j" f  V
    & N& F; ]/ `+ U0 Z% w+ ]$ |6 C5 c* T
    1
    0 ]+ j0 g) @, E$ k8 ^4 j& v结果得到的是相加净重分类指数,还给出了IDI和P值。两个包算是各有优劣吧,大家可以自由选择。
    ) r5 Y1 ]" K4 I: s' |7 Y
    7 e5 H" e$ D; N) \7 W3 i生存分析的NRI
    ; N* X7 M0 o7 j5 P还是使用survival包中的pbc数据集用于演示,这次要构建cox回归模型,因此我们要使用time这一列了。
    - q* l3 J) C1 G% A; V/ @
    2 d2 k; v7 `: [% C  u8 O! Rnricens包! M! D$ ]6 n. O: \
    library(nricens)1 z: I: r8 a2 U% F
    library(survival)" `" {$ q5 Z1 Q8 G/ w( X# w' _

    6 o9 {( S& C$ ?7 odat <- pbc[1:312,]
    - J5 a8 k: d- R+ z" V/ ydat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡
    . m0 f; b9 T2 i/ G: j14 U0 k: N& Y6 B2 Y* R) v
    然后准备所需参数:
    6 S# C: w! b8 J- M, s7 z$ a' }5 s5 R5 |& {- x0 O- W" n5 U$ C
    # 两个只由预测变量组成的矩阵
      e* N) L# X0 G1 \$ kz.std = as.matrix(subset(dat, select = c(age, bili, albumin)))
    5 V" j$ T8 o9 v  j% B; qz.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))
    ) a+ _7 q2 m' w0 \7 x9 s
    ! t1 n& M4 z+ j5 v4 ^# ^# 建立2个cox模型
    2 \5 z9 c+ L. D5 A5 X$ B8 L( umstd <- coxph(Surv(time,status) ~ age + bili + albumin, data = dat, x=TRUE)0 R3 d+ }) `2 W5 D1 T8 @  s' O* h/ y3 n
    mnew <- coxph(Surv(time,status) ~ age + bili + albumin + protime, data = dat, x=TRUE)
    : m: {" U) f5 Y# u! P" e, i6 ]0 B; V! a' P. `0 ?0 k6 ^# h
    # 计算在2000天的模型预测概率,这一步不要也行,看你使用哪些参数8 M  n( q+ T5 Z/ P, X# c
    p.std <- get.risk.coxph(mstd, t0=2000)
    7 M& Q4 X8 H& [; {p.new <- get.risk.coxph(mnew, t0=2000)/ p$ @1 O9 [! |$ c
    1
    # S6 Z4 E1 a2 F4 q) K% \; Q+ w计算NRI:- q8 ^# y% }$ `# F" D. N

    ) G2 a6 W7 n. G+ a0 F$ j0 e/ `, Mnricens(mdl.std= mstd, mdl.new = mnew,
      h2 F" m7 m7 [5 Z+ N) P/ m        t0 = 2000,
      y" q( U2 e% V. ]! N/ d        cut = c(0.3, 0.7),
      _. K/ n. X9 ]2 C8 ^$ ?  D        niter = 1000,
    " v- @0 |# [& D& E2 P- S        updown = 'category'); {/ V% s* j) g. V6 I: ?# f

    9 D6 o$ F2 j# m# J9 \+ H! b* KUP and DOWN calculation:* X& p1 B% t2 {6 N; N- u- t6 ]
      #of total, case, and control subjects at t0:  312 88 144
    7 Y9 ~  n0 h) z% L9 Z% v
      `1 X7 a* ]1 E" U0 W+ {  Reclassification Table for all subjects:
    # y. Q8 R  s4 F" i8 G( z  D        New0 H, j$ L1 q" x, y
    Standard < 0.3 < 0.7 >= 0.7
    3 D4 b5 S9 c( Y8 c1 U0 N0 W( J6 ^  < 0.3    202     7      08 g' t4 B% i5 L9 {6 X( g
      < 0.7     13    53      6
    * ]' L" \6 ~9 M$ O6 v1 i  >= 0.7     0     0     315 O" b, M0 o, R
    ' D) p( j, l/ W. f2 I
      Reclassification Table for case:
    4 p, Z7 N3 _' [" |( ]1 y        New( L" o7 r% s9 z
    Standard < 0.3 < 0.7 >= 0.7
    ; o* v4 m, ~1 z) B$ d/ A  < 0.3     19     3      0; @" M8 c5 O- N" J( X5 ]- E
      < 0.7      3    32      4+ L4 M3 T; t, m" y5 e
      >= 0.7     0     0     278 V2 b* F( V( A$ @

    + c$ R6 i5 P7 E9 y7 h* b! U  Reclassification Table for control:% K7 b  `8 `  z) E" M" U$ P7 p
            New% c" m+ c, X( d: ?$ |
    Standard < 0.3 < 0.7 >= 0.7
    ) o. I. X. ~  d% f; a  < 0.3    126     3      0
    " C4 v4 C% y) b& D) p! |" D  < 0.7      5     7      2( }0 s' {- S, O  D
      >= 0.7     0     0      1
    * h8 a1 Y5 Y( G5 {* F6 R# n1 I
    , \/ W0 X8 T7 y! O/ J$ ]) s  QNRI estimation by KM estimator:/ k- F7 ?4 Q5 w% p* {7 ^
    % Q: i# S5 Q& q+ g" y9 s7 S/ \
    Point estimates:( H: @, n# K! Q2 X0 @
                    Estimate
    : ~9 W! b; Y2 f3 L5 oNRI           0.05377635/ g, W- j& l7 q$ V$ Q, e
    NRI+          0.037486601 \9 s8 ?+ a" s" j
    NRI-          0.01628974
    6 M0 O+ Q* o: P) h& l  v6 u0 xPr(Up|Case)   0.07708938
    ) e* V0 U: z8 o' w6 x, S8 dPr(Down|Case) 0.039602785 |( l, x$ K$ o9 Y; ~. }% x
    Pr(Down|Ctrl) 0.04256352( h/ Y3 X3 v$ @% O# O5 J2 H
    Pr(Up|Ctrl)   0.02627378
    5 A. ~' v; W/ a1 x) f/ z1 y$ s3 {" k6 p  l) q
    Now in bootstrap..4 m$ y; C' V$ F; y7 S
    # _+ g( ~+ Z% t- U5 X8 g
    Point & Interval estimates:
    8 r4 S; w( j' V) J3 Q                Estimate        Lower      Upper& b/ q  N7 M! E& |) S
    NRI           0.05377635 -0.082230381 0.16058172
    % ^' I1 I/ @/ R, O1 eNRI+          0.03748660 -0.084245197 0.13231776
    9 i9 i& V+ L3 D1 u4 a% CNRI-          0.01628974 -0.030861213 0.06753616, ~+ D9 z& `$ E5 ^
    Pr(Up|Case)   0.07708938  0.000000000 0.19102291
    & v9 _% n& T8 A+ `1 BPr(Down|Case) 0.03960278  0.000000000 0.15236016  }+ b; B( N: ^6 v2 `
    Pr(Down|Ctrl) 0.04256352  0.004671535 0.098631709 J. ?4 V# X& f8 f/ W9 y3 H% R: j
    Pr(Up|Ctrl)   0.02627378  0.006400463 0.05998424* k/ p+ j/ h' M; h- n  q  V
    $ J, a, g  {( J3 }0 m6 K. K
    1
    : G: e% ^, c" u! R5 c8 P
    6 {5 K$ x0 m7 W7 O( c/ k3 tSnipaste_2022-05-20_21-49-38
    2 H) N. v: L* u; F结果的解读和logistic的一模一样。! X, q7 d/ k5 V8 X1 S( \$ M! F

    8 n# p4 @( Y+ DsurvNRI包( O- c2 R2 p+ b, Q* n7 o$ K: e4 t
    # 安装R包
    7 ^4 o% O. o, ]' {devtools::install_github("mdbrown/survNRI")
    9 f0 n9 {4 m; B4 w6 W1. q9 {: Q$ g# E/ K5 V- Z
    加载R包并使用,还是用上面的pbc数据集。
    & b" e" i! K9 j. u" t/ h
    & K' U7 Q9 T3 h# Glibrary(survNRI)1 v2 `$ }+ f4 V: G! [
    1: N" J4 n* z, r. J
    ## Loading required package: MASS2 U5 }! z1 W+ Y
    1
    , B) o0 N, A7 z7 flibrary(survival)
    5 J, R) y, ^$ X+ n4 q9 Z- {: M0 o( _! s( W, f6 V- g, n7 e
    # 使用部分数据7 j  A, }& o+ @* C2 |; ~9 b6 J
    dat <- pbc[1:312,]8 ~/ N" `  G5 ^: q8 ~
    dat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡
    5 |0 P; R2 D  E; j6 Z# [2 S
    " m$ _7 q3 ~7 R7 W* Wres <- survNRI(time  = "time", event = "status",
    3 W: i6 b4 D3 f8 c        model1 = c("age", "bili", "albumin"), # 模型1的自变量5 F9 C& _6 r2 F! _1 b% n, @
            model2 = c("age", "bili", "albumin", "protime"), # 模型2的自变量
    4 c9 e0 t4 M) i5 P        data = dat, 8 u: I# S- Q, R1 B5 V
            predict.time = 2000, # 预测的时间点
    0 {& W( ~$ F1 x1 W  @        method = "all", + N6 u0 v% w; n# `6 ]& k! A
            bootMethod = "normal",  
    6 k1 ~+ U( z0 O& t) X1 r. \        bootstraps = 500,
    & B+ @: E5 v' N) x        alpha = .05)  X" V9 M4 H' Z
    6 ^0 R1 w# C- [  |7 o- U
    1
      f3 ~/ F9 w- h+ P% @; x查看结果,$estimates给出了不同组的NRI以及总的NRI,包括了使用不同方法(KM/IPW/SmoothIPW/SEM/Combined)得到的结果;$CI给出了可信区间。6 e1 ?0 ?. Q/ V$ a! @" C) Q

    ; U- \  U* Z' v* B, u$ A( Bres& I) U6 V1 u6 O% c
    1
    5 }( [+ z3 V- i+ I## $estimates
    . H! x8 w2 b- Z! W% k6 v: n##            NRI.event NRI.nonevent       NRI2 D* k* C1 P7 Y) N" H* W2 o
    ## KM        0.20445422    0.3187408 0.5231951# `% ]( X2 @6 {. I2 X$ Y( b9 X# b) O
    ## IPW       0.22424434    0.3273544 0.55159871 }5 `. b7 I5 @) y) q
    ## SmoothIPW 0.19645006    0.3144263 0.5108763
    ' _  T  n  o4 Y- _. y( Z## SEM       0.07478611    0.2632127 0.3379988
    ( v  Y  y0 n: H1 u5 C: B## Combined  0.19633867    0.3143794 0.5107181
      J; L3 u3 `5 E4 D; N  y% H## * z7 I' M! D2 a' j$ ?
    ## $CI
    7 y1 \: _* K- d- \# q' V## $CI$NRI.event2 B9 g6 ^! p) R5 s& J, @4 p( a
    ##                     KM         IPW   SmoothIPW        SEM   Combined  r% X  `, {) K, o
    ## lowerbound -0.03915924 -0.02185068 -0.04724202 -0.1162587 -0.0473723
    ; N. Q+ c2 ]# o! J$ G1 ~" V## upperbound  0.44806768  0.47033936  0.44014214  0.2658309  0.4400496
    * J! B, T& [8 q2 U## 8 T4 f! I: e5 K0 o8 Q
    ## $CI$NRI.nonevent: u  _  \( f8 |) a
    ##                   KM       IPW SmoothIPW        SEM  Combined& C$ |1 L6 b2 @0 g1 k" O
    ## lowerbound 0.1317108 0.1396315 0.1286685 0.08638933 0.1286426
    3 F& k, r4 k7 I9 Q## upperbound 0.7102251 0.7393216 0.6966341 0.51482212 0.6964549$ `3 ]" ?, \1 a& T+ `8 r
    ## / ~/ n* ]2 k' J$ f2 o% \
    ## $CI$NRI- ]) v6 ]7 ?0 q9 n% N3 a3 W. V
    ##                     KM         IPW   SmoothIPW         SEM    Combined3 ]/ J" u, Y! Z  Y$ h+ n" \9 N
    ## lowerbound -0.05112533 -0.04569046 -0.05439863 -0.04132364 -0.05443409
    - y0 J1 f+ T- {## upperbound  0.89306122  0.92464359  0.87970125  0.64253510  0.879531536 i* x$ G$ P" D; z1 ]
    ##
    . N9 }8 q: A; r9 P+ g! G##
    3 b' K2 J: x: l  ^! n/ i6 n% ^## $bootMethod2 w* d1 `" i! ?+ V. e8 p- D" z
    ## [1] "normal"5 Q+ x  b3 g$ Q; l" q
    ## ; A' A4 h: X3 T/ W# @
    ## $predict.time
    : P% i/ d* T' H  N+ X' F7 n/ m9 _## [1] 2000
    6 T, m# g8 J: l8 F## + h! q* Y- S8 Z/ G
    ## $alpha( P# |, W. ?. N7 I7 j9 b9 I
    ## [1] 0.05
    & S( `) |2 y7 I9 ^##
    & F7 x; I7 D0 O' R9 x& J5 G1 O## attr(,"class")
    4 j9 e3 M/ M) C% s+ @## [1] "survNRI"- W) j' u+ ^& M- J

    $ ?0 r) V% m6 O! ]1
    2 Y1 o+ j5 |- y2 }+ gOK,这就是NRI的计算,除此之外,随机森林、决策树、lasso回归、SVM等,这些模型,都是可以计算的NRI的,后面会继续介绍。大家如果有问题欢迎在评论区留言。
    + A6 h; l3 j: b* o) L. ~+ K6 `. W/ e$ w- `8 P
    本文首发于公众号:医学和生信笔记
    ; C) c# l) b7 ?, z* {3 u! x0 P$ Q2 G5 E2 ]  g
    “ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。
    7 b1 m9 h0 e. H0 W$ p+ |% O本文由 mdnice 多平台发布- H! C/ d9 t! {. `% K" v9 ^
    ————————————————
    6 m) @# p1 x# D9 H版权声明:本文为CSDN博主「阿越就是我」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。# U( k4 }, O: j& u( A
    原文链接:https://blog.csdn.net/Ayue0616/article/details/1267680064 e- e+ `9 e/ c/ u; L. I
    3 T+ t( h& C+ z& |1 A

    * A3 B9 S$ K" F0 \; m
    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, 2025-5-31 09:00 , Processed in 0.694441 second(s), 51 queries .

    回顶部