数学建模社区-数学中国

标题: 净重新分类指数NRI的计算 [打印本页]

作者: 杨利霞    时间: 2022-9-12 18:43
标题: 净重新分类指数NRI的计算
# Y9 U& Q2 \# i: p
净重新分类指数NRI的计算, l5 z2 V$ e* x+ p) {
“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。& ?7 e3 d9 F; G: Q5 @
NRI,net reclassification index,净重新分类指数,是用来比较模型准确度的,这个概念有点难理解,但是非常重要,在临床研究中非常常见,是评价模型的一大利器!% {- J. k( M6 z

! C8 I5 Y5 H1 ]: N在R语言中有很多包可以计算NRI,但是能同时计算logistic回归和cox回归的只有nricens包,PredictABEL可以计算logistic模型的净重分类指数,survNRI可以计算cox模型的净重分类指数。
, ]/ s1 r9 L% L5 ]; ~9 B5 s) k1 a4 N# x+ b# h
logistic的NRI. b) \: g7 S3 ^# _0 H$ t1 W
nricens包
- e* g# U) I/ O+ u8 s6 T$ u7 EPredictABEL包
4 ]9 w" H( T& y生存分析的NRI
2 n) R- J& i" u* C: R: @5 Qnricens包: g' v5 N, d& h: i1 B4 F+ `: f
survNRI包
9 o1 d  K" Z. qlogistic的NRI
9 p& f% T; a- {8 J2 C2 Qnricens包2 ~( P+ E' ]# f8 t- I
#install.packages("nricens") # 安装R包7 V! h, x3 j( I  Z$ G6 A$ J6 P8 S8 q
library(nricens)! u) _& }9 U: M
1! K& K( m5 |; [6 B: m' r: I' g
## Loading required package: survival
% e3 ~. c) l1 b/ l: r6 Z1, b# f& F* {/ O6 C) Z
使用survival包中的pbc数据集用于演示,这是一份关于原发性硬化性胆管炎的数据,其实是一份用于生存分析的数据,是有时间变量的,但是这里我们用于演示logistic回归,只要不使用time这一列就可以了。* j- |) B7 Q: h( [) w- c) _4 Z  H

% p0 R9 y' c! I, w/ T# c; Plibrary(survival)
  x# |! I. C2 ~& f  G1 F' C
