QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3027|回复: 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
    & i' a4 |! S3 `1 }: R- b
    净重新分类指数NRI的计算2 e% W4 c1 M' y2 e' Q
    “ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。
    0 O; |: k+ g1 n- XNRI,net reclassification index,净重新分类指数,是用来比较模型准确度的,这个概念有点难理解,但是非常重要,在临床研究中非常常见,是评价模型的一大利器!: Q- e2 q, y1 h6 w
    $ A( t4 a6 d" _# O1 o2 x0 a! V
    在R语言中有很多包可以计算NRI,但是能同时计算logistic回归和cox回归的只有nricens包,PredictABEL可以计算logistic模型的净重分类指数,survNRI可以计算cox模型的净重分类指数。# C3 L8 }! n8 i0 p" p

    9 D! y0 e7 f& S: E1 |logistic的NRI% a7 a1 a# f! Q
    nricens包& s- \$ Z/ }4 N$ Y, K) _! T% Z% o: A
    PredictABEL包
    2 e2 `% E( H* h: l* F; E( ^生存分析的NRI2 Y! M) H7 u& q4 z- Z$ W) p% l7 p0 a
    nricens包
    8 N1 [2 N6 {, b- ?! X; ~survNRI包/ L6 v3 x# Q  z
    logistic的NRI+ `# W) M0 ~. ?- i! ?& l
    nricens包. B5 V- c( j  I" o" ~' X
    #install.packages("nricens") # 安装R包1 D  i6 f; ?: L9 O) S7 a
    library(nricens)9 F* O, I, ?6 q2 W
    1% i4 Z9 I( \/ t% \
    ## Loading required package: survival% P) p) x$ y0 x7 A
    1% t2 {" l' B: Q5 t8 ?+ c& L9 Z
    使用survival包中的pbc数据集用于演示,这是一份关于原发性硬化性胆管炎的数据,其实是一份用于生存分析的数据,是有时间变量的,但是这里我们用于演示logistic回归,只要不使用time这一列就可以了。
    6 p- v" Q5 N$ i7 F/ d8 T' G$ b0 o6 y( F0 {/ I: Q, ^
    library(survival): M- A5 j2 o; q' `% K# u
    * G( a5 B: N6 q! J6 V- b
    # 只使用部分数据
    8 F" E$ v4 J  \# O9 hdat = pbc[1:312,] $ u* Y& f1 `$ y) U: E  E! `( ], B
    dat = dat[ dat$time > 2000 | (dat$time < 2000 & dat$status == 2), ]7 F7 w8 Q# P* n* U8 i% T

    8 {( x; M7 ?$ I% M, \9 u: Pstr(dat) # 数据长这样
    ( g$ J) `: y5 g' _% \- g7 S1
    $ v' o9 ^+ {& o8 }' t% }( S; e## 'data.frame': 232 obs. of  20 variables:  @7 V' @! N* M+ F+ C9 p6 L
    ##  $ id      : int  1 2 3 4 6 8 9 10 11 12 ...
    # f% D2 C1 n+ u) m( ^##  $ time    : int  400 4500 1012 1925 2503 2466 2400 51 3762 304 ...
    & X# _6 T6 @8 e6 N; v5 ^! C. b##  $ status  : int  2 0 2 2 2 2 2 2 2 2 ..." x7 G* P) ^7 P, t3 n; M0 |- Y
    ##  $ trt     : int  1 1 1 1 2 2 1 2 2 2 ...6 n/ x: X% E+ g% W' ^* k+ M  I
    ##  $ age     : num  58.8 56.4 70.1 54.7 66.3 ...  a# n- [2 t3 z/ q$ Y8 d4 U
    ##  $ sex     : Factor w/ 2 levels "m","f": 2 2 1 2 2 2 2 2 2 2 ...
    ; s  x. g& z0 n: F##  $ ascites : int  1 0 0 0 0 0 0 1 0 0 ...
    5 w4 T, \; V' ^5 w9 H  w4 X1 ^1 {##  $ hepato  : int  1 1 0 1 1 0 0 0 1 0 ...
    " w+ F0 J1 o0 e9 S' n0 E##  $ spiders : int  1 1 0 1 0 0 1 1 1 1 ...3 |  M( b! [9 b8 d; ?0 ]9 T) B
    ##  $ edema   : num  1 0 0.5 0.5 0 0 0 1 0 0 ...
    : s: d) h+ ^" r0 J/ c8 ^# H6 X##  $ bili    : num  14.5 1.1 1.4 1.8 0.8 0.3 3.2 12.6 1.4 3.6 ...* F. Z- s( _. Z2 L0 K" |
    ##  $ chol    : int  261 302 176 244 248 280 562 200 259 236 ...) \4 J) e1 v, t/ A1 Y
    ##  $ albumin : num  2.6 4.14 3.48 2.54 3.98 4 3.08 2.74 4.16 3.52 ...
    ) i" t( ~! z& l( h7 W##  $ copper  : int  156 54 210 64 50 52 79 140 46 94 ...7 i  N8 w7 w' p& _5 w1 s
    ##  $ alk.phos: num  1718 7395 516 6122 944 ...
    5 O# u# m& M- P##  $ ast     : num  137.9 113.5 96.1 60.6 93 ...
    : i: E* k& Q8 V. z) W##  $ trig    : int  172 88 55 92 63 189 88 143 79 95 .... |. ^' ^4 s& o3 B+ a; n
    ##  $ platelet: int  190 221 151 183 NA 373 251 302 258 71 .... Z9 @) \. y$ A
    ##  $ protime : num  12.2 10.6 12 10.3 11 11 11 11.5 12 13.6 .... @+ y8 E9 s  W9 W4 c1 k0 J
    ##  $ stage   : int  4 3 4 4 3 3 2 4 4 4 ...
    5 d% Z, q& {4 `; L7 |4 L8 H7 s2 v6 d/ S* v  R) T
    1) j, ~* ?% J7 Y6 S" J- |
    dim(dat) # 232 20
    6 J3 H5 f* p: o; |" N, G1& ~" p" N, p& ?" W
    ## [1] 232  205 ^& e! z0 x' d( f0 K( o
    1
    & D' P1 V: D/ U8 P" |/ i然后就是准备计算NRI所需要的各个参数。7 _; q8 d) O* o! O4 V

    " D. s6 `: ]2 R# 定义结局事件,0是存活,1是死亡$ d; W( Y% H3 h. p1 Y
    event = ifelse(dat$time < 2000 & dat$status == 2, 1, 0)
    0 u( z: T/ K4 K8 C
    ) I- G8 D1 @3 o& l7 t0 F* u# E; @# 两个只由预测变量组成的矩阵' a7 \1 J7 k& F. G: V" u, p' S1 z  `
    z.std = as.matrix(subset(dat, select = c(age, bili, albumin)))
    / z1 M7 w; ^+ X6 K* S3 z1 d! _z.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))
    5 R3 s- ]2 |/ ]" O
    $ Q3 V7 P1 e0 _) A4 \1 o  X# 建立2个模型& d9 D* h; h' t. }1 y( }6 p5 u
    mstd = glm(event ~ age + bili + albumin, family = binomial(), data = dat, x=TRUE)# l3 ?# i  ~9 B8 A7 Z* F
    mnew = glm(event ~ age + bili + albumin + protime, family = binomial(), data = dat, x=TRUE)' {5 U0 M* S) ~
    " i% A( a6 V- h% l: @
    # 取出模型预测概率) ]! w- r* F4 m) y1 d
    p.std = mstd$fitted.values# {" }9 H+ x) J1 W5 a) q& W
    p.new = mnew$fitted.values
    ; a. D; W& E- q# y8 @; Y9 y3 s6 c* k0 `# Q6 o
    1
    , o/ w8 ?8 {) v$ w: M然后就是计算NRI,对于二分类变量,使用nribin()函数,这个函数提供了3种参数使用组合,任选一种都可以计算出来(结果一样),以下3组参数任选1组即可。 mdl.std, mdl.new 或者 event, z.std, z.new 或者 event, p.std, p.new。, o/ z: v# ^. G' B

    ( s( u6 o3 G; z2 k( M- r7 r. Z* x# 这3种方法算出来都是一样的结果6 E9 S$ D$ W3 Z- H

    $ H3 K& {% L. A( _  V( B3 \# 两个模型
    7 T2 M6 T/ d7 d5 P; _nribin(mdl.std = mstd, mdl.new = mnew, ( A5 a; L- J- v5 w
           cut = c(0.3,0.7),
    / |  ]/ d: j# L0 A7 t) _0 Y* b7 l       niter = 500,
    ; {: ?$ K5 @; z* J       updown = 'category')( [: l1 y% M  c" Q! [
      H; }- y" i, O1 Y
    # 结果变量 + 两个只有预测变量的矩阵3 o  y$ G; B+ e2 ]) r; n
    nribin(event = event, z.std = z.std, z.new = z.new,
    ; E! @; w9 d: A3 \$ e0 \, Z9 I1 C       cut = c(0.3,0.7),
    6 Z7 L- q" d' w& j       niter = 500,
    ) @# R1 }+ j  Q( w3 c       updown = 'category')
    & ~6 A$ W" U) P1 l, M6 K" u
    / h4 Q1 f; Q* j+ ?! J4 G2 @## 结果变量 + 两个模型得到的预测概率$ T4 N" ~! _' J3 D
    nribin(event = event, p.std = p.std, p.new = p.new,
    : Q  n) f& `6 b       cut = c(0.3,0.7), : Z) w' |* |. b; o+ z& v
           niter = 500,
    , f, Y0 T# P) v# O       updown = 'category')
    # ]& l$ v: N3 t' N0 N- P+ ~2 n) Q+ r  ~- k
    1
    5 J% b1 _" b# a: S其中,cut是判断风险高低的阈值,我们使用了0.3,0.7,代表0-0.3是低风险,0.3-0.7是中风险,0.7-1是高风险,这个阈值是自己设置的,大家根据经验或者文献设置即可。4 j$ D  u2 Y& j

    , p7 J, \* e; ^+ Q* E  Jniter是使用bootstrap法进行重抽样的次数,默认是1000,大家可以自己设置。# |* k7 [' _0 s3 u4 b1 x0 k
    . s6 Z; D6 o4 S- ~" K
    updown参数,当设置为category时,表示低、中、高风险这种方式;当设置为diff时,此时cut的取值只能设置1个,比如设置0.2,即表示当新模型预测的风险和旧模型相差20%时,认为是重新分类。
    $ r+ p2 _4 W" g1 ?! A- D! |  G: N- a5 L: F& W8 X
    上面的代码运行后结果是这样的:8 V( W. v/ `) s* [( e& I) M/ {
    / {* P; T* i$ t# t$ \' i5 H- t
    UP and DOWN calculation:$ w# u/ P# x4 y) d- h/ T
      #of total, case, and control subjects at t0:  232 88 144
    ) Q# b7 K3 t- N8 e, |0 ~1 S6 G' c2 v5 k& s" H: V( {
      Reclassification Table for all subjects:
    . y( `7 S% O; O4 o/ }, u        New
    ! ?+ X) M9 O$ F2 e- c8 A$ uStandard < 0.3 < 0.7 >= 0.7
    $ A- y# d2 s( P. b# g$ _; E  < 0.3    135     4      0! p2 q; F6 B/ L
      < 0.7      1    31      4
    ' [; T0 m9 N# {3 W, C5 ?8 E; E' p  >= 0.7     0     2     55
    , J! u2 D3 T2 v2 g# W: j4 a
    * {: a3 H; w; y6 a' h  Reclassification Table for case:
    & g; y1 v0 U( q  F) ]% I& e5 t        New
    1 I+ q) q* |: v1 M4 rStandard < 0.3 < 0.7 >= 0.7! Y1 D' _* l+ g) K
      < 0.3     14     0      0
      T8 L* W+ Q! N9 w  < 0.7      0    18      3
    9 X. P  G, y& L8 U, s+ S8 g; E  >= 0.7     0     1     52' N# Z8 m1 I- B: Q/ S( \
    5 x4 b3 J7 h. A8 U7 l
      Reclassification Table for control:  J: j; k1 G( f& p( g
            New3 }0 l5 Q2 J* w1 k  ]
    Standard < 0.3 < 0.7 >= 0.7. k" f% y8 {1 C( I# M& ?# v
      < 0.3    121     4      0
    7 P6 @, k+ K; }! [8 K) A" ^3 k+ O  < 0.7      1    13      1
    - R( `+ g! F: D+ i4 b  >= 0.7     0     1      3( `' d( [! v. w
    + V& D& W0 U+ f" x) T- ?
    NRI estimation:& J  K3 x/ P+ [+ M  L4 u5 R6 c8 @
    Point estimates:
    $ U# j. {5 G7 c* ?                  Estimate
    4 j' q. U, I% c! s) f0 g% FNRI            0.001893939# s# E$ J4 h, a- U  y) R% Y$ y
    NRI+           0.0227272736 t; q' j- l( w2 A# S
    NRI-          -0.020833333
    2 h* H4 {2 h7 f6 p, EPr(Up|Case)    0.034090909
    . r7 n. X0 ?4 DPr(Down|Case)  0.011363636/ _8 ?2 I4 ?/ R
    Pr(Down|Ctrl)  0.013888889
    * S$ ]4 L2 I! Q7 BPr(Up|Ctrl)    0.034722222' d8 o/ R% ~9 z7 e3 c' J

    # {  _1 `( N8 g. R9 D- JNow in bootstrap..
      D+ i: ^, z4 D; ^& E1 b# g+ L' K8 ?* }
    Point & Interval estimates:
    5 a+ V1 h) C& x2 j7 t# c  j/ ]                  Estimate   Std.Error        Lower       Upper9 _- P9 \: a+ g; q7 g
    NRI            0.001893939 0.027816095 -0.053995513 0.055354449
    $ z# x4 H) F' N5 z: \7 h  O0 V; LNRI+           0.022727273 0.021564394 -0.019801980 0.065789474
    3 k6 U) P5 q9 B$ z' T* \, ^$ PNRI-          -0.020833333 0.017312438 -0.058823529 0.007518797
    ' h% n7 t2 r; H% q% a5 }2 iPr(Up|Case)    0.034090909 0.019007629  0.000000000 0.072164948
    ) U+ \0 p% A3 {8 I& FPr(Down|Case)  0.011363636 0.010924271  0.000000000 0.039603960
    ) @* \. R$ u' j  Y( u! }6 zPr(Down|Ctrl)  0.013888889 0.009334685  0.000000000 0.0352112687 j8 ^, c) O8 A- G1 u/ ?
    Pr(Up|Ctrl)    0.034722222 0.014716046  0.006993007 0.066176471
    , C+ l: P6 Z3 x6 u, Z* e
    % K5 H* \* Z; y; @: T  _- \1
    2 V3 X( {2 M- G* f$ ~( Y9 E首先是3个混淆矩阵,第一个是全体的,第2个是case(结局为1)组的,第3个是control(结局为2)组的,有了这3个矩阵,我们可以自己计算净重分类指数。
    6 y5 L) L  t- C' W/ i9 k- ~3 G/ R
    看case组:
    . \# o; o+ l3 T* w9 O6 g# G0 |8 g% J5 p
    净重分类指数 = ((0+3)-(0+1)) / 88 ≈ 0.022727273
    - N. k$ F- J. \. P+ N9 n6 f) X! c4 B+ d3 [) H# P
    再看control组:8 {5 A+ f: I' L* v2 u5 [0 A

    9 z) W0 \' K' `8 p+ l: q. F9 j5 S# W6 I8 g净重分类指数 = ((1+1)-(4+1)) / 144 ≈ -0.020833333
    2 r6 D: E7 k* N# U! P# [. b# j8 _0 S( r* N7 t
    相加净重分类指数 = case组净重分类指数 + control组净重分类指数 = 2/88 - 3/144 ≈ 0.000315657# V- u1 R6 l& x- g* |7 u: Y
    . Z/ d2 t. F6 r# ^
    再往下是不做bootstrap时得到的估计值,其中NRI就是绝对净重分类指数,NRI+是case组的净重分类指数,NRI-是control组的净重分类指数(和我们计算的一样哦),最后是做了500次bootstrap后得到的估计值,并且有标准误和可信区间。# ~) b8 P/ y& |6 ^' f/ ?9 A  g
    9 _; ?9 @  e9 w( h
    最后还会得到一张图:
    9 I- {8 A8 N: i; t# u  ^8 x
    ' x5 O; x, f; }这张图中的虚线对应的坐标,就是我们在cut中设置的阈值,这张图对应的是上面结果中的第一个混淆矩阵,反应的是总体的情况,case是结果为1的组,也就是发生结局的组,control是结果为0的组,也就是未发生结局的组。1 s8 P! Q) T1 n+ _
    0 `- v" X% {5 L1 z
    P值没有直接给出,但是可以自己计算。
    ' p- b2 [/ ~8 n2 ?
      d  R; Q  u& J& C/ Q# 计算P值
    ( M3 z5 H4 u' m6 E8 N2 I* i/ `z <- abs(0.001893939/0.027816095)
    8 H) l+ n4 }7 h  ], [& R$ Lp <- (1 - pnorm(z))*23 i; K4 y/ b) j+ M
    p" s2 T3 Q! ~$ M3 s. r% ~! x5 L$ j9 G
    1
    2 I4 C! J! O, J8 u2 e## [1] 0.9457157
    4 E1 p( q- i7 S3 D) q1, [* p9 j: ~/ W9 b, @
    PredictABEL包2 w9 y& x4 a9 D" e2 X0 B
    #install.packages("PredictABEL") #安装R包
    2 b4 {' A* E0 y: d  S# M& jlibrary(PredictABEL)  
    # @% Z2 h3 |- }/ M
    4 v- w" i- w- b6 _, Y: U$ \# 取出模型预测概率,这个包只能用预测概率计算% h1 p# A* Z. y
    p.std = mstd$fitted.values# j2 R) ]  n; O5 f6 F/ Z
    p.new = mnew$fitted.values
    . `* }: |: R1 z) N- X, c1
    3 r3 Q, H& _* M* P然后就是计算NRI:
    % z4 r, Y( v) l) t5 u
    ( e0 I5 k8 r! A1 n! G3 odat$event <- event
    0 x. Y' n0 s8 P3 L( X6 M9 S9 n. Y4 m9 t; h
    reclassification(data = dat,
    7 u& {  S* ?, a) z4 ~8 i                 cOutcome = 21, # 结果变量在哪一列
    9 l5 k; V3 B& b+ [" T. A' l                 predrisk1 = p.std,7 D2 F5 h9 l& `* _9 T" ?
                     predrisk2 = p.new,
    ( A* X# p! A1 `7 p) u: O5 J5 Y                 cutoff = c(0,0.3,0.7,1)! C! [3 y) F: k6 {* i2 \* C
                     )9 ~: n+ b- e1 [* o" q: }, ~
    1/ }' L; [2 R+ H
    ##  _________________________________________8 C  K6 M# _# \0 p; n4 J# O3 G3 z
    ##  # z9 E* p# R$ [' m8 q: Q
    ##      Reclassification table    $ K4 t7 U5 z, Q8 s* ~" I' d7 G) d2 Z
    ##  _________________________________________
    5 u# s* T5 l' o6 _3 A; }3 q0 h/ n##
    : r0 N1 D3 t! X: n+ l7 ^2 I7 J& E4 g##  Outcome: absent / A/ X2 U( Y  G  [
    ##   
    3 m0 h) A" [& z2 ^- a# ^##              Updated Model
    : }. |. g; n' M/ [## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
    ) ~6 m! I6 h. W7 k##     [0,0.3)       121         4       0               3
    $ r" ~! U5 |# E##     [0.3,0.7)       1        13       1              13
    ) X0 x/ h) t' `  _7 j+ @$ C' u##     [0.7,1]         0         1       3              25
    4 [' q: w' ]# z. _1 E" Y: ]: q: i##
    ; t% h) t( \7 U##  
    4 H( {" g! o' h( H/ n! E##  Outcome: present - r  k% k9 n" l" X) N
    ##   
    ! `, n, v7 \* u! m% k3 u# _$ k##              Updated Model3 J! E7 ^" F- s
    ## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified+ p9 z" d9 j- h6 A/ ~  I! D, Z
    ##     [0,0.3)        14         0       0               0
    2 n$ Y  l9 m! c5 F6 U! V##     [0.3,0.7)       0        18       3              14
    ( b, a+ R/ U. U. Y# j3 l! t6 c##     [0.7,1]         0         1      52               2  l; N9 G% D& Z' r9 R  \/ E
    ## 4 I* P! L4 |  [0 N  L, ?
    ##  # O% C  j2 f/ U: ]) }5 _
    ##  Combined Data 5 r. m9 _3 n3 \: t
    ##   : e8 U! _8 c+ t; p) j8 ^7 @
    ##              Updated Model$ G0 F3 S  ?% p. x) Y
    ## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
    9 u2 J, Q* D1 A! I* |% b/ J& y) W6 D##     [0,0.3)       135         4       0               38 n# s. Q8 T8 C; s
    ##     [0.3,0.7)       1        31       4              14
    3 F/ e! t) s5 x- P: _##     [0.7,1]         0         2      55               4
    0 t. A" ^5 z; }$ |; g% |! x##  _________________________________________
    ) U& Q" U- O4 j##
    . O0 F7 j! e/ m# Y* |##  NRI(Categorical) [95% CI]: 0.0019 [ -0.0551 - 0.0589 ] ; p-value: 0.94806 , R0 H9 ?5 c0 V. M
    ##  NRI(Continuous) [95% CI]: 0.0391 [ -0.2238 - 0.3021 ] ; p-value: 0.77048 2 \7 ?6 y' F; A2 X( C
    ##  IDI [95% CI]: 0.0044 [ -0.0037 - 0.0126 ] ; p-value: 0.28396
    # \/ p$ U2 p; D( a5 q' H( s  x4 Z1 C4 Y
    18 Y, F: `! I( _. [* _7 R
    结果得到的是相加净重分类指数,还给出了IDI和P值。两个包算是各有优劣吧,大家可以自由选择。! o: r/ V# i  g+ R0 @) f

    ' H' q+ w9 b* E8 H生存分析的NRI4 V7 \5 X) ]: r; m' d; K" k
    还是使用survival包中的pbc数据集用于演示,这次要构建cox回归模型,因此我们要使用time这一列了。
    4 n, K5 w! j5 R, t+ y% S
      w6 M8 J) R. K/ t5 U/ Xnricens包
    # i8 I. t, i0 j' ^, W' u- R; mlibrary(nricens)
    . n1 w3 L2 y4 dlibrary(survival)
    / |9 T- x- L% t0 P, F
    : Y3 {& d* A3 T5 S7 h( M; Ndat <- pbc[1:312,]
    0 c( K5 ]' \3 [dat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡
    5 T$ `2 S4 N  b$ b/ ]1- r6 m, ?9 F' B" S: h2 }# Q0 U" M
    然后准备所需参数:; T, C0 M% _' K. ~$ j' D

    4 |% D( _. ^+ ^: O- d# 两个只由预测变量组成的矩阵7 Q( A' q3 {- J1 R9 i
    z.std = as.matrix(subset(dat, select = c(age, bili, albumin)))5 }( @* `: ~" t
    z.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))
    , V# D6 V: Z4 G$ g5 Q0 G0 H0 G# X* N5 J! J( i7 v0 O  v" G
    # 建立2个cox模型
    7 _  s! @% W# L+ pmstd <- coxph(Surv(time,status) ~ age + bili + albumin, data = dat, x=TRUE)' t, P$ R- q, R  U: c
    mnew <- coxph(Surv(time,status) ~ age + bili + albumin + protime, data = dat, x=TRUE)6 K1 z- i5 Y: o0 i9 \! j
    ; ]" X: g2 I# K$ o; ?+ e
    # 计算在2000天的模型预测概率,这一步不要也行,看你使用哪些参数' @- k( J6 T& P+ \
    p.std <- get.risk.coxph(mstd, t0=2000)
    2 j% m& g2 @. M$ np.new <- get.risk.coxph(mnew, t0=2000)
    0 y0 a" x# m$ r8 }/ `1; d+ O% @3 t# b0 V4 H# b2 q
    计算NRI:5 O; \! a+ u# H( y- `5 V' M
    9 G' p. D9 q% G9 h2 C0 ~
    nricens(mdl.std= mstd, mdl.new = mnew,
      m4 J, Q2 U  o8 l  H8 E% m        t0 = 2000,
    9 U& {3 G0 B" ]% c        cut = c(0.3, 0.7),
    " }- @. o4 \: B        niter = 1000,
    * N4 \0 C' e* F        updown = 'category')! V: U; @' X: m6 ]
      C' v1 L* A8 t* b$ N8 g3 c: s
    UP and DOWN calculation:. k5 X4 L2 d' g$ Q5 e
      #of total, case, and control subjects at t0:  312 88 144- e8 ^1 x. Z" T7 }! h
    3 V* O/ `1 U: L8 P
      Reclassification Table for all subjects:: U) [( A$ U" V1 @( u! D' H6 s' Q) I
            New
    1 t( k) ~# {2 G$ Y" {. \$ ]' A* X! bStandard < 0.3 < 0.7 >= 0.7
    + |4 u5 M$ i3 ?' X  < 0.3    202     7      0
    + C- I4 @9 h2 I) t  F- B  < 0.7     13    53      6
    7 g9 D* j5 M. Y5 X( }  >= 0.7     0     0     31+ z' F7 g  h, N
    5 I2 n: f# X: f" i% E
      Reclassification Table for case:
    + {+ l- @* @1 r# S1 K9 ?9 S! H        New& P& G2 a" q% h4 B
    Standard < 0.3 < 0.7 >= 0.7
    + J( b8 W7 w7 ]) a  < 0.3     19     3      0/ C( R1 B' b& C3 n5 a% Z. ?, E; I3 |
      < 0.7      3    32      49 g0 b1 ?0 t6 Y- y3 F9 M& }# N
      >= 0.7     0     0     274 O/ Y6 i9 K$ g9 A2 t
    3 \( j9 z/ x$ b. H/ q
      Reclassification Table for control:* o$ j! b/ \, f4 A2 |& O8 h' _
            New# ^' j+ l  c8 D: k
    Standard < 0.3 < 0.7 >= 0.7. z$ \5 }+ Z2 ?3 ?
      < 0.3    126     3      0, |9 V6 x9 N3 y9 p
      < 0.7      5     7      2
    - [& J5 G  @+ i# B$ ?% m4 N  >= 0.7     0     0      1+ }+ \) |! ]  ]

    " W: b0 @; G" M, Y, VNRI estimation by KM estimator:. i* H. m& ^3 d9 ]& U( ^- h% ^
    6 X/ m, [9 ?% T; r4 h
    Point estimates:
    $ c3 R+ l$ o" ?; W                Estimate
    - \- H' A; y* x3 g% ]+ I- nNRI           0.05377635% U7 ?3 |5 u' M7 d% k& N9 {
    NRI+          0.03748660' e2 `" x( g& M
    NRI-          0.01628974# ]9 o4 ^; ^# _4 C! l
    Pr(Up|Case)   0.07708938
    : s+ w0 w# b% ^) Y6 r& XPr(Down|Case) 0.03960278
    - `3 F  p" }% vPr(Down|Ctrl) 0.04256352
    $ y2 ~. @9 ]/ D0 kPr(Up|Ctrl)   0.02627378# b  v  K8 Q! F# ~- I& w
    ! L  I& \! y: ?
    Now in bootstrap..
    : r6 l% u3 U3 f* a. G$ ]
    - M/ p+ b  k# R) W& N3 ^4 WPoint & Interval estimates:
    4 t: D% r3 i2 }; }4 M. u                Estimate        Lower      Upper
    + K& @2 x+ q# D: BNRI           0.05377635 -0.082230381 0.160581724 |+ N1 Y3 \; r: a3 v( c$ T2 l
    NRI+          0.03748660 -0.084245197 0.13231776( h7 n  C4 q$ C: l" p
    NRI-          0.01628974 -0.030861213 0.067536162 R6 D; Y9 v6 W' O. r* w* u3 A
    Pr(Up|Case)   0.07708938  0.000000000 0.191022917 U7 |8 g8 q- B/ _8 v9 ~9 G- h
    Pr(Down|Case) 0.03960278  0.000000000 0.15236016
    1 U& w; m  y, i9 |Pr(Down|Ctrl) 0.04256352  0.004671535 0.09863170
    6 X3 n6 X5 d1 B$ N7 K4 C1 \Pr(Up|Ctrl)   0.02627378  0.006400463 0.05998424* ^$ [5 \6 P5 ]1 f7 g+ m
    1 t* a7 a+ h$ d/ P7 v6 V+ ?
    12 _6 h2 X1 W3 R8 R$ f
    0 Q1 q- p7 t" [" H% ~: [
    Snipaste_2022-05-20_21-49-38' U1 S3 W& |/ t2 I. f% v8 W
    结果的解读和logistic的一模一样。
    * g) W# L7 |9 z
    $ m$ l+ l# R) a5 IsurvNRI包1 B' Q  ?" a/ E9 Q, B* l
    # 安装R包2 N, d" B; E, C/ ^" r
    devtools::install_github("mdbrown/survNRI")! n1 p/ c: L+ @# I  `
    19 O$ h1 J/ T% v- V
    加载R包并使用,还是用上面的pbc数据集。+ U3 ^9 t) _8 O

      _# Q, c' D) A! q7 p2 X! |( ulibrary(survNRI)
    + U% W, f) a1 r, Q4 n1( f2 K; d' X8 X( k  `1 Y- t
    ## Loading required package: MASS# L6 `/ D* ~5 T$ L* U
    1
    ' a2 g  j0 Q$ v- i& a! ?library(survival)
    0 K7 |, n& P' h5 z* e! ~5 A
    1 O, G. L  ?" }. {' r  l# 使用部分数据
    $ `/ i% @6 ~# L9 q# O; p5 fdat <- pbc[1:312,]# p3 T# F% t3 c2 w
    dat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡
    ' E1 g: e5 m- X" J0 B: x8 I
    . _, I7 m8 k- M- ?, n* d/ G( g) ores <- survNRI(time  = "time", event = "status",
    1 W) w# T: u( E. o3 O. k- d        model1 = c("age", "bili", "albumin"), # 模型1的自变量  k# C+ T. q8 F0 N8 a7 ^: E
            model2 = c("age", "bili", "albumin", "protime"), # 模型2的自变量
    * \& n5 `0 [( p0 m) [% r' W7 S        data = dat,
    2 J6 \( V4 s5 C0 _: w5 V0 R$ u( g        predict.time = 2000, # 预测的时间点
    ' g8 ?+ x- p2 M1 S" T3 R, g        method = "all", * H. b9 r& [, X6 U9 ^
            bootMethod = "normal",  ) \  T  f' o: \
            bootstraps = 500, / {% r7 I: _6 |
            alpha = .05)
    $ w. K3 l4 o( D. K8 I( y8 A% z) Y
    . X+ Y' R8 d: k! {: u+ l1  f+ {' U2 x; K( I1 p. a  f
    查看结果,$estimates给出了不同组的NRI以及总的NRI,包括了使用不同方法(KM/IPW/SmoothIPW/SEM/Combined)得到的结果;$CI给出了可信区间。& k4 y  z) F. `" Y" h) f+ ?
    ( B4 Z; L( y  b0 X" [7 x
    res
    ' u- L, C  |9 V" c- i0 W1
    ( _  E& g: a: V4 Q8 a$ h9 E; p## $estimates
    4 K, n6 O, K+ V% U3 J4 t* K##            NRI.event NRI.nonevent       NRI
    ( {6 Q* O' ^: D4 \8 |; `/ P9 P## KM        0.20445422    0.3187408 0.5231951
    , I: r, a" N2 i0 C% b. y( Q7 ]## IPW       0.22424434    0.3273544 0.55159872 J5 P6 o6 z1 y% v9 a  K: c# `" }. f
    ## SmoothIPW 0.19645006    0.3144263 0.5108763: F; v3 k( z% z' B# v
    ## SEM       0.07478611    0.2632127 0.3379988
    + Y7 `) E  e5 |9 x% E, H## Combined  0.19633867    0.3143794 0.51071817 K& G/ u' J4 f, z9 Q1 K" g
    ##
    ; G( s& a, i9 o. V  ?## $CI
    # u% _; J# k- l- @) k+ k2 x## $CI$NRI.event/ _3 A: B6 g) y8 j2 K6 b
    ##                     KM         IPW   SmoothIPW        SEM   Combined* q/ q9 R9 X4 ]/ c9 k
    ## lowerbound -0.03915924 -0.02185068 -0.04724202 -0.1162587 -0.04737235 u0 j* I2 I- x. x5 h$ l5 n
    ## upperbound  0.44806768  0.47033936  0.44014214  0.2658309  0.44004965 S* Y( v7 {5 }1 ]
    ##
    9 b* {9 H* k9 O+ @( s+ a9 F4 H1 K## $CI$NRI.nonevent
    ! R+ [9 {% ?9 _9 l* B6 E##                   KM       IPW SmoothIPW        SEM  Combined5 X0 e% x) ~5 U2 S( M
    ## lowerbound 0.1317108 0.1396315 0.1286685 0.08638933 0.1286426
      W0 m# R8 a. Z7 u- [/ w  R## upperbound 0.7102251 0.7393216 0.6966341 0.51482212 0.6964549
    : U- m( W1 U- I) F( k## & Q0 U; V  Q! \+ E! b5 E/ @
    ## $CI$NRI  d' _- r$ g/ J
    ##                     KM         IPW   SmoothIPW         SEM    Combined
    # O( g! A( s: a/ {0 o1 {( D( v## lowerbound -0.05112533 -0.04569046 -0.05439863 -0.04132364 -0.054434095 n& B+ f/ e4 ]* a2 P
    ## upperbound  0.89306122  0.92464359  0.87970125  0.64253510  0.87953153
    & e1 N% j7 o$ A7 Z6 a- N  J1 V$ I## $ l; H& s* r% M1 E
    ## 4 y" r' I% X6 i% Z/ B6 h8 |
    ## $bootMethod
    ) j% C7 p& [3 e1 c+ |, T) z9 B## [1] "normal"
    $ K- K  w% j0 f7 h3 ?4 r##
    7 E0 T! f$ S7 m+ e/ y" H## $predict.time
    / ~2 M: b1 g2 {% @3 ~& ]## [1] 2000, v- P& D+ _% M
    ## 2 c/ V6 ^: I7 h/ W* d0 A) r
    ## $alpha
    / W8 {; \. }8 o, [: e9 H; K; u## [1] 0.05- J' O; ^5 F# @
    ## # j) S* v- ~& `8 p7 ]" e9 z
    ## attr(,"class")
    $ r* |7 B9 o( {! n## [1] "survNRI"
    2 L" H" @% _. ?# D' d6 r6 X& z9 a5 S
    14 i% v9 o; R5 P- p
    OK,这就是NRI的计算,除此之外,随机森林、决策树、lasso回归、SVM等,这些模型,都是可以计算的NRI的,后面会继续介绍。大家如果有问题欢迎在评论区留言。' p. H! p! y/ o& d
    5 C% w8 t0 ~4 x
    本文首发于公众号:医学和生信笔记
    1 ?+ k/ D; ~# P
    . l4 W; A: i0 U) \“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。( z' p6 B8 H6 m! \
    本文由 mdnice 多平台发布  x2 K: C& q/ k3 q! t1 ]! u4 H0 N
    ————————————————* j  r) z& P7 v  t/ J
    版权声明:本文为CSDN博主「阿越就是我」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    5 S, @+ j' n: X5 [# p原文链接:https://blog.csdn.net/Ayue0616/article/details/126768006( l; u( z' v) ]  ^6 w7 M
    9 E. V% f' F) o
    1 ^  A0 f4 a! P/ Q2 d1 ]- t
    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-20 15:06 , Processed in 0.468475 second(s), 51 queries .

    回顶部