QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3080|回复: 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
    & k4 e0 A) i/ ~" ]
    净重新分类指数NRI的计算  ^* b+ b4 `& ~3 e. g
    “ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。! `6 P* K7 p) U, {8 ~
    NRI,net reclassification index,净重新分类指数,是用来比较模型准确度的,这个概念有点难理解,但是非常重要,在临床研究中非常常见,是评价模型的一大利器!
    1 `0 C" [1 e6 i9 Z2 P# e+ K) I* N1 O
    在R语言中有很多包可以计算NRI,但是能同时计算logistic回归和cox回归的只有nricens包,PredictABEL可以计算logistic模型的净重分类指数,survNRI可以计算cox模型的净重分类指数。
    - X0 D% ^- Y$ Z# n( Y! |' v9 ?! ?6 J4 g; |5 Y5 b5 v; c) m' }/ v
    logistic的NRI
    ! B2 o  H! z5 l% _7 J: [nricens包2 ?; }: O. _7 x8 u7 n* F! D+ o2 D5 }
    PredictABEL包, X8 E' x& ~7 S/ l* ]1 G. }7 `' H( F: T' i
    生存分析的NRI5 j/ f5 {) ~- p& T/ O$ Z1 N, \! ?/ i
    nricens包
    / N/ x/ M7 g. Q; PsurvNRI包/ v0 ?( O1 D, I& \) f
    logistic的NRI
      ]" P8 `. `& g# a8 \" @1 cnricens包
    . b/ V. u) O: V1 z#install.packages("nricens") # 安装R包
    ; [5 L9 D' g1 d  Z% plibrary(nricens)
    . d; g! j. e+ ]18 L; T# N! m1 c8 ^5 {
    ## Loading required package: survival9 _6 D7 a7 k6 y# Y9 @+ B
    1
    / N0 T, N/ }0 a0 l" b, Q使用survival包中的pbc数据集用于演示,这是一份关于原发性硬化性胆管炎的数据,其实是一份用于生存分析的数据,是有时间变量的,但是这里我们用于演示logistic回归,只要不使用time这一列就可以了。
    9 Z" Y7 x& g( \- V6 s( X6 R, E1 j* F  T
    library(survival)
    2 p# o8 o! {  v0 N! K% s# z) z4 g" s
    - n5 E; u' c8 b# 只使用部分数据, g3 k5 O( |$ v6 ^# @
    dat = pbc[1:312,]
    1 x, @/ W% L1 c; F- vdat = dat[ dat$time > 2000 | (dat$time < 2000 & dat$status == 2), ]' `( L. d& M* J3 g# q0 X7 M

    3 Q" }/ E; U3 J, M8 `str(dat) # 数据长这样8 B. r' I; D+ T, ^3 p
    18 M( T" R( \* @: i
    ## 'data.frame': 232 obs. of  20 variables:
      ~$ [" L8 `0 Y/ Q, ?##  $ id      : int  1 2 3 4 6 8 9 10 11 12 ...( K; ^- B' o: o6 W
    ##  $ time    : int  400 4500 1012 1925 2503 2466 2400 51 3762 304 ...
    0 e$ ?5 {( @, k: U##  $ status  : int  2 0 2 2 2 2 2 2 2 2 ...
    % V5 ~/ n! `$ E% H3 e##  $ trt     : int  1 1 1 1 2 2 1 2 2 2 ...
    0 H7 J) h* Q+ A) d/ w0 T- Q##  $ age     : num  58.8 56.4 70.1 54.7 66.3 ...* |3 R! r$ ~. U( x; S
    ##  $ sex     : Factor w/ 2 levels "m","f": 2 2 1 2 2 2 2 2 2 2 ...9 i1 w1 r1 g" f3 I6 i+ y+ q
    ##  $ ascites : int  1 0 0 0 0 0 0 1 0 0 ...7 y; U  w  `! u" [
    ##  $ hepato  : int  1 1 0 1 1 0 0 0 1 0 ...
    ) y1 Z- D; Q5 F  W  `##  $ spiders : int  1 1 0 1 0 0 1 1 1 1 ...9 K) r" \- ?; z$ e7 m1 o
    ##  $ edema   : num  1 0 0.5 0.5 0 0 0 1 0 0 ...) k- q7 E$ ?2 I6 Y- B0 U6 A
    ##  $ bili    : num  14.5 1.1 1.4 1.8 0.8 0.3 3.2 12.6 1.4 3.6 ...' m. `% k( V4 x& G" z' L
    ##  $ chol    : int  261 302 176 244 248 280 562 200 259 236 ...
    ! i% C8 J# S7 m9 t8 |1 e##  $ albumin : num  2.6 4.14 3.48 2.54 3.98 4 3.08 2.74 4.16 3.52 ...* A6 d% X- D0 F1 o
    ##  $ copper  : int  156 54 210 64 50 52 79 140 46 94 ...6 k$ Z9 G+ p$ H0 x) d
    ##  $ alk.phos: num  1718 7395 516 6122 944 ...
    . j5 |# p* ]  O  s##  $ ast     : num  137.9 113.5 96.1 60.6 93 ...( [! R; z' R3 p
    ##  $ trig    : int  172 88 55 92 63 189 88 143 79 95 ...
    " {' Z' H8 I  v9 t2 }##  $ platelet: int  190 221 151 183 NA 373 251 302 258 71 ..." \; Z$ D. h1 @8 @% }) x& I5 _- k
    ##  $ protime : num  12.2 10.6 12 10.3 11 11 11 11.5 12 13.6 ...2 S( X8 A' T* J  m5 u0 p& V
    ##  $ stage   : int  4 3 4 4 3 3 2 4 4 4 ...
    + r8 l/ F1 t- ]& W. [! X$ ]' _6 R) {
    $ l. o" n* H9 Q0 Q5 C6 b1
    8 F5 u, H6 Y0 O5 \4 E/ jdim(dat) # 232 20; [+ p% j/ z% t- _& d
    1
    3 @! C) |) ^& c/ C& T; [## [1] 232  20
    ' h5 G# f9 E6 @8 ?9 u$ g" G1
    2 r( t/ b6 k/ r" \" \2 H/ Z& j' y然后就是准备计算NRI所需要的各个参数。; z. `$ g" s1 \$ Q

    7 J* U( l' a& S2 ^* [) c7 [# 定义结局事件,0是存活,1是死亡6 K' v: ?( S& ~' Z, q
    event = ifelse(dat$time < 2000 & dat$status == 2, 1, 0)
    1 Q. f2 l  L0 _  `$ A  f/ g: s) I/ Y% r0 |" A6 b0 A
    # 两个只由预测变量组成的矩阵
    ' r8 ?" l1 K) k# o. t5 e/ D: Lz.std = as.matrix(subset(dat, select = c(age, bili, albumin)))
      P" E4 M+ r5 \9 x( p0 ez.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime))). b+ C& W5 `. m" C/ m
    % Q2 R) L5 Y6 [  Z! x, }$ b
    # 建立2个模型
    5 w# E9 ^, @) [. F  `! o% n5 V9 lmstd = glm(event ~ age + bili + albumin, family = binomial(), data = dat, x=TRUE)" s) ~! e6 d) w: O% K% C4 N$ T6 o5 c
    mnew = glm(event ~ age + bili + albumin + protime, family = binomial(), data = dat, x=TRUE)& P% h$ x3 P" c- c7 F; g

    7 }$ o; ^+ r6 W. [# 取出模型预测概率* I' @$ w" g, h; F: B& K5 A. F+ u  B
    p.std = mstd$fitted.values6 U! u- v' \- e/ h, a5 q4 [) V
    p.new = mnew$fitted.values
    6 F# @9 X, r- S- }% x% A
    8 @1 l! x6 `9 X: N8 l2 ], k% H14 L7 x8 q. V8 k# {) |' S
    然后就是计算NRI,对于二分类变量,使用nribin()函数,这个函数提供了3种参数使用组合,任选一种都可以计算出来(结果一样),以下3组参数任选1组即可。 mdl.std, mdl.new 或者 event, z.std, z.new 或者 event, p.std, p.new。1 B6 B' R7 J6 \' H$ X1 {! J/ b

    1 R1 m3 l9 O: k. x/ h' K: |% d# 这3种方法算出来都是一样的结果1 v' g/ R5 ?! o/ j! @
    ; C7 ]1 b5 M1 Y# O/ j, a0 d
    # 两个模型# g3 T3 H5 H3 W8 j! S" o* d
    nribin(mdl.std = mstd, mdl.new = mnew,
    " V- L6 e3 y( E# G7 F$ m4 J       cut = c(0.3,0.7), * P! Z: T1 ~8 @- l; R  [
           niter = 500,
    % r" A! I6 A. d# U) v       updown = 'category')
    8 C. U0 I1 O% e4 v" T1 g- v3 U; }  M9 F
    # 结果变量 + 两个只有预测变量的矩阵8 y! }& ~( ^2 J! t' b8 f
    nribin(event = event, z.std = z.std, z.new = z.new,
    3 m/ K" f7 c1 \* P; S6 U, r       cut = c(0.3,0.7),
    ( ]' N# ~8 A7 O! N6 {; F" s       niter = 500,
    ! T; n$ o  Z; B! j) R, m  X# ~$ h       updown = 'category')% i! p5 y4 `- x$ r

    & d+ e+ V- H/ O( a## 结果变量 + 两个模型得到的预测概率  P0 n% }) r! V2 t3 N4 i6 u
    nribin(event = event, p.std = p.std, p.new = p.new, # ?( e8 k9 H  |( g- ~
           cut = c(0.3,0.7), & ]' B; l5 f$ {. [  J' `
           niter = 500, - |; [* S0 _. x. c8 S; u4 k
           updown = 'category')
    9 I) c2 Z# D' G' F2 r( s7 n. }7 n6 ~8 P
    1$ a9 ?  D* w2 J$ Q
    其中,cut是判断风险高低的阈值,我们使用了0.3,0.7,代表0-0.3是低风险,0.3-0.7是中风险,0.7-1是高风险,这个阈值是自己设置的,大家根据经验或者文献设置即可。3 I$ V1 L8 v7 I# ^$ \
    + y6 `+ L9 R, H0 \! P
    niter是使用bootstrap法进行重抽样的次数,默认是1000,大家可以自己设置。
    - d* l- R/ h" M- ?7 ^+ E, ^% O, Q
    updown参数,当设置为category时,表示低、中、高风险这种方式;当设置为diff时,此时cut的取值只能设置1个,比如设置0.2,即表示当新模型预测的风险和旧模型相差20%时,认为是重新分类。
    1 b, p- s# n. S: M0 H5 x+ K3 q+ ?& @
    上面的代码运行后结果是这样的:" E: w7 h( Z8 z& L. Z) L( O

    ; F) t% v( Y3 X! z" ^0 N5 qUP and DOWN calculation:
    ' m% k2 o  D% @( i+ g) b  #of total, case, and control subjects at t0:  232 88 144% z7 E* @* \) V$ M1 E3 @- d+ P

    # r6 I8 e$ p  x; U  z  Reclassification Table for all subjects:
    ( q$ q, j$ K& R. K( |8 P        New
    ( m1 c& r- A  PStandard < 0.3 < 0.7 >= 0.7
    $ k/ J: A. I( K- u* Y8 A( t3 B, g  < 0.3    135     4      0
    * t% w/ B9 \- Y  < 0.7      1    31      4
    & ?, o: C3 r1 V  >= 0.7     0     2     55* M/ x7 R3 Z" b
    2 G% H( O9 R/ f  B1 \! t+ H
      Reclassification Table for case:
    $ ?! E  w% b" ]# `# f% Y! o" p/ f        New
    7 N- B0 W3 G+ H' S$ RStandard < 0.3 < 0.7 >= 0.7
    8 a4 u' N- e/ E' o; {+ a0 d  < 0.3     14     0      0
    1 I7 O, I( `1 {; C  < 0.7      0    18      3
    $ z3 O( k( C$ F9 d7 Q  >= 0.7     0     1     52
    / {' o1 z4 ^' k9 u/ Y
    7 t& T1 i9 H+ G0 l# H5 u, g( ~  Reclassification Table for control:- ?: b8 K, q! T
            New
    0 B8 I* k. A# A4 MStandard < 0.3 < 0.7 >= 0.7& ?4 p  V: M( H; t: P# {/ t
      < 0.3    121     4      0$ Z; q) c: W, {" Z
      < 0.7      1    13      1
    , I7 F5 l( |" J; }2 s6 P  >= 0.7     0     1      34 B" W6 a& g# l
    # j3 G' K+ M$ e6 u7 E, `& C' U
    NRI estimation:
    ( v8 }: ]2 n  V  P* p( s8 U  pPoint estimates:
    0 N- F# W, P' k" [( q" }+ k                  Estimate- n$ K! V, P* T& h% B
    NRI            0.001893939
    2 r1 r% c. u6 h- ^4 FNRI+           0.022727273
    + I; d6 ?% R3 s2 b9 oNRI-          -0.020833333& N: x! ~) y$ ]9 M
    Pr(Up|Case)    0.034090909$ M* i. C! ?) n! V3 ^, M
    Pr(Down|Case)  0.011363636/ D; e. |) j8 c
    Pr(Down|Ctrl)  0.013888889( z4 x2 H; A* B" n
    Pr(Up|Ctrl)    0.0347222229 k' q7 [/ l$ d  s# x
    ; Q$ E$ W0 ^! h: P+ w9 H3 J
    Now in bootstrap..
    + m. t2 }% z8 _: v# G0 `5 g6 y. E
    4 s. [* k0 Y1 J# v- k* bPoint & Interval estimates:
    9 c# x. I# @1 D) A4 \9 O2 I: s/ w, s                  Estimate   Std.Error        Lower       Upper8 P9 }' P" F6 w; M5 l4 t
    NRI            0.001893939 0.027816095 -0.053995513 0.055354449+ \6 x$ q2 h  x9 V; f5 F  \
    NRI+           0.022727273 0.021564394 -0.019801980 0.0657894743 C6 D6 q- D% u* k
    NRI-          -0.020833333 0.017312438 -0.058823529 0.007518797
    ' y0 I! F) a' IPr(Up|Case)    0.034090909 0.019007629  0.000000000 0.0721649485 n+ _9 ~2 u6 r' N$ L; F5 D
    Pr(Down|Case)  0.011363636 0.010924271  0.000000000 0.0396039606 E/ \0 p, q' u2 n  d% A
    Pr(Down|Ctrl)  0.013888889 0.009334685  0.000000000 0.035211268+ R% V1 V" Q) N) L; z# v2 ^7 a
    Pr(Up|Ctrl)    0.034722222 0.014716046  0.006993007 0.066176471
    ; M4 N1 v5 h7 @# q1 O& G
    ) t2 A7 Z" `- M, ^6 {- |- p# P$ V) {1
    $ H8 n# u0 K, L! K首先是3个混淆矩阵,第一个是全体的,第2个是case(结局为1)组的,第3个是control(结局为2)组的,有了这3个矩阵,我们可以自己计算净重分类指数。: S9 R2 y' l4 P7 y+ j$ P

    % O8 k1 y* D2 }% J; d8 b) N看case组:
    1 L: X% T$ M7 l3 _, ?0 w( Y4 e' p5 E" U3 d; j
    净重分类指数 = ((0+3)-(0+1)) / 88 ≈ 0.022727273
    8 v% y# b, l) `. @- A
    9 A- X4 z# @% l7 y  g1 ]再看control组:; g4 B1 n5 }7 I: D# v$ s' b
    8 E2 x( {# L4 d& b2 s8 j; l/ I
    净重分类指数 = ((1+1)-(4+1)) / 144 ≈ -0.020833333
    8 f# t! w& u( n+ g+ i/ p' _, ?8 @4 z; }! t, u9 H
    相加净重分类指数 = case组净重分类指数 + control组净重分类指数 = 2/88 - 3/144 ≈ 0.000315657
    ! s4 [+ X' y; R1 g1 k5 _6 S- E) R1 ], [$ ^
    再往下是不做bootstrap时得到的估计值,其中NRI就是绝对净重分类指数,NRI+是case组的净重分类指数,NRI-是control组的净重分类指数(和我们计算的一样哦),最后是做了500次bootstrap后得到的估计值,并且有标准误和可信区间。
    ( P6 q$ a+ S; m5 [1 l
    ; r, w, {0 H. H7 @最后还会得到一张图:
    3 L- G" x7 g& g' V) @/ ?( _6 r$ p" R! l$ q( H
    这张图中的虚线对应的坐标,就是我们在cut中设置的阈值,这张图对应的是上面结果中的第一个混淆矩阵,反应的是总体的情况,case是结果为1的组,也就是发生结局的组,control是结果为0的组,也就是未发生结局的组。
    - R1 {: ?" I$ t6 T: w1 ^! i& |
    / l$ ^+ Y5 f. k; bP值没有直接给出,但是可以自己计算。% B7 w$ `5 o0 [4 I

    : l( A" ]" I# {/ i& Y# 计算P值
    " Y, a( m" t2 i0 X6 p, ]2 z" Qz <- abs(0.001893939/0.027816095)
    , M& }- I& h5 D: {' Qp <- (1 - pnorm(z))*2
    1 C( Z9 ^; R1 e/ f/ ]0 op
    . h5 ~+ S/ d+ I' t* ?4 u$ I8 y1/ k  i; L; e& Q) ]
    ## [1] 0.9457157
    - c* x& m; p/ w+ P! ~; v; i1
    ) L+ `' ]0 I1 KPredictABEL包5 P: l8 Z/ k5 G6 R
    #install.packages("PredictABEL") #安装R包; E! H3 g- v( g7 _) o
    library(PredictABEL)  * [" R! ]2 G' t: i: |/ Z3 }4 I
    9 D# K/ z) I  G1 X0 l
    # 取出模型预测概率,这个包只能用预测概率计算
    1 G, J% d. Z" M& p& U3 dp.std = mstd$fitted.values
    6 k3 q7 Y3 r; P, K8 G5 I: up.new = mnew$fitted.values
    ; C: F! `; _0 g$ ^! K* q/ W' K1
    ) h) V- A0 I5 L) h- ^7 I( g然后就是计算NRI:
    / Z3 u) L$ o$ j2 e
    ' c) K/ r+ o  x; v& odat$event <- event: N: s2 W% F& _  r# ]
    * T. [$ D( Y/ P+ H
    reclassification(data = dat,
    $ g# r3 k% g+ V7 L5 I; s$ P9 I                 cOutcome = 21, # 结果变量在哪一列
    % M5 O- |4 ~6 i4 j; y4 L9 C                 predrisk1 = p.std,
    1 z0 u/ G% ]$ e) T- j+ b. H% X- b                 predrisk2 = p.new,: y. Z- N3 f8 l' n
                     cutoff = c(0,0.3,0.7,1)) j! c2 u- O3 w: |
                     )9 S5 g* \! i3 L  G
    1
      G# V5 S& E0 C" E8 @$ _: L- A0 W##  _________________________________________
    3 e, r9 A: F6 E& Z8 R##  ) H5 K( ]; z2 X# y& C5 b1 u% x0 x# i
    ##      Reclassification table    + _4 D; a3 y! j/ M
    ##  _________________________________________
    ' _; e+ E5 Q2 v, N2 C+ ^& I$ _##
    / g2 j0 H: O; Y; l) J: N6 s* l##  Outcome: absent
    ' h+ P+ h' h& ~##   2 m7 d6 o( I. Z
    ##              Updated Model
    ! o8 i- g) B3 t* l, L## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
    4 w: L3 r2 H6 a) Z##     [0,0.3)       121         4       0               3
    - F% }5 K8 R: X/ }3 L6 ~##     [0.3,0.7)       1        13       1              133 t1 v; H* Q* l0 _1 U
    ##     [0.7,1]         0         1       3              25
    % c" E. K* M* B9 u: A# G) F$ V##
    : c0 w$ L! w% r2 E( G' W1 C+ n9 d##  
    ( u7 C' w  u: f9 N: p; Y, w##  Outcome: present
    % |+ `6 V3 N) I# {4 }; h##   
    ( E0 y; \1 o0 m4 @##              Updated Model: T5 e  o0 A/ o/ v: }7 m. u$ y
    ## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
    & W8 T! N" P1 U/ x* F##     [0,0.3)        14         0       0               06 X/ _; m, u2 {/ h+ V7 e
    ##     [0.3,0.7)       0        18       3              14
    , g# V  V. g, P9 i% ]##     [0.7,1]         0         1      52               21 c' p! R! I' |" r; U9 x# j
    ## 0 v, @# y, A! h! p/ }4 L  u
    ##  $ n7 {7 m) D& u# e
    ##  Combined Data
    / a* Z- ]8 C# o' X7 n* c- u##   
    * {  F* y3 H6 V% z$ u##              Updated Model
    ) j: w4 D" [" C1 @+ `; [## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
    : o( ^, B  M1 U! k2 _##     [0,0.3)       135         4       0               3+ r! N) J3 E( D0 t  c' r. r8 f
    ##     [0.3,0.7)       1        31       4              14$ w8 H, S6 g$ z  ^8 n/ d# V
    ##     [0.7,1]         0         2      55               4
    8 }8 p  E$ i2 M* S##  _________________________________________8 x5 r+ l; l( |; f
    ##
    % H# M1 r( p* T  S##  NRI(Categorical) [95% CI]: 0.0019 [ -0.0551 - 0.0589 ] ; p-value: 0.94806 4 y( M. R/ [/ F7 ~* [# X! C
    ##  NRI(Continuous) [95% CI]: 0.0391 [ -0.2238 - 0.3021 ] ; p-value: 0.77048 7 {% ^, f  _7 W. I9 k
    ##  IDI [95% CI]: 0.0044 [ -0.0037 - 0.0126 ] ; p-value: 0.28396
    6 M5 l6 y$ M' p" u+ p: t% k3 f6 D" Z) j5 O0 n5 u
    1
    & v% L3 e  {( A8 S0 q( A9 W结果得到的是相加净重分类指数,还给出了IDI和P值。两个包算是各有优劣吧,大家可以自由选择。6 g) X0 Z- c( k

    & h) Z. {5 }3 y1 i2 D& ?生存分析的NRI1 G3 Z0 A& w: @
    还是使用survival包中的pbc数据集用于演示,这次要构建cox回归模型,因此我们要使用time这一列了。' z* v, ~9 w, X/ q8 T5 F) M& E
    1 z  z' a# A9 A# l  n# X
    nricens包
    " {" r0 l4 O2 H/ r# A! F) ~6 wlibrary(nricens)3 ?/ M. j* o3 @) x6 N& U, `) V
    library(survival)  h5 _$ G- }# k, f* U! \

    4 k; k1 p# L% `9 O! y7 a7 f2 t; [9 Gdat <- pbc[1:312,]
    ! S* p# ~# J8 Ddat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡
    : h( C$ W0 K* N6 e/ O  _' w, A0 h1
    ; g& y# H1 L4 S. {, r/ j然后准备所需参数:" o1 V! N9 q! X# T' i! E4 d

    5 V, F% ^, u# U$ R6 C# 两个只由预测变量组成的矩阵' n$ L; B7 h( B* t+ l
    z.std = as.matrix(subset(dat, select = c(age, bili, albumin)))
    + L6 y' N  H+ ?; C9 M3 hz.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))
    5 t5 A4 n+ l$ G% x* c; b1 `1 T( B
    + J! I2 d7 a, I3 E: _% E# 建立2个cox模型& T! v+ ?/ V% Q8 m8 `
    mstd <- coxph(Surv(time,status) ~ age + bili + albumin, data = dat, x=TRUE); T/ |7 _4 m4 y# I( o/ i
    mnew <- coxph(Surv(time,status) ~ age + bili + albumin + protime, data = dat, x=TRUE)7 |& }  t- U: L; C4 T3 c
      |3 |+ O8 D6 \2 Q0 W8 f
    # 计算在2000天的模型预测概率,这一步不要也行,看你使用哪些参数6 L1 ~0 v0 K& c
    p.std <- get.risk.coxph(mstd, t0=2000)3 U  \' A7 D& ?; {7 S- Q' p# d4 e
    p.new <- get.risk.coxph(mnew, t0=2000), [" T2 K" w& M: o! s
    1. C; l6 f' R6 @. F0 W) W
    计算NRI:/ J% }( b- u2 X
    3 N1 _0 W+ Q9 P7 s; l# f
    nricens(mdl.std= mstd, mdl.new = mnew,
    . t" R: e- p; K. E, {        t0 = 2000,
    . m6 M- Y! k8 w6 _) n$ ~2 g        cut = c(0.3, 0.7),4 P4 S8 Y! g, r" V9 T, K
            niter = 1000, 1 {, h- P. M; d. ]
            updown = 'category')- [" @2 R7 O. ~, e- `! z/ X
    . f; c- r1 m" d, m0 x! P" V0 ]
    UP and DOWN calculation:# j  W- ^1 [/ j2 a# q0 S% u" Y7 m4 j
      #of total, case, and control subjects at t0:  312 88 144
    : ~7 W1 k  }( {2 Z, u1 C+ {1 ]5 ]. ?% `  C
      Reclassification Table for all subjects:, ]) i; ~' W* @  s4 ?: i
            New: P% W8 O' {* ]9 ~
    Standard < 0.3 < 0.7 >= 0.7& ], l! b2 E. y; d( N$ k1 z" S8 I5 T
      < 0.3    202     7      0
    , d, N  V) ]0 F6 @3 C  < 0.7     13    53      6, T8 ]/ m8 R4 \$ K+ {
      >= 0.7     0     0     31: ?7 ?" g* a% A

    1 H9 Z2 H  o+ Z5 u5 i$ m# H  Z  Reclassification Table for case:
    , X  x( f7 O. o5 x, Z        New
    . H& F; o4 I8 ]" i  a- m6 Q+ n6 s. WStandard < 0.3 < 0.7 >= 0.7
    * Z  C4 Y. u5 u) F  < 0.3     19     3      07 K& J# n+ q* p) S/ g
      < 0.7      3    32      4
      X- ?* ~% O) Y8 M: f' u4 ^( o0 p  >= 0.7     0     0     27
    4 W" N( U. l6 ]6 l0 ^/ z- ?3 }! Z! z7 F1 `
      Reclassification Table for control:  y7 G0 d; }; f5 H
            New5 n$ w  d* S# N/ B+ C
    Standard < 0.3 < 0.7 >= 0.7% s, K: e( D# p: X# a. B
      < 0.3    126     3      0
    6 \* \* O, p6 U, f- d* T  < 0.7      5     7      2
    - E  @% Y4 O* m; |0 m  >= 0.7     0     0      1$ T2 D/ E' y$ B' ?  V4 _/ L
    & d" O7 ?+ k% g" z9 x3 O
    NRI estimation by KM estimator:* t/ b# O: u; s; ~8 X) l/ q

    # P% ]( m- t- C; C/ G; \Point estimates:" u( F! z$ ^6 [$ h1 F$ [! B  q1 P
                    Estimate
    * T0 x9 ?) L9 I! s; P5 N6 rNRI           0.05377635
    . S" I8 l3 U. P5 ]5 r4 vNRI+          0.03748660
      D) a  u7 M9 d7 `; J& A: yNRI-          0.01628974; F# ?* [2 a4 K& _' r
    Pr(Up|Case)   0.07708938; B1 J5 Q0 T# u* I3 [7 o+ t! ?
    Pr(Down|Case) 0.039602785 L$ z+ N, s$ S/ Q& k8 ]
    Pr(Down|Ctrl) 0.04256352
    4 H' c  o- t  UPr(Up|Ctrl)   0.026273786 \7 o/ X" b6 c. H7 L$ g
    + s7 ^: g9 ?1 g8 ?* ]3 q& J
    Now in bootstrap..5 r) R7 ^& ~( z2 @
    7 _- \+ J( n2 B' o$ U. G5 V
    Point & Interval estimates:7 \# R1 E# R' [0 S2 x
                    Estimate        Lower      Upper; a3 ]+ Y/ n' S& F% M0 @
    NRI           0.05377635 -0.082230381 0.16058172
    3 d; R  H$ D% N! c% z" wNRI+          0.03748660 -0.084245197 0.132317761 T6 c8 s( d! x& b0 U" s! ?
    NRI-          0.01628974 -0.030861213 0.06753616
    & N1 G1 v7 e5 R+ _5 LPr(Up|Case)   0.07708938  0.000000000 0.19102291
    3 \) r0 p: O" h# W6 K- x. Q- Y% CPr(Down|Case) 0.03960278  0.000000000 0.15236016
    ( |( N! n7 P/ L1 S8 y" P' h& XPr(Down|Ctrl) 0.04256352  0.004671535 0.09863170. s% l; s0 N" F4 j- q; J. z
    Pr(Up|Ctrl)   0.02627378  0.006400463 0.059984246 [. i; s- E& z% O( D) D

    ) c; ?1 T, V# l0 [, _6 _. X1# Z5 I4 W+ |6 x! i* @. L/ }

    4 t1 |! l. P* \6 {Snipaste_2022-05-20_21-49-38
    7 p  U) X! s8 c, O& s结果的解读和logistic的一模一样。
    + `! D. N3 t, q. B3 |" s8 Y/ u0 M$ c% C4 R" B# r0 @: C
    survNRI包9 j! e- r+ e# B1 G5 Q% K! f$ {+ R
    # 安装R包  E8 H$ N8 Q. Z0 m1 X4 M
    devtools::install_github("mdbrown/survNRI")7 ?" _8 J; r; {* ?8 r
    1
    " m2 [3 b8 }% T* S. S加载R包并使用,还是用上面的pbc数据集。6 C# [! i% M; J+ w$ C

    - I/ p; L* k4 Z. flibrary(survNRI)( ?( p+ L4 n# a" h9 l$ q
    1
    ; b+ g  N$ S# @1 v( C## Loading required package: MASS$ w, M/ X' v& g$ {
    1
    + j3 D6 b; h  T8 }' n( P2 X. U! @5 Slibrary(survival)
    / h% N; ?  F, i
      Y5 `) v  U" O8 Q5 n& E2 U# 使用部分数据+ G  p5 L# K( ^$ t% U+ b/ Q
    dat <- pbc[1:312,]
    " S7 f/ A# R* Bdat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡$ y# |1 y, q  X- g% |/ A- M

    0 ~! {9 a! E$ z1 Kres <- survNRI(time  = "time", event = "status",
    0 d& e' @& x6 q- A" Y* W        model1 = c("age", "bili", "albumin"), # 模型1的自变量
    " {! F  f' J7 }) o/ R2 B' t' ]        model2 = c("age", "bili", "albumin", "protime"), # 模型2的自变量
    2 K4 W) t) T/ {7 |( S" a7 w        data = dat,
    . [* d1 v6 M! t" |7 D! E. W* }        predict.time = 2000, # 预测的时间点
    - {* p3 `6 Z+ M% r        method = "all",
    . P+ q4 Y) G# g8 |  }" |- _( X& q        bootMethod = "normal",  
    5 Y# z) }. \: x0 r3 z0 c& R' h        bootstraps = 500,
    4 |0 ~+ L4 ?: G2 `) X8 W        alpha = .05)
    5 k# q6 L5 ?5 `2 j1 s5 Z7 P# ]" {8 y/ A6 g1 a
    1
    / }: E$ m3 z6 {查看结果,$estimates给出了不同组的NRI以及总的NRI,包括了使用不同方法(KM/IPW/SmoothIPW/SEM/Combined)得到的结果;$CI给出了可信区间。
    7 p7 P7 P- ?/ G% e
    & A8 f* Q+ X/ W+ Dres
    ; q" b, R8 M0 P8 |' Z* V7 T% t- {1, U/ p- V6 Y7 U( M4 y6 L
    ## $estimates8 b( M3 P. ~3 [' c" a( f1 @4 ?
    ##            NRI.event NRI.nonevent       NRI  n3 s3 e1 I7 V$ b+ F/ s
    ## KM        0.20445422    0.3187408 0.5231951
    " P- U" }% V; x' K) L4 p" N## IPW       0.22424434    0.3273544 0.5515987! O* e7 U% G; r. \- |) {
    ## SmoothIPW 0.19645006    0.3144263 0.51087637 m- G/ m1 f% v. {
    ## SEM       0.07478611    0.2632127 0.3379988( z1 w/ h2 P" E4 {( i3 i8 g
    ## Combined  0.19633867    0.3143794 0.51071816 o( W% ]' B. l/ `4 k
    ##
    4 I' P; g: e9 g2 M4 l& E" `# Y' Y## $CI
    ( u: A* K  I& r8 H# `## $CI$NRI.event& ^( p. ~, M8 Q/ [/ a7 i
    ##                     KM         IPW   SmoothIPW        SEM   Combined
    $ w0 A% m1 C% s0 Z+ i## lowerbound -0.03915924 -0.02185068 -0.04724202 -0.1162587 -0.04737232 H2 N  h% I; T  z
    ## upperbound  0.44806768  0.47033936  0.44014214  0.2658309  0.4400496& N/ {  U7 @- D3 f: A/ K" i+ i
    ##
    : ~6 y! V, ^, i1 @& l8 c; M## $CI$NRI.nonevent
    % _& [) ]) U7 x& H##                   KM       IPW SmoothIPW        SEM  Combined6 z4 U* d% N8 ?6 o, h1 j( }
    ## lowerbound 0.1317108 0.1396315 0.1286685 0.08638933 0.1286426. n. z+ ~- t% r$ b
    ## upperbound 0.7102251 0.7393216 0.6966341 0.51482212 0.6964549
    & N& i5 m4 Z( o8 d. b/ N## 6 C: D4 ^/ l2 A6 @% u2 U
    ## $CI$NRI; A7 f6 \3 h2 F) u& f. |' z2 S
    ##                     KM         IPW   SmoothIPW         SEM    Combined
    % O) W( L. ~9 |0 I. I- X! m## lowerbound -0.05112533 -0.04569046 -0.05439863 -0.04132364 -0.05443409
    - y9 k# A! G3 n/ {/ @) ]4 K$ r  T## upperbound  0.89306122  0.92464359  0.87970125  0.64253510  0.87953153
    . K( b  B  U1 O1 R/ l$ G##
    ! G, A3 n- d9 |! U7 s% O## , |: P' z1 H" p( W1 |
    ## $bootMethod
    8 A6 ?) R* I* I( y- j3 z5 s, W## [1] "normal"
    # f* W+ G* ~5 g4 J# Z2 v##   r' X# `  c9 p! S( U+ _! H
    ## $predict.time
    6 B+ d  M9 W( _  l## [1] 2000
    ' R; G( r$ `6 W, y## + F+ Z. J2 e+ I2 p  r* d
    ## $alpha
    4 w/ |3 ~4 k6 R9 h/ a## [1] 0.05
    9 O" n0 B4 _! H! N- S3 g##
    * [* A" p9 v$ h0 t( P) ~% `## attr(,"class")/ {  q$ K' e) A3 W0 y4 n- [7 m
    ## [1] "survNRI". A2 \+ T/ m' M

    $ ]  t& \) h- K# \" t- M. y0 c0 w% E' f1
    $ l9 y; s( P2 E3 Z. a, _OK,这就是NRI的计算,除此之外,随机森林、决策树、lasso回归、SVM等,这些模型,都是可以计算的NRI的,后面会继续介绍。大家如果有问题欢迎在评论区留言。8 _6 X: H- ?7 T4 }( W6 P1 A

    6 K* r( R& g# I5 j# @7 L本文首发于公众号:医学和生信笔记7 [! p+ H" \! @2 Y
    + u! L/ {" s0 Y/ S/ s7 V" F
    “ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。- o/ f; f: ~$ y2 T! w
    本文由 mdnice 多平台发布
    # h, o9 E3 C9 P! C& T* O% B————————————————
    7 K" P$ y! N( \版权声明:本文为CSDN博主「阿越就是我」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    + V, H% |+ E- }0 r原文链接:https://blog.csdn.net/Ayue0616/article/details/126768006* o9 U) E8 E  H1 `
    5 w4 B9 j- v% P2 f% J1 E
    9 c) n- Q" H1 f" S2 @
    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-7-30 02:45 , Processed in 0.392468 second(s), 50 queries .

    回顶部