# X* l2 y9 h9 s; K. s# 只使用部分数据/ g3 w9 {* _) b9 b
dat = pbc[1:312,]
  g/ _( C5 D; \% _" m+ ?dat = dat[ dat$time > 2000 | (dat$time < 2000 & dat$status == 2), ]; C- v$ x+ `1 R

* ^. W6 r# g& p: v( u  D4 ostr(dat) # 数据长这样
& l1 z1 h7 S6 g. D. H8 z1" S2 ]3 Z3 a- X; b1 N; t: D) T
## 'data.frame': 232 obs. of  20 variables:
) i4 E, q# p- y- I1 \! R##  $ id      : int  1 2 3 4 6 8 9 10 11 12 ...- r3 |) ?7 O, ]6 j. O
##  $ time    : int  400 4500 1012 1925 2503 2466 2400 51 3762 304 ...
5 b6 K- U& a6 Q  o% J4 L##  $ status  : int  2 0 2 2 2 2 2 2 2 2 ...
- x' h" d- M) z##  $ trt     : int  1 1 1 1 2 2 1 2 2 2 ...
0 }8 a  e7 P% l) Q) @##  $ age     : num  58.8 56.4 70.1 54.7 66.3 ...) h" h% V( x$ r' w
##  $ sex     : Factor w/ 2 levels "m","f": 2 2 1 2 2 2 2 2 2 2 .... Y8 k" V/ s8 g/ }; H( e6 Z
##  $ ascites : int  1 0 0 0 0 0 0 1 0 0 ...7 z5 s+ W  N: a2 z- z% k; F" \
##  $ hepato  : int  1 1 0 1 1 0 0 0 1 0 ...( Y$ |7 s5 T7 B6 y+ g8 W: @
##  $ spiders : int  1 1 0 1 0 0 1 1 1 1 ...
9 G: i& h  k4 [3 V3 i##  $ edema   : num  1 0 0.5 0.5 0 0 0 1 0 0 ...% ?0 [' [( ~3 Y
##  $ bili    : num  14.5 1.1 1.4 1.8 0.8 0.3 3.2 12.6 1.4 3.6 ...% W) {$ H) n' b3 w
##  $ chol    : int  261 302 176 244 248 280 562 200 259 236 ...
% r. g$ @3 q2 E- b' H# V##  $ albumin : num  2.6 4.14 3.48 2.54 3.98 4 3.08 2.74 4.16 3.52 ...
: z4 P3 Y( U$ J( @1 ~  U; Y' N3 Z1 k7 x##  $ copper  : int  156 54 210 64 50 52 79 140 46 94 ...4 D4 H6 u" p; r4 C" {. s
##  $ alk.phos: num  1718 7395 516 6122 944 ...
: k/ |2 m9 R$ y/ E/ W/ r##  $ ast     : num  137.9 113.5 96.1 60.6 93 ..., A$ P8 o9 m( \
##  $ trig    : int  172 88 55 92 63 189 88 143 79 95 ...8 Z5 J, S' t3 e2 U: h
##  $ platelet: int  190 221 151 183 NA 373 251 302 258 71 ...
2 Z  a: p$ p; S" Z( j& k5 c; V# \8 g##  $ protime : num  12.2 10.6 12 10.3 11 11 11 11.5 12 13.6 ...# o6 X* i" g& G0 G7 p2 S. S9 r  M
##  $ stage   : int  4 3 4 4 3 3 2 4 4 4 ...0 i8 L' ]  b3 n% a0 n

$ a4 n" m2 G' \$ L/ @/ R6 V  q1# i% Y( s: y: c% F; a9 P4 ]8 N3 q
dim(dat) # 232 20
" C% W6 I; s) z9 d1 `8 `0 {1) g* g- n# o2 h* B  {  |
## [1] 232  20
: v! m- c9 ~+ _) x% ?7 ^' g% r1" R" A) l0 Y# k9 G6 [7 t3 h3 |
然后就是准备计算NRI所需要的各个参数。
6 g2 I% a" p4 x- j% c" I: }: L  e! f* F2 r, C6 ~
# 定义结局事件,0是存活,1是死亡
9 H& V" o. ?# V; [) Q9 g3 ~event = ifelse(dat$time < 2000 & dat$status == 2, 1, 0)1 H. c6 _1 Z5 g0 B, S

! P+ p6 @6 o3 M" K/ `# 两个只由预测变量组成的矩阵: B+ J# T7 S! L
z.std = as.matrix(subset(dat, select = c(age, bili, albumin)))
' |' G% v2 `1 S: a5 rz.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))
8 u( k  ^7 y- ~7 ]% w0 g1 T. K% P+ J0 w4 A1 l  h# }
# 建立2个模型- i1 _# B5 z3 r+ U, I  N
mstd = glm(event ~ age + bili + albumin, family = binomial(), data = dat, x=TRUE)) B# _( B4 A0 p/ J2 t/ d: E, ]
mnew = glm(event ~ age + bili + albumin + protime, family = binomial(), data = dat, x=TRUE)0 i& F2 a/ K- c) \! \+ w& z

4 `; q( X  v( o  A$ X6 J5 L# 取出模型预测概率
+ G+ r# p- j4 ^  O2 h4 Ep.std = mstd$fitted.values
% A0 u, ~# _+ K5 Gp.new = mnew$fitted.values& d) h  [6 l8 l, N' @

! `. f0 C& {* {1
; l0 j1 ]5 [$ M9 i- e) h2 @  {然后就是计算NRI,对于二分类变量,使用nribin()函数,这个函数提供了3种参数使用组合,任选一种都可以计算出来(结果一样),以下3组参数任选1组即可。 mdl.std, mdl.new 或者 event, z.std, z.new 或者 event, p.std, p.new。: ?8 f" z" F: `- ]  ?, {7 m  u

6 W& P, }0 [  x  B# W0 h/ d5 ^# 这3种方法算出来都是一样的结果
+ I+ ?1 o% \/ r- B' C
; r' l# W$ o' o1 J6 t9 q# 两个模型
0 K( v2 y# q6 a3 _9 z  _8 wnribin(mdl.std = mstd, mdl.new = mnew,
7 d" ^$ ?" B  U4 k. v! ]       cut = c(0.3,0.7),
, H3 p4 O: ^/ z) E       niter = 500, % z6 D" z- i6 e6 q5 t
       updown = 'category')3 I$ e2 B% D9 w1 E

8 @/ |6 D8 g" y. v, w; f6 K# 结果变量 + 两个只有预测变量的矩阵
7 h. n' p, J, Mnribin(event = event, z.std = z.std, z.new = z.new,
: _$ H3 n) T! C5 @2 [' F       cut = c(0.3,0.7), / `2 m" ]) h+ A0 |; m. {. f, f
       niter = 500,
  k3 k/ h7 b, e       updown = 'category')
