QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3059|回复: 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 g3 f) n0 C, d6 u& z9 c
    净重新分类指数NRI的计算, }% j* J4 r* H% t! @% d+ c4 _
    “ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。
    - [' A1 C" _* J% q4 y6 X0 {4 x% xNRI,net reclassification index,净重新分类指数,是用来比较模型准确度的,这个概念有点难理解,但是非常重要,在临床研究中非常常见,是评价模型的一大利器!0 l+ }0 Z& H/ @# \
    " m6 ], H7 Y' \
    在R语言中有很多包可以计算NRI,但是能同时计算logistic回归和cox回归的只有nricens包,PredictABEL可以计算logistic模型的净重分类指数,survNRI可以计算cox模型的净重分类指数。
    & J  t- W, F3 Z4 ?  r0 ]# p9 O2 X! @0 T# a$ g- u5 ]( k
    logistic的NRI; H8 T3 ~! p& {; L3 O( H3 S
    nricens包- u/ E" ?, p* A* T7 P; r  Q
    PredictABEL包# i7 o6 s. k8 S( a
    生存分析的NRI
    7 B; P, r( q% v* ^9 I2 [nricens包& i. X8 u2 N9 @4 O3 c
    survNRI包: ]( D, J" R1 m' I6 G9 _% ?( {5 J! j
    logistic的NRI( ^& p4 }% ^4 q1 U
    nricens包0 E7 ^, b! J  O3 o# O) l: D
    #install.packages("nricens") # 安装R包
    ' S5 K% n' C% P! X, @* C6 ~2 Elibrary(nricens)6 W1 b3 N: \, d2 L. K  s  z) [+ H
    11 w0 U) v) B5 `
    ## Loading required package: survival
    % g5 A% n/ t, r* ]" Y3 a6 o1
    * ?1 x" q% E  `+ V9 o8 J9 T9 Q: U6 `使用survival包中的pbc数据集用于演示,这是一份关于原发性硬化性胆管炎的数据,其实是一份用于生存分析的数据,是有时间变量的,但是这里我们用于演示logistic回归,只要不使用time这一列就可以了。
    1 O4 r/ A# M- C0 y1 t) A+ L0 a9 r6 Q8 u5 F7 }7 Z! t- q
    library(survival)/ C0 \* `5 M1 U3 I+ ~

    $ F* g  m7 l4 I- P# 只使用部分数据
    0 `$ E7 h- d8 p$ e! ?dat = pbc[1:312,]
    # s3 R4 c' a( u( p- c+ bdat = dat[ dat$time > 2000 | (dat$time < 2000 & dat$status == 2), ]3 y8 N5 c& G) r( l1 R5 h9 L

    7 N1 S- a2 m4 Cstr(dat) # 数据长这样
    3 z. A! W) l! V3 T1
    6 [0 n& b0 z* ]. D## 'data.frame': 232 obs. of  20 variables:6 R. C4 r9 d. v9 C# P( k
    ##  $ id      : int  1 2 3 4 6 8 9 10 11 12 .../ L5 I8 P: t& v) d
    ##  $ time    : int  400 4500 1012 1925 2503 2466 2400 51 3762 304 ...
    8 u% B8 P+ f& M; n! x8 W* o##  $ status  : int  2 0 2 2 2 2 2 2 2 2 ...
    , D3 y' ]- @* a##  $ trt     : int  1 1 1 1 2 2 1 2 2 2 ..., Q9 B+ r3 S- ?5 L* r
    ##  $ age     : num  58.8 56.4 70.1 54.7 66.3 ...
    5 k2 @% G2 h; f$ g4 O##  $ sex     : Factor w/ 2 levels "m","f": 2 2 1 2 2 2 2 2 2 2 .... y, s3 W) [5 S0 ]5 ^
    ##  $ ascites : int  1 0 0 0 0 0 0 1 0 0 .... t; ^, `! c. V3 O7 y
    ##  $ hepato  : int  1 1 0 1 1 0 0 0 1 0 ...) v1 ?" }+ g+ F) B
    ##  $ spiders : int  1 1 0 1 0 0 1 1 1 1 ...
    & p0 X: K. \( ]+ w" [##  $ edema   : num  1 0 0.5 0.5 0 0 0 1 0 0 ...% `) Y6 W6 ?) q
    ##  $ bili    : num  14.5 1.1 1.4 1.8 0.8 0.3 3.2 12.6 1.4 3.6 ...+ ?* n: {8 x+ g& J6 l! G: P8 {
    ##  $ chol    : int  261 302 176 244 248 280 562 200 259 236 ...9 O. F" w3 m: _- f+ [3 }( @
    ##  $ albumin : num  2.6 4.14 3.48 2.54 3.98 4 3.08 2.74 4.16 3.52 ...# P$ P2 w+ a) }/ Q5 q; I5 K1 f
    ##  $ copper  : int  156 54 210 64 50 52 79 140 46 94 ...
      }9 g- P# g! R0 `/ p4 V##  $ alk.phos: num  1718 7395 516 6122 944 ...
    6 y; c. I; {- n9 Z8 v0 g, E* `, w##  $ ast     : num  137.9 113.5 96.1 60.6 93 ...
      ^) }, v* I! A5 l4 p0 K##  $ trig    : int  172 88 55 92 63 189 88 143 79 95 ...
    ! B# R4 {( I* p6 r##  $ platelet: int  190 221 151 183 NA 373 251 302 258 71 ...6 q/ C; H7 L; x3 c/ J3 p( {
    ##  $ protime : num  12.2 10.6 12 10.3 11 11 11 11.5 12 13.6 ...6 f0 i7 z$ i7 g# d: h! x9 L/ Z8 b; z
    ##  $ stage   : int  4 3 4 4 3 3 2 4 4 4 ...
    / h" h) v+ ?9 v$ [7 x6 P/ ^! _* m# l3 t/ ~7 R& {' `9 B- m
    1
    1 C7 m! v6 q9 z3 K/ P/ l, x4 Cdim(dat) # 232 20  Y8 G  Y6 Y: J3 L
    1
    ' I4 c' K0 k5 ^3 R! C/ i9 M## [1] 232  20) o: M/ _0 X0 L. c' m
    1; J+ s' N2 f$ R2 u5 I
    然后就是准备计算NRI所需要的各个参数。
    5 W% {, F9 M3 z7 I' z  \
    5 ]  r) Q% }: T* ~; \+ C7 ?, Q" U) X# 定义结局事件,0是存活,1是死亡
      v' j8 @! E/ e5 k4 a& Jevent = ifelse(dat$time < 2000 & dat$status == 2, 1, 0)
    $ j- k% f0 h/ a. Q) F! {$ r1 H. `" ?) P: G  L6 @0 p
    # 两个只由预测变量组成的矩阵
    5 _" j  S( X: \! Oz.std = as.matrix(subset(dat, select = c(age, bili, albumin)))
    0 Y/ V* d( Z! @8 y% az.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))
    # V! z. G2 s! Q' ^# `8 j! o7 g. ^8 O8 W$ U- Q% [
    # 建立2个模型
    ( u: k" z: h  [0 U$ umstd = glm(event ~ age + bili + albumin, family = binomial(), data = dat, x=TRUE)+ C1 N" _5 A( x
    mnew = glm(event ~ age + bili + albumin + protime, family = binomial(), data = dat, x=TRUE)
      y$ _, X# H5 X* G7 N0 b4 w( x; v9 l7 ~1 u9 f9 v
    # 取出模型预测概率2 a  ?6 f8 @; t
    p.std = mstd$fitted.values
    , q3 e- [* H, H( ap.new = mnew$fitted.values
    5 b+ [" O' f1 ?- P
    4 X9 L: Z3 [6 w4 Q1
    9 P5 I( a8 \0 s/ _( I! p然后就是计算NRI,对于二分类变量,使用nribin()函数,这个函数提供了3种参数使用组合,任选一种都可以计算出来(结果一样),以下3组参数任选1组即可。 mdl.std, mdl.new 或者 event, z.std, z.new 或者 event, p.std, p.new。
    4 h; s7 _5 ^% q% O5 L- u* D. m+ w: S
    # 这3种方法算出来都是一样的结果) ^$ H/ j& k( a! {# |* H* X! T9 ?

    $ R- d! h9 k' P( x# 两个模型
    4 A0 _! L+ N( ]. A8 Unribin(mdl.std = mstd, mdl.new = mnew, ; V. \" Z- N$ i7 |$ N( Q2 d" |
           cut = c(0.3,0.7), 9 P8 Y/ Y! u- u/ C
           niter = 500,
    $ I, z9 m$ z9 Q5 i! c# \, I       updown = 'category')# Z% i. j# k* x/ V" ~( Y$ Q/ q% ?

    ! b3 p) a' g) M3 H8 x% J) |2 M# 结果变量 + 两个只有预测变量的矩阵3 r# R) w  Y# r- `! r/ i2 {
    nribin(event = event, z.std = z.std, z.new = z.new,   ^0 @$ A7 ^/ Z+ I
           cut = c(0.3,0.7),
    / m6 i3 w2 G* s  C       niter = 500, . ~1 X3 h. `! J# E
           updown = 'category')$ R7 E# H4 x% o3 E$ b

    ! B0 s9 S  U3 b' |## 结果变量 + 两个模型得到的预测概率
    8 v' {) Y& K4 x7 m' _nribin(event = event, p.std = p.std, p.new = p.new,
    # a6 y, p3 Z2 v, p5 p: S5 ]# r       cut = c(0.3,0.7), 4 {+ C8 a+ A4 }  n/ o* h
           niter = 500,
    # m. C8 D. j. n( \$ v# d       updown = 'category')7 D- j& |3 q* c) |& u* ?

    " _2 G' D: g- A" g) {! z& e1
    " y: ~3 C9 Y& p7 x其中,cut是判断风险高低的阈值,我们使用了0.3,0.7,代表0-0.3是低风险,0.3-0.7是中风险,0.7-1是高风险,这个阈值是自己设置的,大家根据经验或者文献设置即可。5 P% E$ N" c1 U/ p4 a1 A9 W
    ( m4 ~1 h8 N' P; d- R; r  B# G
    niter是使用bootstrap法进行重抽样的次数,默认是1000,大家可以自己设置。9 O7 L9 m4 A, T& U
    ( t4 \$ o0 a: B
    updown参数,当设置为category时,表示低、中、高风险这种方式;当设置为diff时,此时cut的取值只能设置1个,比如设置0.2,即表示当新模型预测的风险和旧模型相差20%时,认为是重新分类。
    5 }5 \9 H' S# ]4 M  [. x& \/ A! V# ~# S% G* ]1 i4 `- p
    上面的代码运行后结果是这样的:) |3 m; s) H- O4 B  W
    5 T* E( n, U5 N( B
    UP and DOWN calculation:. A, t$ T" f) ?. T, g5 D; d  h
      #of total, case, and control subjects at t0:  232 88 144; V4 D1 V' X4 ?% k

    + n) X# I) w0 D- M  Reclassification Table for all subjects:' Q0 b9 f3 x8 G- {
            New$ @3 C( h6 W( s) @! J( |
    Standard < 0.3 < 0.7 >= 0.7
    : J$ ]. R, j# x8 m  < 0.3    135     4      00 \1 @  M# W9 y5 U, q5 L, m0 k
      < 0.7      1    31      4
    * ~+ @8 A: s4 S0 B- {  >= 0.7     0     2     55( }* Y+ x- W7 H
    % V% b9 E. b$ |) z. M
      Reclassification Table for case:
    * l* H/ U- {2 ^% W) z/ M+ D        New1 ]# l# F& F) e
    Standard < 0.3 < 0.7 >= 0.7
    , g7 A' n2 T/ s  < 0.3     14     0      0
    ! m/ G6 l: J# p6 _  < 0.7      0    18      3
    $ R. B. v5 s" W& |+ o: d" u0 G, ~  y, P  >= 0.7     0     1     52
    ) s, r' {. L% ^; z9 I3 ^1 B) w  r
    3 a9 N5 z4 c1 O% M7 [% f  Reclassification Table for control:! t! ^7 A, c' n% s2 @' [
            New0 v) x4 J. `  c5 Y" r1 }; P& S5 L- r
    Standard < 0.3 < 0.7 >= 0.7' q5 T8 C* k* r+ [8 n
      < 0.3    121     4      0. [$ w  n' b: x3 S
      < 0.7      1    13      1# d0 K* x1 E3 t, ^
      >= 0.7     0     1      3: d% u2 F4 d; S! C1 ^

    4 D5 L+ R. r* R/ jNRI estimation:
    , e4 J# R' R" o. X! ZPoint estimates:$ y. p" o" Z( Y- j
                      Estimate
    ( }! A2 L( ~0 k: T. W4 ~NRI            0.001893939: ~, K5 }: [2 `: c: W
    NRI+           0.022727273" J) J- V9 a' G, b* ?8 S
    NRI-          -0.020833333
    8 S8 s' ]* @) tPr(Up|Case)    0.0340909096 K) V2 A* }+ \& J3 Z8 H
    Pr(Down|Case)  0.011363636
    2 f* x. h/ o9 ~8 }% @* U7 KPr(Down|Ctrl)  0.013888889. I6 _0 O0 i- H  A9 o
    Pr(Up|Ctrl)    0.0347222227 }/ H! w4 f0 b6 B! D& X; k

    ' D0 ]1 H# s7 ]8 `4 `( L5 jNow in bootstrap..
    ! F5 T) X, c& f, J& I7 k' n' i7 v( W/ k, O$ L6 p
    Point & Interval estimates:
    ( x/ L) p* n/ ~. [' \7 f                  Estimate   Std.Error        Lower       Upper/ K4 {- L+ S( n/ A5 M- R- F
    NRI            0.001893939 0.027816095 -0.053995513 0.055354449$ X+ r: n8 V5 _! ^; }8 A( S
    NRI+           0.022727273 0.021564394 -0.019801980 0.065789474% v9 Q$ `- ~* g5 Z
    NRI-          -0.020833333 0.017312438 -0.058823529 0.007518797
    " u' ^& e1 ]4 t& ~0 v1 L5 zPr(Up|Case)    0.034090909 0.019007629  0.000000000 0.072164948, o7 k$ B$ u! v' O4 Z
    Pr(Down|Case)  0.011363636 0.010924271  0.000000000 0.039603960
    ) @5 n; Z3 @0 t9 d; @# LPr(Down|Ctrl)  0.013888889 0.009334685  0.000000000 0.035211268# e: I, O3 l" S5 j
    Pr(Up|Ctrl)    0.034722222 0.014716046  0.006993007 0.066176471- h8 |! l: J4 z# z' Z) Q
    0 r2 M) E' v" z- x. p9 w, U
    1: n4 r/ B% j5 ^* A, B8 T5 d% y
    首先是3个混淆矩阵,第一个是全体的,第2个是case(结局为1)组的,第3个是control(结局为2)组的,有了这3个矩阵,我们可以自己计算净重分类指数。
    " U; ]; G, |8 c" J6 J; s$ b& q0 C: g# |5 I
    看case组:$ I7 ]+ q9 c* a! G$ C$ q( t4 h

    % E! |! J; Q: ^4 d净重分类指数 = ((0+3)-(0+1)) / 88 ≈ 0.022727273
    ( _( F2 }3 Q! y
    : Z! m: K, Y' R( L' r再看control组:
    ) j8 s5 F8 M( J- _( k; i3 {6 P; J: k' M, M8 u
    净重分类指数 = ((1+1)-(4+1)) / 144 ≈ -0.020833333
    2 ]  i; T& _9 V) P7 `6 ~
      n6 x3 m# r" {) U2 ?) j! {9 I# U相加净重分类指数 = case组净重分类指数 + control组净重分类指数 = 2/88 - 3/144 ≈ 0.000315657
    * W. u. k; \+ n- w7 w
    / P1 D8 a* P! S再往下是不做bootstrap时得到的估计值,其中NRI就是绝对净重分类指数,NRI+是case组的净重分类指数,NRI-是control组的净重分类指数(和我们计算的一样哦),最后是做了500次bootstrap后得到的估计值,并且有标准误和可信区间。3 _- n" N2 K5 u9 P# g

    - Y; e' s3 w1 Z最后还会得到一张图:
    % z+ K) x6 N0 k! I4 g7 X2 D  [9 n4 d. G$ y  m2 N
    这张图中的虚线对应的坐标,就是我们在cut中设置的阈值,这张图对应的是上面结果中的第一个混淆矩阵,反应的是总体的情况,case是结果为1的组,也就是发生结局的组,control是结果为0的组,也就是未发生结局的组。
    " |1 l: V5 R! g: Z9 N. n$ a7 L8 N, m& e# E* T' t
    P值没有直接给出,但是可以自己计算。
    ; ~" |$ `" A# b( `- I
    1 i+ h8 _) R: ~3 Q7 ]9 L! `0 U3 u& C# 计算P值
    * d. `- W7 g- {z <- abs(0.001893939/0.027816095)" z) E0 {, u* _0 O4 i
    p <- (1 - pnorm(z))*2+ g, R; d  |( N& y) d" \9 u
    p6 K- Q/ O( U) k0 V0 _# ?5 j
    18 G6 m% I- O+ P4 ^9 D
    ## [1] 0.9457157+ J4 j' h$ ~# P0 V3 _& j" Z
    1
    & c! ?* J5 [$ U0 g$ F. q' FPredictABEL包0 l$ a8 }- i1 d5 L
    #install.packages("PredictABEL") #安装R包
    ) ^' t/ O. k0 C- X6 Q: Clibrary(PredictABEL)  
    " x9 s$ F7 c* q' k/ M# K; h7 A) u
    # 取出模型预测概率,这个包只能用预测概率计算7 K9 k) t  [- j
    p.std = mstd$fitted.values( N! K  m& f% S8 o: V
    p.new = mnew$fitted.values
    4 l5 y% A9 S  z3 W+ z2 T0 n* h1
    4 g0 ?2 u4 j1 e  B0 l7 g: b7 t然后就是计算NRI:
    . ~" w5 I; e- Y1 p0 s; @6 h
    # d( T8 D% _$ c. k- Gdat$event <- event
    , y0 o4 F9 e: N6 `: d3 z$ `- J  d; `9 U4 L: `+ I" _
    reclassification(data = dat,
    9 g* \: P) n# r) i) n- }$ Y                 cOutcome = 21, # 结果变量在哪一列8 m: A+ b! [0 f2 ~8 b
                     predrisk1 = p.std,% U& M* J9 [  L# i5 V9 z
                     predrisk2 = p.new,
    2 Q9 Q; z8 Z, x) R4 w3 p                 cutoff = c(0,0.3,0.7,1)
      \) n" C3 A) z8 u9 \                 )+ M5 R1 g4 i" z9 N) N" g+ I
    11 Q, k  h" j- X9 g
    ##  _________________________________________4 `$ G+ Q, Z' f- K* ?) x
    ##  
    9 P2 I! u- P1 Y8 a- `##      Reclassification table    ' O  [) p. J8 w& T8 m$ v) f
    ##  _________________________________________" s6 G0 p' Y6 u* Z# X9 Y1 I
    ## ' v* a$ n* U. U. m& Y; I
    ##  Outcome: absent
    4 ^5 }* H9 ], I) m##   
    * i3 y# B7 A. z4 k##              Updated Model3 [6 T) D3 j5 q% B4 ]" w: H& {4 _
    ## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified/ ^5 J& T6 I$ m( J1 J& F; j
    ##     [0,0.3)       121         4       0               3  g% p2 t+ T' m( p7 h& S
    ##     [0.3,0.7)       1        13       1              13
    7 o+ O( F* j  X# V+ m2 y  O; w##     [0.7,1]         0         1       3              25
    6 P9 i* E  W" B0 f##   z2 S! Q3 l& r# e
    ##  
    0 i# T$ r8 X( p7 j/ Y##  Outcome: present
    " a  p0 ]* ]! Z. \8 ^" M# w##   2 V! l7 f! p, u% T1 {3 R
    ##              Updated Model
    % D4 K  z. P: k" w## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
    * ^# m7 J( L2 m  B##     [0,0.3)        14         0       0               0
    4 z2 q: h7 _9 }! S- x/ d##     [0.3,0.7)       0        18       3              14
      D2 C4 a4 {4 d1 z, T3 H##     [0.7,1]         0         1      52               2
    4 O# h* o3 V+ c4 G$ V## 4 P; E3 J; U) l9 g( G
    ##  
    ( E. V( G3 J  L8 Q& z##  Combined Data ) }9 m4 H9 a+ _0 }
    ##   / E* k7 `+ \$ o4 I
    ##              Updated Model' Y* Q5 [: l5 Z7 c# n( F
    ## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified2 C9 _1 [) c' R$ t
    ##     [0,0.3)       135         4       0               34 F3 @  }4 A4 i+ ?3 _* j" l
    ##     [0.3,0.7)       1        31       4              14( D/ j# w# v7 i0 {- [% q3 z! |5 @( Z
    ##     [0.7,1]         0         2      55               4/ r9 A; h3 [. P. ?. T/ x
    ##  _________________________________________3 B6 U- u% x1 Q
    ##
    / P& X0 w& u- [* d. T+ c$ }##  NRI(Categorical) [95% CI]: 0.0019 [ -0.0551 - 0.0589 ] ; p-value: 0.94806 # e4 M; ~  \8 }! c$ F6 _& @
    ##  NRI(Continuous) [95% CI]: 0.0391 [ -0.2238 - 0.3021 ] ; p-value: 0.77048 % @  z" J6 Y; C
    ##  IDI [95% CI]: 0.0044 [ -0.0037 - 0.0126 ] ; p-value: 0.28396& o3 x, B2 d( W4 h: I
    $ v# q3 O' ]* G* L, [
    1, d! g% ?( Z' A$ {2 L
    结果得到的是相加净重分类指数,还给出了IDI和P值。两个包算是各有优劣吧,大家可以自由选择。2 E2 X( e% N8 r+ v+ X
    3 D  W* p" t0 i& m; P
    生存分析的NRI
    ' i! J( F! M2 A8 {; Q还是使用survival包中的pbc数据集用于演示,这次要构建cox回归模型,因此我们要使用time这一列了。
    " m6 k. m7 a# \3 {0 Z( p  t1 L( s0 d% Y. ?: s
    nricens包
    ' E+ x+ j/ R" @! G  C7 mlibrary(nricens)
    5 g/ x3 z$ N! `; q" j: W# ?: j+ g9 Wlibrary(survival)
      C5 g6 r' i$ e
    ; r/ L# \  u( X/ Ydat <- pbc[1:312,]" R8 i# }) s) b: s+ d
    dat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡. O3 p" O& V( o7 ]! e, s7 ?9 R
    1
    ; a& y. c( V' l$ l! Y然后准备所需参数:
    , W9 X$ v8 w6 [3 z$ M8 }3 C9 o9 A- H
    # 两个只由预测变量组成的矩阵/ k1 }" l+ l9 |$ w& d# _" D- C
    z.std = as.matrix(subset(dat, select = c(age, bili, albumin)))% l$ q7 @$ i0 g* }& J5 y
    z.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))
    8 o! U, n/ A4 T& Z; P$ M" [* L% _1 M5 C1 ]
    # 建立2个cox模型7 Y0 O. t$ P0 ?) F
    mstd <- coxph(Surv(time,status) ~ age + bili + albumin, data = dat, x=TRUE)) F3 F! D) |6 ?7 W% b
    mnew <- coxph(Surv(time,status) ~ age + bili + albumin + protime, data = dat, x=TRUE)
    , w7 A" n7 l# F6 B
    8 p4 k. H. d  p# 计算在2000天的模型预测概率,这一步不要也行,看你使用哪些参数
    : _9 K/ f$ C" W/ _# F# Rp.std <- get.risk.coxph(mstd, t0=2000)- {9 c/ ]) h7 ~
    p.new <- get.risk.coxph(mnew, t0=2000)
    8 P6 u0 {, j" T5 W1 h10 D9 c( a/ C- s7 r
    计算NRI:& J) o) D5 \, S& F2 o
    # B; Y* I# O3 J( E8 h  u8 a0 M
    nricens(mdl.std= mstd, mdl.new = mnew, * [+ j8 x6 p  I; s
            t0 = 2000, : [# i2 Q  W: Y  I
            cut = c(0.3, 0.7),
    1 Q" b' y7 N6 w) p& ?3 k        niter = 1000, $ N- q4 y- X3 B6 `1 z) {
            updown = 'category')( g8 K1 A. A% u' C. A6 Z

    + I# S; I. q1 x( z' Y3 DUP and DOWN calculation:9 S& \* A( L+ P
      #of total, case, and control subjects at t0:  312 88 144
    . t( C" o  l; X% U4 _* H
    ! A# k/ I' d# Z/ d* j8 q; D  Reclassification Table for all subjects:  y0 K; e* x: K7 t" z8 X, y
            New
    * U+ h1 l# I' b8 YStandard < 0.3 < 0.7 >= 0.7
    8 v# L8 o0 j/ r" C4 l$ C3 B7 ]/ c  < 0.3    202     7      0+ \4 @# J) w; I% s" }! k3 R
      < 0.7     13    53      66 n$ e/ x( T( W5 Q! Y5 L8 k
      >= 0.7     0     0     31
    / c. s. U# m6 o- @" ?
    ; T! k4 z, `4 s, R$ @, {4 a  Reclassification Table for case:
    2 x* z- `: V8 X4 i' o: [. ^        New
    " ~! b& P1 q( \" [! ^. C4 H% DStandard < 0.3 < 0.7 >= 0.7
    + v  B3 @3 C$ u+ A  < 0.3     19     3      0
      a2 b4 \( R; g4 N# [  < 0.7      3    32      49 x! W* o2 f8 j' C1 _
      >= 0.7     0     0     278 d& n9 c# [  y1 [3 w  G4 H
    + g1 U2 Q+ i* B, l. e- ?7 A9 y
      Reclassification Table for control:
    $ S4 V2 U4 \5 }! }        New1 q5 N! |; R9 q0 k5 p
    Standard < 0.3 < 0.7 >= 0.7
      Y- q: n6 ^0 z5 w  < 0.3    126     3      0; K9 c$ k$ x) O% A6 T( @9 W  C
      < 0.7      5     7      2
    ( U0 @) I" w$ W1 P( Z( \, M7 r. [7 J  Y  >= 0.7     0     0      1! S! v  g& B0 s0 Z, T9 k( r
    ! L  p3 x. O  P6 M# c  P
    NRI estimation by KM estimator:
    3 L1 ?6 u* a7 J0 m# h( M$ S: t
    9 U9 f5 g9 w& \4 h& A0 q, GPoint estimates:
    : j0 l& c& p6 _* D- |0 X! a                Estimate) ~2 M$ a) `* |5 F, G- m* X
    NRI           0.05377635  y. |  l9 e$ |
    NRI+          0.03748660
    # o+ x1 u7 b3 f' H% h. ^NRI-          0.01628974: u& @( l2 L" E, l# ~7 F. {- R
    Pr(Up|Case)   0.07708938- G( n5 t1 b( n7 g/ L
    Pr(Down|Case) 0.03960278) Y* w6 j% |! `7 R
    Pr(Down|Ctrl) 0.04256352
    5 h1 _+ @3 P$ a; J# s2 o: O& JPr(Up|Ctrl)   0.026273783 U$ _: P% \( [1 N+ e

    1 h, T& f" z$ j# CNow in bootstrap..
    , l- A0 M# m' k0 N8 R& F# k- A  C
    Point & Interval estimates:
    % l% W7 A. Z  {& b& b                Estimate        Lower      Upper
    ' q# f& Z6 ~% @3 p8 yNRI           0.05377635 -0.082230381 0.16058172* y. L" d; E3 d# x
    NRI+          0.03748660 -0.084245197 0.13231776) O) c) ^  i( j' Y  e
    NRI-          0.01628974 -0.030861213 0.06753616
    $ [2 M, Y- {9 a+ X+ k# YPr(Up|Case)   0.07708938  0.000000000 0.19102291
    3 K6 B  w5 \; R! @& x; |' wPr(Down|Case) 0.03960278  0.000000000 0.15236016
    8 G2 v5 D; x4 Y3 y, H0 a+ V6 gPr(Down|Ctrl) 0.04256352  0.004671535 0.09863170
    8 P8 p1 m) `/ f. w8 v* D: I/ iPr(Up|Ctrl)   0.02627378  0.006400463 0.05998424, P# [4 v: p6 u; c

    1 ~4 F% ^0 ^, `4 D+ J- Y1' _8 z4 ?  N; Z% K
    , L4 B% _, b4 j9 p6 Y- z3 ]+ D
    Snipaste_2022-05-20_21-49-38
    2 L& P. V9 m' U0 l# \1 }3 o/ s' T结果的解读和logistic的一模一样。, {1 ?/ f( W  _3 p, k! g  _
    ; r1 M* Y" O. l  n  C4 v% b+ @$ G5 C
    survNRI包+ h2 R: {6 X! L! B
    # 安装R包  h+ `% b; }4 B7 a1 X* U
    devtools::install_github("mdbrown/survNRI")0 o( Q7 r+ o- h- Z# k* a  M* K
    17 E8 e( n- f& q" h5 Q  K
    加载R包并使用,还是用上面的pbc数据集。" j6 t" b" n8 D9 K7 p

    2 M7 A( t, W0 slibrary(survNRI)( |# ?8 b$ J5 x+ X( b
    1* R+ T6 I7 ^2 N
    ## Loading required package: MASS7 f( u) X- j3 s6 k# s2 |
    1  l' M2 a7 l- C
    library(survival)4 h7 {' B" U4 ~+ C% M5 N

    % O! [" }3 c* D+ P: W# m# 使用部分数据, n% `. M8 B% N
    dat <- pbc[1:312,]
    $ h4 t: }* d( d& T! _dat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡
    & ~% f1 `7 }$ Z: x, L2 x7 |& h. z5 n" u! ]7 j
    res <- survNRI(time  = "time", event = "status",
    3 {. b& a/ A  X" d( e7 g        model1 = c("age", "bili", "albumin"), # 模型1的自变量
    ' T% g" m$ z0 m8 G, j7 K- ]3 J% O% L1 K        model2 = c("age", "bili", "albumin", "protime"), # 模型2的自变量
    5 _; L) h, V& k# Y/ v, [9 G0 q        data = dat,
    , }9 h& g& @7 }- m8 m/ L* O# F" ^! ^        predict.time = 2000, # 预测的时间点$ t" ?! I1 A! J' s! {) r; b
            method = "all",
    ' [9 `2 @( N" U2 s2 R% C' w$ F7 \9 l        bootMethod = "normal",  : @+ h, c. ~) q
            bootstraps = 500, * ^6 B+ R6 P3 {9 Z
            alpha = .05)
    : b1 \- i4 Y! T' N* h# n$ t3 q" ~7 p4 z+ t
    1# n. ]8 b6 P% N7 w# R
    查看结果,$estimates给出了不同组的NRI以及总的NRI,包括了使用不同方法(KM/IPW/SmoothIPW/SEM/Combined)得到的结果;$CI给出了可信区间。
    9 r, V  L9 M% @3 v
    / W5 }" @& y( a6 m# Vres  M8 `7 e# n; f  T- W+ A5 J
    1
    ( d! y8 N0 N# r" ^" c" B## $estimates
    . v$ i, G9 O4 d; ~7 K( @2 c0 l6 Z##            NRI.event NRI.nonevent       NRI# V5 ?2 [9 [2 n4 h4 {+ g, N
    ## KM        0.20445422    0.3187408 0.5231951/ r) Q$ {" o" h1 ~" `3 y
    ## IPW       0.22424434    0.3273544 0.5515987
    6 z; m9 r# G# d$ l3 V: v2 R## SmoothIPW 0.19645006    0.3144263 0.5108763! E4 E+ N' {$ ?& Q
    ## SEM       0.07478611    0.2632127 0.3379988, E  B: N3 z4 D$ f& o: h% h6 r
    ## Combined  0.19633867    0.3143794 0.5107181' e9 L/ J5 W% N: D6 {
    ##
    ( X2 b5 G% z5 Q0 }0 i## $CI
    . E3 b5 Z+ W! N% ^## $CI$NRI.event" p3 P3 J0 d  ~  v8 m7 N  K! W
    ##                     KM         IPW   SmoothIPW        SEM   Combined
    + g) H. a% W, w3 Q## lowerbound -0.03915924 -0.02185068 -0.04724202 -0.1162587 -0.0473723
    " m- z1 X7 W* u+ y7 k7 J  D0 N## upperbound  0.44806768  0.47033936  0.44014214  0.2658309  0.44004963 t% t0 o$ z; C4 B/ n5 C9 C& A% L
    ##
    4 A9 A: [7 K6 C8 |/ x9 T* R## $CI$NRI.nonevent: j- D0 F* i& [& t2 N
    ##                   KM       IPW SmoothIPW        SEM  Combined7 H9 B6 I/ g* G2 ^# p& F9 T
    ## lowerbound 0.1317108 0.1396315 0.1286685 0.08638933 0.1286426
    , o% l# I, m5 s0 J## upperbound 0.7102251 0.7393216 0.6966341 0.51482212 0.69645495 P' t) |! p; r5 a- Y5 h6 |: R
    ##
    , ?  L2 b$ m; `/ C+ [& Q## $CI$NRI& ?$ a* w* _5 Z8 Z; [( i' C
    ##                     KM         IPW   SmoothIPW         SEM    Combined, w2 U# @$ p$ ^7 V* l3 A
    ## lowerbound -0.05112533 -0.04569046 -0.05439863 -0.04132364 -0.05443409. W3 z% I4 Q+ i6 ~" ?+ Q$ U6 C8 q
    ## upperbound  0.89306122  0.92464359  0.87970125  0.64253510  0.879531532 e+ J( d6 c; W
    ##
    : i4 S6 b6 N$ J  F- \' w## % ^) P! V. z, R5 b; j
    ## $bootMethod
    & K1 l, T1 E* Z& [1 g+ U9 B# ]" h, p## [1] "normal"7 D. f7 _- Q( k; i: o( c
    ## * o9 h% n( Y) ?. {1 B2 A$ S, d
    ## $predict.time  S! y# y) _: d" A9 I9 z
    ## [1] 2000' h" F, \  P- K) @
    ## . a3 W# e( S, p# c5 _2 q
    ## $alpha% }% l6 m* k$ c/ ^
    ## [1] 0.05; F% j) y& j& t9 B0 I) E* f
    ##
    4 E. {6 u) p1 M/ M% ~  z& s## attr(,"class")7 ~5 R) f  c) l( T. `
    ## [1] "survNRI"  j, B- `% i1 O* @+ f. a3 ?6 t0 |7 B
    " ~0 ^) a7 w% l1 `3 P
    1
    3 A5 [; \. G6 R; H9 l  hOK,这就是NRI的计算,除此之外,随机森林、决策树、lasso回归、SVM等,这些模型,都是可以计算的NRI的,后面会继续介绍。大家如果有问题欢迎在评论区留言。% v5 |7 _; N& Q

    , l; Y: X+ e7 C! a7 o本文首发于公众号:医学和生信笔记
    ' K) C2 B% `- N; f' A8 r+ J# E/ s9 M& p- n1 n! O! v
    “ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。
    1 y9 C- X8 f! z* ^3 n  H本文由 mdnice 多平台发布
    # V* Z+ k' ?+ |2 j————————————————
    3 e2 U2 Q- P$ p6 M& K9 o版权声明:本文为CSDN博主「阿越就是我」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。' ^. l) t6 p5 ~0 F
    原文链接:https://blog.csdn.net/Ayue0616/article/details/126768006
    " c0 u5 o3 l8 b  h7 g7 l* N' h& ]5 s5 n- X
    0 K: d2 E+ f2 i
    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-6-15 01:07 , Processed in 0.446075 second(s), 53 queries .

    回顶部