QQ登录

只需要一步,快速开始

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

    % [4 E9 {$ r1 `7 P* }' i净重新分类指数NRI的计算
    & Q% Z& F/ b- R3 a+ y5 ~“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。8 }* U; P) X% _% n1 @! i# e$ V! x
    NRI,net reclassification index,净重新分类指数,是用来比较模型准确度的,这个概念有点难理解,但是非常重要,在临床研究中非常常见,是评价模型的一大利器!! i( s- Z" L; n; r7 W; M5 R

    , C) h, |7 \* Y( R在R语言中有很多包可以计算NRI,但是能同时计算logistic回归和cox回归的只有nricens包,PredictABEL可以计算logistic模型的净重分类指数,survNRI可以计算cox模型的净重分类指数。6 a: k1 ?! X- P1 S
    8 M+ l) g& s8 t
    logistic的NRI
    * Z3 S# g5 H1 ]) U' {4 c. Tnricens包4 M3 k0 x: R' Q: R3 }% ^
    PredictABEL包, r4 t, t; q) ~8 X5 m1 k
    生存分析的NRI
      Q7 [" B0 l4 R. |' z) ]nricens包
    : H1 ]  T. I0 n: q$ \  HsurvNRI包+ |* G9 @' g0 F
    logistic的NRI+ ?- F  v+ A* w. V4 H( s
    nricens包
    ( L' R/ K: x4 a#install.packages("nricens") # 安装R包0 y$ c1 H9 U$ j) S8 |8 m% \
    library(nricens)
    $ _5 ]; `- O( B  R1 A! l: ]1( Y* p) c7 [3 L$ l6 Q
    ## Loading required package: survival
    # P; v7 w& k8 R) s. }: ~* A" C1/ y. u. [$ h% h2 R6 B
    使用survival包中的pbc数据集用于演示,这是一份关于原发性硬化性胆管炎的数据,其实是一份用于生存分析的数据,是有时间变量的,但是这里我们用于演示logistic回归,只要不使用time这一列就可以了。4 y1 c$ S; q! S5 {, D/ k- s4 a# m

      P+ k0 y. R, D: j, `' Qlibrary(survival)$ L; W* t) X* ]$ S" Q3 c
    % ?+ F$ K7 X/ f% w; r+ @
    # 只使用部分数据
    0 T" u# @4 V0 v# ~! |  Gdat = pbc[1:312,] 8 b. V. C/ z9 W
    dat = dat[ dat$time > 2000 | (dat$time < 2000 & dat$status == 2), ]
    . u% h+ m+ X5 E. C) `% w# f: I$ i3 R+ h# [  c
    str(dat) # 数据长这样' L/ O' ]( L8 ^9 e# D
    1: @" u7 U6 m/ ]# R' K9 C
    ## 'data.frame': 232 obs. of  20 variables:
    7 B" P" |3 I, M5 r4 r4 r$ G##  $ id      : int  1 2 3 4 6 8 9 10 11 12 ...5 V! v  G+ t( L" W' f
    ##  $ time    : int  400 4500 1012 1925 2503 2466 2400 51 3762 304 ...
    3 ?' d; i" q9 f- x7 v##  $ status  : int  2 0 2 2 2 2 2 2 2 2 ...
    1 V! T# W; p- J; R, t8 V##  $ trt     : int  1 1 1 1 2 2 1 2 2 2 ...
    # W- ~+ t) ]  _! _##  $ age     : num  58.8 56.4 70.1 54.7 66.3 ...9 x: V$ u8 L1 p9 O* W
    ##  $ sex     : Factor w/ 2 levels "m","f": 2 2 1 2 2 2 2 2 2 2 ...
    , K& l3 L  \' E' T6 ~##  $ ascites : int  1 0 0 0 0 0 0 1 0 0 ...
    4 B: a9 h+ i) h5 a* s. x##  $ hepato  : int  1 1 0 1 1 0 0 0 1 0 ...6 P  X" \6 P) v
    ##  $ spiders : int  1 1 0 1 0 0 1 1 1 1 ...) Y) H! ?$ H1 H, Y' U; L; ]4 ~
    ##  $ edema   : num  1 0 0.5 0.5 0 0 0 1 0 0 ...
    2 }+ M* ~# a5 E# C##  $ bili    : num  14.5 1.1 1.4 1.8 0.8 0.3 3.2 12.6 1.4 3.6 ...) P! d2 n9 G& B5 B" ]8 O
    ##  $ chol    : int  261 302 176 244 248 280 562 200 259 236 ...* @! c3 s# E: d0 s+ ^: }+ i
    ##  $ albumin : num  2.6 4.14 3.48 2.54 3.98 4 3.08 2.74 4.16 3.52 ...1 {8 @# p9 o4 g9 |, l. u
    ##  $ copper  : int  156 54 210 64 50 52 79 140 46 94 .... O: j2 D/ v% \0 x; B+ ]+ N+ \/ S0 D+ {
    ##  $ alk.phos: num  1718 7395 516 6122 944 ...7 }, K) y! X  \1 q! Y
    ##  $ ast     : num  137.9 113.5 96.1 60.6 93 ...  ^9 H$ P4 p' c% L, I$ v8 w. I
    ##  $ trig    : int  172 88 55 92 63 189 88 143 79 95 ...
    ' p+ o- a2 r# @  F6 r% o##  $ platelet: int  190 221 151 183 NA 373 251 302 258 71 ...3 E% n9 G# r3 H8 ?  c2 q3 T
    ##  $ protime : num  12.2 10.6 12 10.3 11 11 11 11.5 12 13.6 ...8 G( p1 Q2 A3 A+ t
    ##  $ stage   : int  4 3 4 4 3 3 2 4 4 4 ...2 q, n; K; Q/ R5 w; x

    # W( k3 `4 {0 Z- n5 Y' \$ s. n1. e% j% x9 H  V- S: j! {
    dim(dat) # 232 20" g6 K9 V0 K. ~' w
    1
    + n2 R. M0 U3 U. L& J5 C## [1] 232  20
      E' ^: p; w# @1
    . I7 V) {0 z  T4 p$ F2 R然后就是准备计算NRI所需要的各个参数。( H& {4 B/ U% J) u, {0 K- y

    . p! U. n5 ~. }7 Q; P# 定义结局事件,0是存活,1是死亡
    ; e+ G: y8 ^! z) i5 Wevent = ifelse(dat$time < 2000 & dat$status == 2, 1, 0), W) j' L9 z5 a& ]9 X6 s" p

    0 p" C3 v" N9 C, S$ \" D5 g# 两个只由预测变量组成的矩阵6 x& I3 d1 y- r; b
    z.std = as.matrix(subset(dat, select = c(age, bili, albumin)))1 |8 |+ G+ P& A
    z.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))+ L& W1 \# j, i

    + v, c9 c" S7 x7 @9 \, `4 R& _# 建立2个模型# b0 r. V; M9 u/ z3 v
    mstd = glm(event ~ age + bili + albumin, family = binomial(), data = dat, x=TRUE)
    1 F+ g4 _2 d9 T$ f6 wmnew = glm(event ~ age + bili + albumin + protime, family = binomial(), data = dat, x=TRUE)# c! l$ z5 |' @( D

    6 P8 }+ s4 c, [3 K# 取出模型预测概率! D' v. ^# \" c! H5 ]. ?
    p.std = mstd$fitted.values5 R- s8 s& {$ X! e6 B
    p.new = mnew$fitted.values
    5 Y4 x: ]/ k) \8 {2 }/ Q! [; E& |2 ^* T* E; n# j9 A1 n: a- q
    1
    , I; \# W1 F1 g& W- l1 a, `然后就是计算NRI,对于二分类变量,使用nribin()函数,这个函数提供了3种参数使用组合,任选一种都可以计算出来(结果一样),以下3组参数任选1组即可。 mdl.std, mdl.new 或者 event, z.std, z.new 或者 event, p.std, p.new。0 o" v( O( H9 h! T
      j) O4 \1 G5 r, @
    # 这3种方法算出来都是一样的结果! ^' z6 w0 L0 D/ a3 z+ f

    3 i' L$ c- C( x) r- L8 \+ K, B# 两个模型% e* j& o/ g/ h% x
    nribin(mdl.std = mstd, mdl.new = mnew, " X8 m: _. o% F4 b4 y, E/ s+ o& X9 g
           cut = c(0.3,0.7), / ~0 g* x* p; x' s
           niter = 500,
    9 j4 E1 [1 a0 G( S  D; Z, e       updown = 'category')
    , F# o0 @& H. V6 j6 I
    5 p6 X! _" {5 |; J( ]0 }8 Q# 结果变量 + 两个只有预测变量的矩阵
    6 R" t+ E# j- O% F2 ~* t% Fnribin(event = event, z.std = z.std, z.new = z.new, 6 v2 _7 _4 k2 O$ P( ^
           cut = c(0.3,0.7), / X0 ]. `1 q& L; A# f% p
           niter = 500,
    ' ]6 G4 J6 `' W0 e% G: d4 Y       updown = 'category')* Z& s0 m2 G, B1 J6 c
    0 ~5 T  _; h* J4 W7 k% @
    ## 结果变量 + 两个模型得到的预测概率
    # O% g: c1 d2 X- D, ^. b+ [nribin(event = event, p.std = p.std, p.new = p.new, . N: D" I$ R7 D% B' c. ^
           cut = c(0.3,0.7), 7 S# Y6 W7 L0 Q! v. U
           niter = 500,
    6 f8 }7 O+ L3 |; m4 |0 @5 m$ ]- i4 |       updown = 'category')
    ! w& M: I9 L( i7 O
    ) q; w7 A( X! n. I1
    / a0 Z4 @- n/ Q5 h$ E2 T$ W! x3 P0 d其中,cut是判断风险高低的阈值,我们使用了0.3,0.7,代表0-0.3是低风险,0.3-0.7是中风险,0.7-1是高风险,这个阈值是自己设置的,大家根据经验或者文献设置即可。3 C  n! o0 L: {- x

    ) v% a* j) y' n6 Q6 F, U, I+ hniter是使用bootstrap法进行重抽样的次数,默认是1000,大家可以自己设置。
    , v! l8 i/ |; w) C1 ^! H. I' K' p% D+ G8 w* R' c) ?( r
    updown参数,当设置为category时,表示低、中、高风险这种方式;当设置为diff时,此时cut的取值只能设置1个,比如设置0.2,即表示当新模型预测的风险和旧模型相差20%时,认为是重新分类。
    " g& e1 Z0 i2 F% U4 U! ]
    ) s# H3 @0 P$ b  X8 A上面的代码运行后结果是这样的:
    1 @; v5 ?+ @( \% ]1 e: P
    $ f5 p( B* c+ M3 y' WUP and DOWN calculation:) Y! G, K% S# l  @- T% W6 S
      #of total, case, and control subjects at t0:  232 88 144) K) c& d8 `. k

    % J  V* v: H& ?# f* a+ j( ?3 U  Reclassification Table for all subjects:
    5 y# F* f9 B' X) x# ]0 F        New' j( r* ], R7 Y/ j2 M0 u# I' N
    Standard < 0.3 < 0.7 >= 0.76 T2 Q) d7 ]4 V1 `
      < 0.3    135     4      0
    4 O- p0 p" _. z" N7 [  < 0.7      1    31      4
    5 E$ x5 ^/ o- e( P# K- |) r' D2 w3 t  >= 0.7     0     2     55) i' E7 x. V2 K2 X

    2 M) [4 N" U6 G, z8 p1 \+ w  Reclassification Table for case:1 [- z0 P2 m' b, X& o, \
            New
    ( C7 z2 ~" L+ uStandard < 0.3 < 0.7 >= 0.7
    + @7 n; i8 V/ {0 P4 `  < 0.3     14     0      0
    9 m7 {" J4 H/ H6 I3 Z1 S  < 0.7      0    18      31 i' ]$ H  E" N. O; F- P6 m( f( ^
      >= 0.7     0     1     52
    9 q/ `. \1 `: o7 v
    1 ?9 Q' @- C# O' p0 r% R0 P& z! Y  Reclassification Table for control:4 t8 g' F3 b( f
            New
    ) S2 I& }5 C, P' E# AStandard < 0.3 < 0.7 >= 0.7
    " y( k. g: _! s! H7 q+ O  < 0.3    121     4      0
    . I: w, d3 A3 y; l: I  < 0.7      1    13      1- L6 Y" y7 E. Z2 `2 C  @4 M
      >= 0.7     0     1      34 Y# {. t0 N  {/ ^

    7 ?, k% j$ w5 d0 g* m! XNRI estimation:# P! E3 _/ {' ^* i
    Point estimates:8 n# W. V5 ^) g$ ]* c8 E
                      Estimate4 o  O, b6 _: A+ ?
    NRI            0.001893939
    % t) w' T  o7 GNRI+           0.022727273( f9 h% K# M8 ?* Z2 f
    NRI-          -0.020833333; |1 v# L: V& g/ p
    Pr(Up|Case)    0.034090909
    ! t* ^- ?  z9 j( `  z* |7 R$ oPr(Down|Case)  0.011363636% I( t3 P# x! E
    Pr(Down|Ctrl)  0.013888889
    % }' T! ~8 }8 ]/ \' x2 Q: S9 aPr(Up|Ctrl)    0.034722222
    5 }/ }) Y6 ]$ ^- ~) [: F$ n5 i2 J4 ]2 n
    Now in bootstrap..) Q, d4 {/ G0 c8 u' t% X
    0 N0 K8 n- J& @7 }2 v
    Point & Interval estimates:
    0 Z8 F: r& [4 J$ M' k$ }; ^                  Estimate   Std.Error        Lower       Upper
    - H* m/ T, u1 G  f3 o' |( {NRI            0.001893939 0.027816095 -0.053995513 0.0553544494 A+ y7 y2 r% x# H6 x6 h9 N: ~
    NRI+           0.022727273 0.021564394 -0.019801980 0.0657894744 @/ m" _! b) C: [" L
    NRI-          -0.020833333 0.017312438 -0.058823529 0.007518797
    5 {; N# U  n$ [: q% LPr(Up|Case)    0.034090909 0.019007629  0.000000000 0.072164948  Z0 |: B- }# S7 Y* j
    Pr(Down|Case)  0.011363636 0.010924271  0.000000000 0.039603960
    + T& e# i" p# i* c0 ?Pr(Down|Ctrl)  0.013888889 0.009334685  0.000000000 0.035211268
    ) d; F, c$ v- W0 i( h8 s; gPr(Up|Ctrl)    0.034722222 0.014716046  0.006993007 0.066176471# j5 S* G+ S* p; [
    , Y2 q* \8 q7 }$ @+ r6 g
    1
    : @7 Q* ^; U: C$ D首先是3个混淆矩阵,第一个是全体的,第2个是case(结局为1)组的,第3个是control(结局为2)组的,有了这3个矩阵,我们可以自己计算净重分类指数。
    . _) y; h6 [* A. {9 Z. q  J' a4 z& K% i
    看case组:9 W( b! b# m2 e! L* R

    , F% [# Q( U7 A# ^( L; a净重分类指数 = ((0+3)-(0+1)) / 88 ≈ 0.022727273
    ! c2 r/ z& i/ V: c8 k" E: [% J% V5 k) r
    再看control组:
    6 [  g3 T( a1 @, x2 ]# f( F# J( t0 |& u3 b3 p$ @
    净重分类指数 = ((1+1)-(4+1)) / 144 ≈ -0.020833333
    ) N9 J  a0 C( H/ D
    ' Q, \3 `2 |3 T: X8 ?) L! ]8 s相加净重分类指数 = case组净重分类指数 + control组净重分类指数 = 2/88 - 3/144 ≈ 0.000315657
    ' |! D- J% @" I* W6 ?* G
    7 `% I* ~! [8 I7 W6 S  X$ b* j再往下是不做bootstrap时得到的估计值,其中NRI就是绝对净重分类指数,NRI+是case组的净重分类指数,NRI-是control组的净重分类指数(和我们计算的一样哦),最后是做了500次bootstrap后得到的估计值,并且有标准误和可信区间。
    & f( s" S8 y- W5 k$ b; K# q8 h3 Q& f5 Q* f7 {; N  t, C
    最后还会得到一张图:) u' ]# V$ g( L6 ]' @9 f
    ! S6 Y$ r5 Q3 \5 e9 V5 v4 K8 w( z
    这张图中的虚线对应的坐标,就是我们在cut中设置的阈值,这张图对应的是上面结果中的第一个混淆矩阵,反应的是总体的情况,case是结果为1的组,也就是发生结局的组,control是结果为0的组,也就是未发生结局的组。
    * y4 s  D5 {7 W; i; r4 `; A2 J/ }' \
    P值没有直接给出,但是可以自己计算。* ]0 }. q! t- {
    2 _! b- b3 ]3 M/ g
    # 计算P值5 W% U! j1 h0 e* H1 S5 m1 j) V
    z <- abs(0.001893939/0.027816095)
    3 H: T, M% F1 V6 [$ }7 `8 l/ X3 k5 jp <- (1 - pnorm(z))*22 c+ N% P2 D3 b- i' v
    p$ _4 `3 I6 R8 Q" t; y
    1
    / ^' {; G# L# O% b$ Q: T## [1] 0.9457157
    & @8 E) x( {2 L& U( c- ?7 v1% W% I  g5 u1 [
    PredictABEL包1 y7 n* H, ~# {5 _$ Q
    #install.packages("PredictABEL") #安装R包
      `* L/ g5 y4 |4 Z* ^; S6 Glibrary(PredictABEL)  
    ) L( ^" e# Q6 v5 m' u
    " G% ?# j* K% G  c; i# 取出模型预测概率,这个包只能用预测概率计算
    ; S2 w" r# W5 |$ y( z+ h& d! ~) H* }! Mp.std = mstd$fitted.values
    1 N; r1 Z9 z/ H' `' zp.new = mnew$fitted.values
    8 b' \% V8 f% C/ l0 U$ p" g10 D; s7 l4 D( t2 M! g( y
    然后就是计算NRI:
    4 g0 \$ K# s- J% n5 C
    " v6 L. p- y# U4 ?4 Xdat$event <- event' i! T" d. a: A) f& G

    . q" e  X/ l/ N5 M& _3 Zreclassification(data = dat,
    8 ~1 `+ n: \9 V" }" z( Z# L                 cOutcome = 21, # 结果变量在哪一列
    ) ^3 c* n) t0 o                 predrisk1 = p.std,. i/ O, l% a& [2 @  L
                     predrisk2 = p.new,
      q  m8 w* q4 v7 o) U# G$ R. p8 d7 `                 cutoff = c(0,0.3,0.7,1)5 |' v0 ^( C9 O; v. I) @/ ^
                     )
    " @0 b) D+ p0 z) _# u% y1* a; W4 U) B: }: t$ X8 {+ ?; X- [
    ##  _________________________________________
    * _; P( _9 \5 J1 t  A( g* B8 e##  
    # _% ^. w4 Q9 W/ q, S' W9 B3 V! m7 ]##      Reclassification table   
    # `+ n: w2 S; f. P2 F& Q##  _________________________________________3 ^' l+ ^* O& @2 E
    ## : }& k  x1 a. M
    ##  Outcome: absent
    7 o* L; a5 K# L! ~$ y##   + V6 y3 V1 r3 V1 ?# J7 B* T
    ##              Updated Model
    $ _4 D. t4 w4 Y0 w& B0 y0 |## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
    % P4 H9 |4 R6 s9 U) W##     [0,0.3)       121         4       0               3) d1 Z( F, D( I5 G0 r
    ##     [0.3,0.7)       1        13       1              13: I' e, n, D. }6 Q
    ##     [0.7,1]         0         1       3              25
    ; k; w% b: x3 h* k: s5 h2 R## + W: v2 f# s# \: ~) |
    ##  + M. G" w. Y1 x1 \, N3 m7 q8 b4 ]
    ##  Outcome: present
    # H6 Z( ~: D2 d. b; q1 J" J##   4 J9 U0 t- q( U" ?8 u/ t8 E
    ##              Updated Model
    - T, h( q  b8 z# }) M9 e5 a## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
    . V7 v9 C2 V0 c6 u! t0 |+ ?$ S% w##     [0,0.3)        14         0       0               0" H5 _: P) U; t8 Z( F- K& b# t
    ##     [0.3,0.7)       0        18       3              14
    , H# x# M  R+ `& G( ?; r8 N5 C##     [0.7,1]         0         1      52               2
    ' T" k* M9 a% x) G##
    6 B% y7 X' I$ d" g8 Z##  
    * U* B" D7 \3 p( ^7 F) ?##  Combined Data
    0 [1 U5 b- k( Y5 \  }, X##   ( x) C  ]3 K! c5 x  b( x
    ##              Updated Model" p1 ^6 e+ A* d3 d0 g3 u
    ## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified2 p; I4 ]; ], [( ^
    ##     [0,0.3)       135         4       0               3
    ' h- P; \  w  T% a0 W##     [0.3,0.7)       1        31       4              143 f7 j% c5 x5 Y/ @
    ##     [0.7,1]         0         2      55               46 O  Z- o6 h) ?9 u1 M
    ##  _________________________________________
    0 D& S1 F) t8 C% r2 s2 A- ^##
    % o% [' r7 ^; o8 u6 g3 y##  NRI(Categorical) [95% CI]: 0.0019 [ -0.0551 - 0.0589 ] ; p-value: 0.94806
    & G% [3 o1 ]5 p& U( r& M2 _##  NRI(Continuous) [95% CI]: 0.0391 [ -0.2238 - 0.3021 ] ; p-value: 0.77048
    & Q( ?) W5 m8 ~6 e##  IDI [95% CI]: 0.0044 [ -0.0037 - 0.0126 ] ; p-value: 0.283969 {. o- \0 t6 I) ?
    1 f, {+ k$ N& P" m' t, R% m
    15 A) ~$ w* m/ O( f; L  e6 B
    结果得到的是相加净重分类指数,还给出了IDI和P值。两个包算是各有优劣吧,大家可以自由选择。
    & J  j. g  y/ G- p* a. \
    , n/ w9 l3 B$ }: K生存分析的NRI
    $ P5 s4 ^% X% W% p; ]/ o1 a3 \还是使用survival包中的pbc数据集用于演示,这次要构建cox回归模型,因此我们要使用time这一列了。
    # W% I- @3 C2 a5 P/ m- L6 f$ A  n' k* F* M& }, G* k
    nricens包% l0 C. L" t3 i6 `8 E
    library(nricens): y: `6 r/ t, j* d6 Y- {
    library(survival)
    ! D! ]0 T( t2 ^; k/ @- z% M2 z* T: V5 J
    dat <- pbc[1:312,]
    8 w1 e+ L( [9 D9 F0 w& E8 B  R4 edat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡
    5 W$ o7 S' U: [: v1/ [  L" {$ W- j0 a
    然后准备所需参数:, ]1 w/ ?6 ~9 h
    ! |) Y1 D7 {6 ?; R( }+ G9 f
    # 两个只由预测变量组成的矩阵
    $ e! j2 ?- r5 L6 xz.std = as.matrix(subset(dat, select = c(age, bili, albumin)))
    . {* W' w9 R! U1 ?z.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))
    ; t3 ~% v+ ^6 H3 q6 l% i. I
    & M) R% ^4 @. v+ c# 建立2个cox模型1 X4 c; Y  b* T6 t7 c+ r
    mstd <- coxph(Surv(time,status) ~ age + bili + albumin, data = dat, x=TRUE)
    ( V8 h: y0 N! U6 B: ~" ^  bmnew <- coxph(Surv(time,status) ~ age + bili + albumin + protime, data = dat, x=TRUE)0 n( }1 |6 s1 M) |2 D1 D9 ^+ U

    " J; |' {0 I- e& N' Q3 j1 Q# 计算在2000天的模型预测概率,这一步不要也行,看你使用哪些参数. V4 b+ b$ a0 ]2 A& C: ]' e* J
    p.std <- get.risk.coxph(mstd, t0=2000)# X. d4 O0 I7 @! `* n- ~% q
    p.new <- get.risk.coxph(mnew, t0=2000)+ ]1 ~' E2 B6 p6 ^( y& S% Y3 ~
    1
    2 d9 n1 I7 J3 w- g7 W9 Y计算NRI:. ?  `- E& T1 P5 n2 S1 ~" F

    9 |" i  @" |& v0 j4 o* x: `. Hnricens(mdl.std= mstd, mdl.new = mnew, # E7 ~, L+ \' a. w+ K. k1 C
            t0 = 2000,
    3 l5 R  U1 d0 U! ]7 B" O; S; ^        cut = c(0.3, 0.7),% z6 {/ Q, c9 _. ]" v: v
            niter = 1000,
    ; j" x& Y0 \/ c( I% t5 ^# {# i        updown = 'category')3 R- r% X. K, v9 l3 q1 Y9 u( y

    ' r0 y% |) a2 r! M1 r, I: C) F& wUP and DOWN calculation:
    ) t; C2 i* n# v1 N! F1 ^- \1 w  #of total, case, and control subjects at t0:  312 88 1446 l. G! [5 @4 v) F3 N6 \1 _, H

    , a" `7 c7 R; U$ ~  Reclassification Table for all subjects:
    8 W0 d$ n1 B1 J$ U        New
    7 |9 E4 }, _. R0 X7 c) |; G  p6 JStandard < 0.3 < 0.7 >= 0.74 O. l  T2 T# t* d
      < 0.3    202     7      0' [( X2 b& [2 d6 ^' J
      < 0.7     13    53      6: l) e  M4 d4 o" p- N/ J
      >= 0.7     0     0     314 Q- w  Y6 ^9 k
    $ W4 n; h5 m; @0 p# F( m
      Reclassification Table for case:8 [' ^" C' P9 y4 ^0 V7 p& w/ O# ~
            New: h8 `( d! D. n( N  q7 p
    Standard < 0.3 < 0.7 >= 0.7
    % Q  R+ {. ^' z  < 0.3     19     3      0' S- V5 q1 I' R
      < 0.7      3    32      4; v1 S9 b9 x1 ]8 Y5 {& y
      >= 0.7     0     0     27
    ) L* w+ _3 T2 k. @) E9 U0 j+ r' u2 \; p( a# n
      Reclassification Table for control:" |0 T8 g  c0 N! R
            New
    0 _9 ]) M1 }3 UStandard < 0.3 < 0.7 >= 0.7
    & ]- n/ \9 P& W  < 0.3    126     3      0
      \2 a5 b1 X) Y% g+ }$ ?4 Q  < 0.7      5     7      2
    ' _; \2 @" K$ }  >= 0.7     0     0      1
    6 X- C0 J- a2 y" f: M0 E' d
    2 q9 ]. _' j4 X5 jNRI estimation by KM estimator:
    6 c1 t& z" [5 U: r2 A5 Z9 `* h8 B! E; l; H, B
    Point estimates:
    & Q" v# q$ B  ^& Q                Estimate
    ( G" I! e6 C* _1 Z, K6 QNRI           0.05377635
    ( j8 W0 `/ a( rNRI+          0.03748660
    : {8 {9 |5 Y# M) t$ {1 ZNRI-          0.016289746 Y  z/ X9 y6 r; f' C
    Pr(Up|Case)   0.07708938$ u# N0 L8 }4 u  _( M! P7 {
    Pr(Down|Case) 0.03960278
    5 v+ S5 o, h! d5 APr(Down|Ctrl) 0.04256352
    7 s$ ~; D: h  c) n/ ?( cPr(Up|Ctrl)   0.02627378
    ( J, n8 J' P  |! n! f. b! z6 N' l; W) h8 ^$ t
    Now in bootstrap..
    3 Y( n/ i) v1 k! u" n2 r* D- P, L2 r3 ?
    Point & Interval estimates:/ T2 }6 J7 l0 h+ [/ G8 C; n) @  w* ?
                    Estimate        Lower      Upper
    % Z% H4 ?% B! I0 O/ |% q# fNRI           0.05377635 -0.082230381 0.16058172
    + y3 }0 H1 A# z! KNRI+          0.03748660 -0.084245197 0.13231776+ L# F- r: \& r  V. w
    NRI-          0.01628974 -0.030861213 0.06753616( U- t- f2 n, G% B5 h" |
    Pr(Up|Case)   0.07708938  0.000000000 0.19102291
    % {- H& j$ S' T! G1 j4 tPr(Down|Case) 0.03960278  0.000000000 0.15236016: N8 }# a5 r0 T5 S; V) r5 `
    Pr(Down|Ctrl) 0.04256352  0.004671535 0.09863170
    & x* H! U& y2 DPr(Up|Ctrl)   0.02627378  0.006400463 0.05998424" [' {7 t! f8 k- V$ U5 r7 c
      L) @3 m, R% u' w8 f9 S
    1
    . X$ s% g$ F+ u% @
    7 E$ n. R1 j$ \5 }  c  S' mSnipaste_2022-05-20_21-49-38* ?+ m) J; {* v% D+ U4 }
    结果的解读和logistic的一模一样。
    % ?0 z) `+ w% \( N( @
    7 ?) j5 ?" [0 H# [. ^survNRI包
    ' q: v. j+ F% X; }# 安装R包, Q3 T+ C0 a7 t/ ~0 Z8 z
    devtools::install_github("mdbrown/survNRI")
    $ c$ [: \4 ^3 Y7 [* V1
      `( }+ ]6 P0 B1 i加载R包并使用,还是用上面的pbc数据集。
    0 L$ d) b' Y$ a1 {$ O; J" d# d7 N6 o
    library(survNRI)6 t+ P1 S, V1 t* p6 t1 C# @$ g
    1
    ; h8 h1 Z- v: ^## Loading required package: MASS
    3 v7 J5 }, `# e) l6 w  ^1
    0 Y$ i! F* n( G3 ?, d4 plibrary(survival); \% r: u' f; ]

    - ]7 R2 o: ?( ], Z. B6 K2 _# 使用部分数据1 _- ~1 M: _) j" h( S. n
    dat <- pbc[1:312,]
    2 o! o. i9 x$ O, K$ G* w  wdat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡- {* ^: y2 e$ o: n
    , Q; u. ]+ l3 ?# q
    res <- survNRI(time  = "time", event = "status", 0 C7 D8 e  ]" r8 Q& s
            model1 = c("age", "bili", "albumin"), # 模型1的自变量
    + z2 y! g% p7 P) ]$ q+ H: ^        model2 = c("age", "bili", "albumin", "protime"), # 模型2的自变量7 t& x& ?* t* b) e( L$ c: Y
            data = dat, 2 w3 o; _2 Y( {
            predict.time = 2000, # 预测的时间点
    ) m! B1 ]0 }* G  J" O( F" O        method = "all",
    & F9 ^( `) d7 B* o6 {( ^        bootMethod = "normal",  ( ^  e4 U$ p% R/ v4 S" R6 D% A
            bootstraps = 500,
    " A# s8 d  t) G4 Z- x+ T        alpha = .05)! K  z* `+ ]1 }/ ?4 G
    ( y+ u/ m( J7 C. {
    1
    6 ~. A! M8 `2 I查看结果,$estimates给出了不同组的NRI以及总的NRI,包括了使用不同方法(KM/IPW/SmoothIPW/SEM/Combined)得到的结果;$CI给出了可信区间。. i6 P% A! x5 G3 `

    " E' y" a6 ~5 V& Z: C" W  i. m" Rres
    3 |# N0 O. h2 R# D8 {1
    & }/ r( c0 o, `) H6 n9 ]* J8 c## $estimates
    4 ^- R, R) i/ X+ A# ~##            NRI.event NRI.nonevent       NRI
    7 F0 k2 K' ?  m" N; P## KM        0.20445422    0.3187408 0.5231951/ G8 E0 X% h9 h0 U; L0 `$ P
    ## IPW       0.22424434    0.3273544 0.5515987
    * V( f2 h$ `% R7 a& D## SmoothIPW 0.19645006    0.3144263 0.5108763+ x# _6 G- A" D" H( v' @
    ## SEM       0.07478611    0.2632127 0.33799880 _0 c5 }. u4 p1 H4 W
    ## Combined  0.19633867    0.3143794 0.5107181, p# S' r2 p% W) @0 p3 d
    ##
    / p- i# N) P6 Z$ D9 m6 m7 ~## $CI
    ; r1 K/ ^0 E) X# {## $CI$NRI.event
    3 F5 E+ L% {# T( x  D9 G##                     KM         IPW   SmoothIPW        SEM   Combined
    ; g$ g) s" {( X9 u## lowerbound -0.03915924 -0.02185068 -0.04724202 -0.1162587 -0.0473723
    ! j8 M, @1 L1 q9 [& p# s  e! Y. F## upperbound  0.44806768  0.47033936  0.44014214  0.2658309  0.4400496
    8 t: [4 x# U9 x' c, G##
      ]6 b7 Q0 c4 M" C: x## $CI$NRI.nonevent+ K0 Q5 F6 h# [) @2 C; u
    ##                   KM       IPW SmoothIPW        SEM  Combined
    4 s" u2 |9 ^2 Y/ w' N% `0 ]## lowerbound 0.1317108 0.1396315 0.1286685 0.08638933 0.1286426/ x7 S; h& \" j) @6 B% x
    ## upperbound 0.7102251 0.7393216 0.6966341 0.51482212 0.6964549! i/ I/ [& w5 Z, i1 T7 G
    ##
    8 H% r; T) @5 B) ?- v* d4 m## $CI$NRI. Q5 @; C" g; g2 k7 H( E7 [' j
    ##                     KM         IPW   SmoothIPW         SEM    Combined
    ' b, {) s0 ~8 u4 A, f## lowerbound -0.05112533 -0.04569046 -0.05439863 -0.04132364 -0.05443409
    ) w7 W  U0 Y9 v& A. M## upperbound  0.89306122  0.92464359  0.87970125  0.64253510  0.87953153% Q' }8 f: U+ ~% U: u7 N
    ##
    % \0 J- n3 \% t: L7 C  q9 y: u+ P##
    1 J5 u2 m( z% V; d3 X## $bootMethod+ a* V# U/ H6 B: B. X7 \$ ^, P& A
    ## [1] "normal"
    0 C/ m' N! [6 j3 p+ i: l9 I## * F. n1 m7 F1 b% Y/ ]
    ## $predict.time7 r( }  {  b* Z" P: y
    ## [1] 2000
    ' n% s/ ]# A. _& @2 v## - o7 g+ U( q2 x0 m: Y1 w
    ## $alpha! w; o+ g. H7 J  G* `
    ## [1] 0.050 p7 J0 b% E4 O! u% l  p
    ## . e$ j# w/ E' v+ \) w$ |
    ## attr(,"class")( t" ^1 z- l) k* O2 r' W- E+ ^
    ## [1] "survNRI"$ z, @: Z2 ~! h5 s  I2 G9 B2 A' k# i

      Z+ I* t, L/ A- c1
    % W6 M5 ~7 s+ mOK,这就是NRI的计算,除此之外,随机森林、决策树、lasso回归、SVM等,这些模型,都是可以计算的NRI的,后面会继续介绍。大家如果有问题欢迎在评论区留言。, O, F  [! Z3 G0 l: x

    ) F; s% o$ E/ R本文首发于公众号:医学和生信笔记
      z2 v! [& E5 Y3 P: y
    " ]: [6 o2 ~' X! C“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。% P- m. J" u! J3 U" C
    本文由 mdnice 多平台发布
    & D7 p' i( n# a# Z* M————————————————
    # x+ F! G2 \8 |& T) ^( P版权声明:本文为CSDN博主「阿越就是我」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。: m3 v! R  i2 ?! V. m/ ]% K. ?
    原文链接:https://blog.csdn.net/Ayue0616/article/details/1267680067 v% X1 I: H8 E, Q6 o; J

    . M! v: T" Z" ?$ B) I. L7 T% q
    9 K2 W5 _0 a2 t, `0 B
    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:27 , Processed in 1.243201 second(s), 51 queries .

    回顶部