( C# e( f9 v6 h1 ~; p6 D  \7 c
## 结果变量 + 两个模型得到的预测概率( c- c  s0 H4 b2 p
nribin(event = event, p.std = p.std, p.new = p.new, , O7 ]8 p9 b2 U/ L) K6 \
       cut = c(0.3,0.7), 3 P! k- R% x; y" Z. g, ]: t
       niter = 500,
* ~# O) @% l# |/ B, u7 L       updown = 'category')
! v$ p6 A  i! L+ Y; w
) C$ k4 w3 }; b* |1" H! ~* U% a4 C! A+ e2 x4 ]
其中,cut是判断风险高低的阈值,我们使用了0.3,0.7,代表0-0.3是低风险,0.3-0.7是中风险,0.7-1是高风险,这个阈值是自己设置的,大家根据经验或者文献设置即可。
- Y/ G- B% z5 Q. k
; ]) s2 \4 {; ~; `8 P! ^) vniter是使用bootstrap法进行重抽样的次数,默认是1000,大家可以自己设置。$ Z" A- z4 d/ _8 ^) e! ?! f
: B. E( _+ U1 Z" V
updown参数,当设置为category时,表示低、中、高风险这种方式;当设置为diff时,此时cut的取值只能设置1个,比如设置0.2,即表示当新模型预测的风险和旧模型相差20%时,认为是重新分类。/ D( A1 p8 g" k. j1 L
7 V2 V3 Y' r! D+ ^$ T; [
上面的代码运行后结果是这样的:' H  p: V' Y3 j) J
5 h6 l5 P' p/ s2 T1 y. D6 c/ x
UP and DOWN calculation:7 f( a& y1 i7 ]6 E  W1 T3 _
  #of total, case, and control subjects at t0:  232 88 1443 b4 E! I- w* M2 J# X
% w9 `! G) |* d' s. p3 R2 a/ @
  Reclassification Table for all subjects:
4 w! a6 [6 w( B, u- w0 [        New6 r! q" T; o! n& I5 N
Standard < 0.3 < 0.7 >= 0.7
. i! o* g9 l3 C/ r; x# l# s4 P: ]8 s  < 0.3    135     4      0) f7 S8 q, m6 }/ g5 ^
  < 0.7      1    31      4
: C" A2 p' s8 J# x+ p' z1 S  >= 0.7     0     2     55
- m; o3 h: H: N# o
" l1 f! S! m" L- c1 m8 t- A  \  Reclassification Table for case:6 u' q& E' W- m: Q; q6 X
        New
8 [9 g' P. i7 s7 i: c* nStandard < 0.3 < 0.7 >= 0.7: b; {, J! Y& v2 T* `( k" K
  < 0.3     14     0      0
: Y/ P% ^6 c& C& @( z# p2 a  < 0.7      0    18      3
) t$ |+ H/ E2 l3 m( E  >= 0.7     0     1     521 E( ]0 H; g, }/ E. h! o
; [6 E  ?0 p+ `( ^
  Reclassification Table for control:. I0 \. c; ?( G% Z* a
        New' a( I& R& ~& y7 }0 U+ j
Standard < 0.3 < 0.7 >= 0.7" A) r) W8 r5 R
  < 0.3    121     4      0
5 E* [3 v" h, v% b) n  < 0.7      1    13      1
2 j$ d' R$ ^' A5 ?  {  >= 0.7     0     1      36 \/ Q2 P9 y2 s" G0 `4 R9 \

# a& J, l( `6 k" b) b  ANRI estimation:
  q8 t' y# |9 U* ?. iPoint estimates:
6 s1 b" N6 v5 N/ X. b: C$ y8 U                  Estimate
3 V, V  Y7 n+ J% @NRI            0.001893939. W& @$ {- q1 r1 }, ?
NRI+           0.022727273
$ d6 \1 O2 w8 F3 K0 YNRI-          -0.0208333339 F: N8 L- b* d' J
Pr(Up|Case)    0.034090909
* w  v& p* [  O* @6 t" r5 l2 gPr(Down|Case)  0.011363636
" G. F' s9 o' j7 {Pr(Down|Ctrl)  0.0138888898 u$ n  ]% e6 f$ ]: [  [
Pr(Up|Ctrl)    0.034722222- F9 ]/ d! @) M; {* O) t

4 L& O6 o& S8 I" Q# W) WNow in bootstrap..0 q) p& v3 j! m9 a: W
! m3 m. H8 i) J# T5 k  I; ~' [
Point & Interval estimates:+ e2 N" J% S. D$ E$ x7 I
                  Estimate   Std.Error        Lower       Upper: k- J8 g5 G5 h1 v+ v; z- }% j5 @
NRI            0.001893939 0.027816095 -0.053995513 0.0553544496 E5 N9 }7 B5 Y* e+ U
NRI+           0.022727273 0.021564394 -0.019801980 0.065789474
$ s6 Y3 T* I8 ~7 C" {" ]NRI-          -0.020833333 0.017312438 -0.058823529 0.007518797: Q8 \/ _. n) W' k. N
Pr(Up|Case)    0.034090909 0.019007629  0.000000000 0.072164948
7 P. x+ J9 `2 D/ W4 y6 i9 ]Pr(Down|Case)  0.011363636 0.010924271  0.000000000 0.039603960
$ Y. ]4 ?7 |; T; GPr(Down|Ctrl)  0.013888889 0.009334685  0.000000000 0.035211268
1 t6 s% U4 |! U0 j7 oPr(Up|Ctrl)    0.034722222 0.014716046  0.006993007 0.066176471
8 [6 t& l' a- h( F" A% p/ O+ u4 d; O; W; w0 R* g& l
1. W- ]0 \' Y; W/ _' I' f: f9 o
首先是3个混淆矩阵,第一个是全体的,第2个是case(结局为1)组的,第3个是control(结局为2)组的,有了这3个矩阵,我们可以自己计算净重分类指数。8 p4 U+ G$ b1 p. H  D

. o( ^* L( ~6 }3 e( \看case组:' h, N8 m9 n( k8 W

4 V) {' u7 @; `2 Y) u1 x净重分类指数 = ((0+3)-(0+1)) / 88 ≈ 0.022727273
9 }% }6 ^& b! p! d0 \7 h; i9 Q
% k3 }4 [+ t! `- }" i1 I再看control组:
1 m" _3 s1 G# z. o) f* z& g
  p5 x6 P, d$ E净重分类指数 = ((1+1)-(4+1)) / 144 ≈ -0.020833333
2 ?. Z% F# s+ |( {, D1 ]" G  p; Z2 q9 U+ l2 ?
相加净重分类指数 = case组净重分类指数 + control组净重分类指数 = 2/88 - 3/144 ≈ 0.000315657) z  g6 M% ~+ K
" O: q, D; Q3 ^$ c% r
再往下是不做bootstrap时得到的估计值,其中NRI就是绝对净重分类指数,NRI+是case组的净重分类指数,NRI-是control组的净重分类指数(和我们计算的一样哦),最后是做了500次bootstrap后得到的估计值,并且有标准误和可信区间。" q# c. W& ~( n5 V

4 @  ?% ~5 k7 M0 d% [! z1 D1 A最后还会得到一张图:
" a/ y/ H' [1 r& p, v" ], l% W# K  X, Y; ~
这张图中的虚线对应的坐标,就是我们在cut中设置的阈值,这张图对应的是上面结果中的第一个混淆矩阵,反应的是总体的情况,case是结果为1的组,也就是发生结局的组,control是结果为0的组,也就是未发生结局的组。5 n' L% \7 l) @: K3 s, z0 @

, \# @+ [& j2 L( F* h9 U  kP值没有直接给出,但是可以自己计算。+ p# j5 _; z0 m6 y8 p- y$ `5 d5 }, ~
# ?4 B2 z7 k/ h* K
# 计算P值
1 L3 o; G/ H- D& ^" \z <- abs(0.001893939/0.027816095)
! l1 D/ m$ O3 o' e6 Vp <- (1 - pnorm(z))*2: Z( g! q8 M9 N
p1 u. g1 `1 I, Z) I; }
14 T4 n. X6 @' ~& [% o
## [1] 0.9457157
3 X3 k4 V$ `- ^& W1 p7 M' x% r8 F1
  U  p9 F: O+ g' v* [: cPredictABEL包% {  Y% m: I& q" \" ?' R7 K, y
#install.packages("PredictABEL") #安装R包
, Z( r, N6 C% N/ ^6 {library(PredictABEL)  6 N5 G6 d1 n- c/ `+ n% x1 e7 F

  ?, U1 X( C' t. s% x# 取出模型预测概率,这个包只能用预测概率计算$ y$ W  L! H! f2 m& l
p.std = mstd$fitted.values+ s8 U& P1 Q# I: r7 J
p.new = mnew$fitted.values $ r; U( R7 ^0 Y& I$ L0 m
1: P4 Y7 v" q! o7 U5 l5 q/ }' s
然后就是计算NRI:
6 W/ C: q7 ]; x  `& Z7 K$ W, ~$ B1 d) Z  p, [: z2 Q
dat$event <- event
' g2 J8 L2 ^1 Q/ S+ a
9 Y; L1 p  ^) f4 m. A: V2 Areclassification(data = dat,
4 h# K9 m. ^% g. t/ F- R                 cOutcome = 21, # 结果变量在哪一列
: x5 Y2 ?! Z* o" Z' U) p  c                 predrisk1 = p.std,
/ R1 i' K1 i! ]                 predrisk2 = p.new,
1 Y  E7 J; b9 i2 o8 L                 cutoff = c(0,0.3,0.7,1)
* R  X( g+ X# P1 z! U                 )* |+ A% l/ {- K+ ?' F4 I
1
5 f8 k$ T* K6 V( L% E# r##  _________________________________________
' Q  u) M0 k& |9 t/ g  P##  
# j8 p$ z% r( ^  ~/ W2 I##      Reclassification table   
8 ]' Z: ]' S$ Q% {$ _##  _________________________________________
& |1 N- ?- H) A4 T% R$ E## # M8 H! F- X, |0 y& }: `" w
##  Outcome: absent 4 [( ~* V/ p" n7 B+ E( ~* |* v
##   
' f4 e7 Z5 e" a7 }  m+ M+ ?##              Updated Model
. B9 V4 K& {3 d. M## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified' t/ d2 `% U; S' h+ s5 j
##     [0,0.3)       121         4       0               3
9 P" [' w4 B- y  r2 y6 F5 q6 H% L# N##     [0.3,0.7)       1        13       1              13
; Z$ c9 _, q, I+ `$ t9 G##     [0.7,1]         0         1       3              25; s. y4 v; c7 t
##
5 O% D: W( n5 N- x##  
% j8 V7 V# n' L##  Outcome: present
( x6 W% j2 X5 z0 t1 |) G2 Q1 b# x##   
9 j* m; V4 h8 ]' f/ u1 \##              Updated Model/ S" `; i  T6 n4 o  l2 x
## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
! }; M- l9 m( B+ O##     [0,0.3)        14         0       0               0
, I6 b0 H/ V! ]# b& z9 P##     [0.3,0.7)       0        18       3              14
4 w' G! y; t6 s3 ]5 x##     [0.7,1]         0         1      52               22 j" V/ M+ _/ X3 [! L) W3 C6 h. E5 U
## / i" s4 t" u0 k  M
##  2 E! d4 H$ [$ q1 ^& {
##  Combined Data 8 I2 s: Y( ?1 |, z# e# i0 C
##     P3 c9 j% ?7 i: q. a
##              Updated Model
2 o* `2 \" I2 e; e## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified' D( \# V& ~1 D1 e
##     [0,0.3)       135         4       0               3
' N# z+ i0 ]# o##     [0.3,0.7)       1        31       4              14# d' c$ I' W0 o) G; j# ]( _! [! A+ i
##     [0.7,1]         0         2      55               45 v$ f' N! r1 L. }- g
##  _________________________________________! s1 G$ I. G& Y
## 8 Z7 e" G' B7 O/ V
##  NRI(Categorical) [95% CI]: 0.0019 [ -0.0551 - 0.0589 ] ; p-value: 0.94806 2 F6 G( @; r( k
##  NRI(Continuous) [95% CI]: 0.0391 [ -0.2238 - 0.3021 ] ; p-value: 0.77048
! V6 m& T0 R+ K' s" R##  IDI [95% CI]: 0.0044 [ -0.0037 - 0.0126 ] ; p-value: 0.28396
. p8 B; u2 b2 x' C
( s1 q8 M5 n1 K& q! P' _1 k1 F/ |4 N1
6 B* ^1 a8 ~1 ^9 T0 Y6 x结果得到的是相加净重分类指数,还给出了IDI和P值。两个包算是各有优劣吧,大家可以自由选择。
& i+ p, O& [/ H' f
& F* R+ X7 H# j5 D8 V+ c/ ]5 s生存分析的NRI2 w" c+ J6 r. |
还是使用survival包中的pbc数据集用于演示,这次要构建cox回归模型,因此我们要使用time这一列了。. v. n% F4 U1 G( Y0 `, q

) v# H$ ^/ E3 w8 ~% D4 F6 Nnricens包
! Z) B4 `7 K2 T- S& k5 z7 zlibrary(nricens)$ s3 }- V$ m" V
library(survival)) M* K. U2 f8 `

- I  h% S* _4 @: e4 rdat <- pbc[1:312,]0 V9 h6 y& P8 j- K
dat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡2 t' L6 W6 f9 @  \* {
12 _% d0 I% U0 p4 B5 ?) q
然后准备所需参数:
1 [( {3 j1 q! d" L* r. H1 x; ~" k* ]0 q- J+ N
# 两个只由预测变量组成的矩阵
3 O% R$ r5 ?6 Z  U( V8 a: N1 Qz.std = as.matrix(subset(dat, select = c(age, bili, albumin)))! t6 M) |# s8 v( `
z.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))
+ z. ], k! f1 p: C
2 D( ]! e" ^2 ^* }0 Y# 建立2个cox模型
4 A1 |0 L/ v& Hmstd <- coxph(Surv(time,status) ~ age + bili + albumin, data = dat, x=TRUE)
$ a) d3 z9 j/ E6 kmnew <- coxph(Surv(time,status) ~ age + bili + albumin + protime, data = dat, x=TRUE)
2 p7 a4 T8 `! `. F& ?
5 B" Y$ ]& c6 A# 计算在2000天的模型预测概率,这一步不要也行,看你使用哪些参数2 l# j6 l+ i+ j. M2 {
p.std <- get.risk.coxph(mstd, t0=2000)
7 r2 B; F. Z  q2 Xp.new <- get.risk.coxph(mnew, t0=2000)
2 _, m7 ~' `$ l/ g1+ ^. I9 D* Y2 r/ y
计算NRI:
# ~1 `- K5 d4 d1 f, W) c  T
' j, Q+ T. }1 Qnricens(mdl.std= mstd, mdl.new = mnew, ' g- J# l1 I9 g  {& `
        t0 = 2000,
8 P" K" C. h9 \        cut = c(0.3, 0.7),% b9 J, O  _  j0 n/ D- `" Q
        niter = 1000,
" A  a: B$ |- m1 u% y# B8 ?        updown = 'category')
( Z9 Z/ v, u( F( o7 N" I* Q
4 o0 i* q. y8 O- MUP and DOWN calculation:
0 x7 Q+ ?& p) c5 X' |  #of total, case, and control subjects at t0:  312 88 1443 E+ ~# c( j7 s5 f! u

1 X6 x. m5 ?8 J+ T9 N  Reclassification Table for all subjects:, D+ _5 k8 H5 u) E% r3 `
        New$ f: }. {  H! D3 z0 `4 @) E" o
Standard < 0.3 < 0.7 >= 0.7
7 S3 c% C/ {. y7 W$ y  ^( ?  < 0.3    202     7      0: U6 x. }' t3 _7 D# a0 V
  < 0.7     13    53      6
! `0 i' F% S& u4 u% c; P) B  >= 0.7     0     0     31
* z& D% o7 |4 D' S9 F3 T1 g6 C1 P9 {3 A) y
  Reclassification Table for case:$ Q1 ~1 o7 g" Z! d. a
        New
5 W) B6 E6 |, W( M6 u$ p; yStandard < 0.3 < 0.7 >= 0.7
! _+ k( ]* }( Q3 w: a  < 0.3     19     3      0( K: {& T( U$ j# @
  < 0.7      3    32      45 x& r) ]7 m; d( j& z
  >= 0.7     0     0     271 O' t/ E3 r+ |3 n1 ?. |7 z

; j: S4 @+ ]9 p2 M  Reclassification Table for control:
9 N4 }" ?' J! Q        New
7 X: e! X- v2 _: c% SStandard < 0.3 < 0.7 >= 0.7+ o2 y' q& D0 ^9 \
  < 0.3    126     3      01 W8 p$ w3 u% ^: m
  < 0.7      5     7      28 c; X7 Y# n! D$ V! n2 Z
  >= 0.7     0     0      1' G0 `1 U0 p( l# \/ R
( ?- m$ y: a! B  T
NRI estimation by KM estimator:2 W# _: V* U* [! M) Y' K0 T

: O. Z, b- c: q) d2 D# [" }  GPoint estimates:
- _/ M/ o. m4 X" E: \. [                Estimate
  Z8 F# B+ ^( E/ @  g! sNRI           0.05377635. q( O1 }) L; T$ ~) z' C, H  ~
NRI+          0.03748660
, Y! g  X1 C: Z+ [+ @NRI-          0.01628974
2 x/ n- Z) M! ~! K0 K3 rPr(Up|Case)   0.07708938
0 o* J# T9 X, N: C, JPr(Down|Case) 0.039602785 v  }/ A/ q1 K- w( e
Pr(Down|Ctrl) 0.042563525 w9 a7 a" o& ]
Pr(Up|Ctrl)   0.02627378- g1 G! c8 ^1 P+ Q: f# m/ V

7 e, {; j: y% d9 j  }: hNow in bootstrap..+ q; b% b/ o" f( `2 L6 S
) l3 }8 k/ ]  p& g( a/ M
Point & Interval estimates:* ~5 \, k* m( V2 D
                Estimate        Lower      Upper* Q: T- P6 O; y6 _, i0 A. j& [
NRI           0.05377635 -0.082230381 0.16058172% l0 y% C" v# }0 z# W
NRI+          0.03748660 -0.084245197 0.13231776$ D2 C- H: z+ R7 p6 w7 H3 J8 }
NRI-          0.01628974 -0.030861213 0.06753616
7 U4 X' T3 D* q5 QPr(Up|Case)   0.07708938  0.000000000 0.19102291
1 m; g3 k; Y+ HPr(Down|Case) 0.03960278  0.000000000 0.15236016
9 c8 T+ ?5 b2 A0 APr(Down|Ctrl) 0.04256352  0.004671535 0.09863170
* g* [- O7 C+ w5 |Pr(Up|Ctrl)   0.02627378  0.006400463 0.05998424
  D( o( i# }. R% {
7 Q) |7 S' D! G! E$ c4 Z7 K6 W/ c$ J1
3 M9 _. V3 Y9 B  `5 h9 H
: |" i: @. ^& I; ]" pSnipaste_2022-05-20_21-49-38
+ y/ d% F3 Y5 z- V/ w6 R/ h结果的解读和logistic的一模一样。
1 d& i0 }1 Q' g3 ]  L
# ?! b9 b- }) C1 {" zsurvNRI包
! \; Z* H6 {& O' V# 安装R包! N3 V$ a6 D4 l9 d( w  ^1 t
devtools::install_github("mdbrown/survNRI")  \( [, r, b+ ?
1) N( |8 ~0 a1 ]) N) V" d
加载R包并使用,还是用上面的pbc数据集。
7 ]% e6 n( X8 T: x7 ^. |
4 ]3 }2 ]0 C/ `! @* c4 I- |6 glibrary(survNRI)/ }. \1 O) V, @7 I/ Q4 g$ _
13 A- d6 e7 s% X* i: s3 w7 L( M# c
## Loading required package: MASS
  g8 y+ ]% u& ~1' `* e4 c" K" z5 z: k, {
library(survival)4 y& R) u$ S% H" i. U. P# _5 N' x

3 m4 Q! @% H; {4 L+ d# a) V# 使用部分数据
4 ~4 b7 c; m% fdat <- pbc[1:312,]
3 G0 ?7 q& S9 m9 C$ W# bdat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡
/ Q" T. R/ r, L: U
. N" l! K# ?  |res <- survNRI(time  = "time", event = "status", # X0 w8 ?. J- e- K/ |: W( D( D7 x
        model1 = c("age", "bili", "albumin"), # 模型1的自变量  k% m) [4 @- j; @
        model2 = c("age", "bili", "albumin", "protime"), # 模型2的自变量
. H8 K. {2 V0 A) p; K        data = dat, & r( G% y$ N# c) f% n
        predict.time = 2000, # 预测的时间点
( \1 }4 W: S( u) D7 |9 a        method = "all",
2 V! m( d4 R( I8 Z1 H1 P& u) h6 f2 i        bootMethod = "normal",  
; x$ a/ P/ @& p        bootstraps = 500,
+ {, O0 a, y4 e5 A8 w# j9 \        alpha = .05)
+ g) _! @. S! j# u: b4 ?/ I& E0 M3 b3 B2 A0 n/ [
1
# j( g) N& ?, J& B. p; t/ E查看结果,$estimates给出了不同组的NRI以及总的NRI,包括了使用不同方法(KM/IPW/SmoothIPW/SEM/Combined)得到的结果;$CI给出了可信区间。0 L' s2 S* O1 H6 ]& s

) W4 r  n6 W& Q- h3 ?8 e! i7 ^& Pres
3 q; L- Q- N9 O& k  s& I. |17 Q/ `- p( o" Q8 M+ E& x$ m
## $estimates
7 G& t( M7 w+ R1 G##            NRI.event NRI.nonevent       NRI
- {' A+ A0 Q' y  D) ]## KM        0.20445422    0.3187408 0.52319513 I9 E1 N) I$ D% F: Q
## IPW       0.22424434    0.3273544 0.5515987
' H& }5 M8 o# M## SmoothIPW 0.19645006    0.3144263 0.5108763
; p) {8 p* o$ ?## SEM       0.07478611    0.2632127 0.3379988
. A3 c/ x2 C" c1 S) [# K6 l/ O# e## Combined  0.19633867    0.3143794 0.5107181
* i  K5 I. x* {. M, Y( ?/ e##
. h5 S: h0 a+ J+ f- M8 q## $CI
: h% J9 ~; ]& C6 Q## $CI$NRI.event1 `/ Q; q/ f( u- n6 _0 s' g
##                     KM         IPW   SmoothIPW        SEM   Combined
4 T( M8 _: n6 h8 ^. A5 K. e## lowerbound -0.03915924 -0.02185068 -0.04724202 -0.1162587 -0.0473723" l8 A5 h& N  M2 V
## upperbound  0.44806768  0.47033936  0.44014214  0.2658309  0.4400496/ x+ y+ E* l+ V) h
## 8 b5 ~$ J' d3 C7 o/ k+ ?
## $CI$NRI.nonevent4 \1 X, G' @3 X& U
##                   KM       IPW SmoothIPW        SEM  Combined2 ^6 I: s( J7 M8 K; Q; f* `( V) T
## lowerbound 0.1317108 0.1396315 0.1286685 0.08638933 0.1286426
8 n  S. @7 Q5 H# I7 d5 M## upperbound 0.7102251 0.7393216 0.6966341 0.51482212 0.69645497 B& y( ^3 z9 K; W- R/ A" x
##
6 |# P" q* t6 z$ I2 h& C( v## $CI$NRI1 r4 ~  ~/ h: v$ T
##                     KM         IPW   SmoothIPW         SEM    Combined8 j! h. V7 l; V. T4 C) b7 M
## lowerbound -0.05112533 -0.04569046 -0.05439863 -0.04132364 -0.05443409% l# [: x7 @; G! ~- f) Y
## upperbound  0.89306122  0.92464359  0.87970125  0.64253510  0.87953153' K; g- |' {+ r) z
## . f- q0 F" ]8 ]3 u
## 8 O! c* }' @) I# q- g% Y
## $bootMethod
7 X" Y! s5 r% n- H4 ?! k* O% i## [1] "normal"
. K! w2 z% {: V##
7 J4 ?8 k7 K% P+ _  F3 y## $predict.time
- X8 K: }$ u' k5 M0 v# d: N## [1] 20009 g, a! R$ i( W9 V: q! @: q
##
0 V+ e  U/ Z! g' R" d## $alpha
- D, x$ ~2 {% A8 s" c' v## [1] 0.052 _" \) O" z" M5 W, Y8 Z& V
##
  m& M. ]; I3 x) H6 O## attr(,"class")* E% T# L5 w0 E3 }7 L0 U& ~
## [1] "survNRI"
# j% t$ i3 X  q2 d
. u) f( f0 G0 k0 z+ ?1
7 l0 _+ i: F+ ?9 {6 L( U1 v( HOK,这就是NRI的计算,除此之外,随机森林、决策树、lasso回归、SVM等,这些模型,都是可以计算的NRI的,后面会继续介绍。大家如果有问题欢迎在评论区留言。
* \2 I/ b! H' ?! J' ^, L" e8 {3 X" P+ [( t/ p: ?- g
本文首发于公众号:医学和生信笔记
3 e9 B7 ?& n7 p2 J' O+ U' y+ d' r8 `6 n$ }, l' q9 y, x1 o
“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。
5 s$ I9 H3 r: l  z本文由 mdnice 多平台发布& E( s1 A+ d* N! Q+ O9 i4 M
————————————————* ]+ F9 I3 m$ B: p
版权声明:本文为CSDN博主「阿越就是我」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
* `3 Q& o# k3 T' @3 h- W$ X原文链接:https://blog.csdn.net/Ayue0616/article/details/126768006. y3 |' s" E4 H3 U
3 `& i' [3 S( ]* e* r( n  h# ?
4 E8 H! p" _5 J7 s





欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5