数学建模社区-数学中国

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

作者: 杨利霞    时间: 2022-9-12 18:43
标题: 净重新分类指数NRI的计算
3 ~( a) a8 W. h1 F% @0 ]; m5 \
净重新分类指数NRI的计算
# J7 @: J" w6 A2 j! P“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。- x% w, z" P. A/ S5 u; D2 t6 d
NRI,net reclassification index,净重新分类指数,是用来比较模型准确度的,这个概念有点难理解,但是非常重要,在临床研究中非常常见,是评价模型的一大利器!" c6 G# K2 r0 [6 k$ P  F8 |- u( P
0 J' y  A. r2 [6 Z
在R语言中有很多包可以计算NRI,但是能同时计算logistic回归和cox回归的只有nricens包,PredictABEL可以计算logistic模型的净重分类指数,survNRI可以计算cox模型的净重分类指数。
' |, m* n% P: ^
; ~0 d% `- o' ?" nlogistic的NRI
/ l- `# ^4 l5 g. e. I+ onricens包& N. o4 X0 b$ L
PredictABEL包
0 X  p! T& w- P- V+ [- Y/ y生存分析的NRI
$ Y) N) t% \6 D9 `3 ^; onricens包+ [2 ]- j  t6 M& Z8 S: N# j
survNRI包
3 p1 m  K6 D9 S* }& f& k: slogistic的NRI0 c7 X- X$ J; `* d
nricens包- I& T' N  a4 g1 i: R
#install.packages("nricens") # 安装R包# `& P% i# s# z
library(nricens)
! N! P# C) m4 a' t/ [1
: w  u0 ]$ O9 ?  z( [: d## Loading required package: survival, `, n6 S# F& q4 b- l& r& B& @- D3 e
1
* Q7 Z% d6 d. y使用survival包中的pbc数据集用于演示,这是一份关于原发性硬化性胆管炎的数据,其实是一份用于生存分析的数据,是有时间变量的,但是这里我们用于演示logistic回归,只要不使用time这一列就可以了。8 ]0 m$ X4 ]6 s1 w/ e2 H+ s) i
! p# \# ?; Q1 ^
library(survival)4 f! p4 k; p# \# P5 Y
% \3 y# ?6 Z. T* Z) [
# 只使用部分数据. |, `4 D+ W9 n
dat = pbc[1:312,] ! r+ m+ N/ s- B# ]) l
dat = dat[ dat$time > 2000 | (dat$time < 2000 & dat$status == 2), ]; z% }/ k% X0 K
* @- l$ O* l: X
str(dat) # 数据长这样7 ]. n( _1 M3 i$ j9 z2 H
1
4 |0 o  W0 T6 b, o## 'data.frame': 232 obs. of  20 variables:9 K: e  D' Q* F% D
##  $ id      : int  1 2 3 4 6 8 9 10 11 12 ...
0 B+ z1 S" s9 Y  B##  $ time    : int  400 4500 1012 1925 2503 2466 2400 51 3762 304 ...% u+ K) a' D" {9 J/ _. d
##  $ status  : int  2 0 2 2 2 2 2 2 2 2 ..., M5 M+ }* i" M+ j/ w! {
##  $ trt     : int  1 1 1 1 2 2 1 2 2 2 ...! K& v: f) K; A+ U. {1 R
##  $ age     : num  58.8 56.4 70.1 54.7 66.3 ...0 ?; G: \' @3 D
##  $ sex     : Factor w/ 2 levels "m","f": 2 2 1 2 2 2 2 2 2 2 ...
, M. Y1 h2 S) C) w. k% f##  $ ascites : int  1 0 0 0 0 0 0 1 0 0 ...
- W4 \6 v0 q$ U% v4 c##  $ hepato  : int  1 1 0 1 1 0 0 0 1 0 ...
& e8 `& z/ X, _4 [8 S##  $ spiders : int  1 1 0 1 0 0 1 1 1 1 ...
" A3 m7 [+ q- a##  $ edema   : num  1 0 0.5 0.5 0 0 0 1 0 0 ...
& Q4 A3 }6 g2 w& X% U, N3 m5 J##  $ bili    : num  14.5 1.1 1.4 1.8 0.8 0.3 3.2 12.6 1.4 3.6 ...# a9 {$ J1 \6 U
##  $ chol    : int  261 302 176 244 248 280 562 200 259 236 ...) e6 P) `5 T' A. f: x" K' H
##  $ albumin : num  2.6 4.14 3.48 2.54 3.98 4 3.08 2.74 4.16 3.52 ...2 Y! p% ?+ {5 i7 n- M# ~; W
##  $ copper  : int  156 54 210 64 50 52 79 140 46 94 ...& n8 y0 @: s# O8 m# t9 p) H
##  $ alk.phos: num  1718 7395 516 6122 944 ...0 K" I6 i& ]3 g$ |4 C
##  $ ast     : num  137.9 113.5 96.1 60.6 93 ...- Y5 a5 v) P; f' i
##  $ trig    : int  172 88 55 92 63 189 88 143 79 95 ...
/ T* m' n. S' x5 N7 s##  $ platelet: int  190 221 151 183 NA 373 251 302 258 71 ...
9 {4 ?1 v4 H0 g2 ~. Y##  $ protime : num  12.2 10.6 12 10.3 11 11 11 11.5 12 13.6 ...9 b; [+ M: d' ^; e# d* J3 B
##  $ stage   : int  4 3 4 4 3 3 2 4 4 4 ...9 h7 e' S) n2 ^9 F$ @
& Y6 s) |% y6 e" ?* Z6 s7 @- ^
1# f2 s; N$ w9 Q  w7 z+ u
dim(dat) # 232 200 z3 o2 ^" |8 ~, w
1
& p1 X3 P; f" T6 h3 v) t; D- D3 A## [1] 232  203 N) l, Y# b  d. S' Z
1
1 ^6 F! T  g5 D  l6 b( ^6 H1 u然后就是准备计算NRI所需要的各个参数。
4 u' y. G2 h* k" x$ E0 {8 P2 x
# 定义结局事件,0是存活,1是死亡% `$ z' m3 h! `5 }0 P6 K
event = ifelse(dat$time < 2000 & dat$status == 2, 1, 0)/ V3 i$ [* S  G$ p1 \. i2 y  K

( W. h5 D* i1 S; o2 g3 R, P8 i" u1 L# 两个只由预测变量组成的矩阵
: J! U% c4 [- C) }7 ^9 k7 \z.std = as.matrix(subset(dat, select = c(age, bili, albumin))); x! j3 J; A( I
z.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime))): n3 n/ g/ G0 T, g) i( P, n; f" A

1 x$ e" Z4 M8 j' a# 建立2个模型! o9 ~% D7 W* P% @3 F
mstd = glm(event ~ age + bili + albumin, family = binomial(), data = dat, x=TRUE)8 }6 ?3 N& `  ~+ D* {
mnew = glm(event ~ age + bili + albumin + protime, family = binomial(), data = dat, x=TRUE)! d. o8 ?  i0 _) {4 ^. h

- c* A& E3 m" N7 `/ n0 z( ?( n# 取出模型预测概率3 p9 M$ m( s2 x" Q6 Z5 p2 G
p.std = mstd$fitted.values7 l: A$ `7 G3 I3 c+ Z; P
p.new = mnew$fitted.values. \# I9 H  D5 {) r8 X+ m5 z2 a" M
/ i  K3 I. R; x
1; f6 e3 n% M" c
然后就是计算NRI,对于二分类变量,使用nribin()函数,这个函数提供了3种参数使用组合,任选一种都可以计算出来(结果一样),以下3组参数任选1组即可。 mdl.std, mdl.new 或者 event, z.std, z.new 或者 event, p.std, p.new。) r0 Z+ ]% P$ |& F7 @$ x

) p, S+ t  h6 ]) X; f# 这3种方法算出来都是一样的结果
. k7 i: `$ h  ?7 ~. V* Z- p" X" x* G) I
# 两个模型8 v( ~8 j, W* a, I
nribin(mdl.std = mstd, mdl.new = mnew, ! A  k& `4 E7 |4 U; `
       cut = c(0.3,0.7), 8 o; H( {0 T7 E  x: H4 @( w9 z
       niter = 500, ( s" O/ C4 ~% E- ^. R. h
       updown = 'category')- m6 t* C, b7 f, ]& Q- m' U
$ F! o" H, o: _: {1 x
# 结果变量 + 两个只有预测变量的矩阵
* B% C/ J* F# I3 Fnribin(event = event, z.std = z.std, z.new = z.new,
/ w: D4 v: q0 w& C# p# {       cut = c(0.3,0.7),
- d) ^" v' ]+ m9 i# b) U  ~% V       niter = 500,
, e% k% D" G# i, z) o# l( @' L       updown = 'category')9 q* R9 x& J% h  f- b) o. t

& Y, J7 ~# x8 a/ j, _## 结果变量 + 两个模型得到的预测概率
5 h( o; i1 H4 A  J& Bnribin(event = event, p.std = p.std, p.new = p.new, 2 Q, ^! J1 }- t% P6 w9 u
       cut = c(0.3,0.7),
4 C8 s; i3 V+ |9 m% x       niter = 500,
' H4 W* R! V! u: Z3 k       updown = 'category'), ^. t8 t: u$ m' I, D4 f
( D, T! f8 e0 J1 H
1
7 j( H, F# G( @# `9 a, ~+ [3 V其中,cut是判断风险高低的阈值,我们使用了0.3,0.7,代表0-0.3是低风险,0.3-0.7是中风险,0.7-1是高风险,这个阈值是自己设置的,大家根据经验或者文献设置即可。9 p% F8 J0 u5 q1 O- g# r

' \) b* t( C" [. Oniter是使用bootstrap法进行重抽样的次数,默认是1000,大家可以自己设置。
& z( y+ D4 a+ c: A, s$ ~3 r4 t8 E
* Z5 v1 d9 R1 ?+ D; X7 xupdown参数,当设置为category时,表示低、中、高风险这种方式;当设置为diff时,此时cut的取值只能设置1个,比如设置0.2,即表示当新模型预测的风险和旧模型相差20%时,认为是重新分类。
, _% |1 S1 p2 K) |: W3 p9 Z# `3 Z7 {/ j4 w/ |  p+ b) t, a* R* y$ ^: t6 U) |
上面的代码运行后结果是这样的:$ j6 }5 E( Z) X) c) Y

2 d3 X. n% \! X! Q- pUP and DOWN calculation:
  I% c9 l& r5 a+ S  #of total, case, and control subjects at t0:  232 88 144# w- M# E+ e- n7 Z( A
9 E1 ~/ c  ~: t0 d
  Reclassification Table for all subjects:+ \3 g3 B5 `3 R
        New
. ~/ D1 {- h0 h8 p+ tStandard < 0.3 < 0.7 >= 0.7
* p  |+ x4 s' q2 Y6 \3 n  < 0.3    135     4      08 ?2 d) ~- M" e7 y3 E
  < 0.7      1    31      4: K- [4 M/ W6 Y
  >= 0.7     0     2     55
: G6 j7 E( l/ |% T7 C* V9 {/ i, w8 D# C$ U/ ?# s2 Y- q" }! G" s+ s
  Reclassification Table for case:; i4 j2 M6 b& z) q/ s# ]
        New1 h* u  I7 m5 F9 Q/ ~
Standard < 0.3 < 0.7 >= 0.7
4 |/ t  p/ F) C  < 0.3     14     0      0
6 }# F& G) m& c1 l& K  < 0.7      0    18      3
) C5 S) ?1 I$ S3 e/ N  >= 0.7     0     1     52
& J' d6 M9 x2 \* z7 C9 b
. n- {1 W+ F& J$ K) |2 J8 J  Reclassification Table for control:2 d0 v4 R* c/ ]- v
        New: w( q. E% r( W5 ^# z: Z! j, w: R; U
Standard < 0.3 < 0.7 >= 0.7- S4 I, U9 B! P' x  y1 u- z7 U$ ^* c
  < 0.3    121     4      0$ C7 K6 F7 ~% _) W# _% S* p
  < 0.7      1    13      1
: d+ i- E7 F+ C$ _, p# G  >= 0.7     0     1      3) f; o1 {* m& J  V* r4 b
7 R  a/ H9 K; q: ^/ u0 F* E. Y
NRI estimation:5 i1 N! V$ d8 a9 S" V! m5 d
Point estimates:) |& v" Y* F/ ~6 \" _+ d
                  Estimate
% \4 v, d; p2 y+ o$ [" bNRI            0.001893939: F6 u: }+ r; c8 w
NRI+           0.022727273
4 e( K- ^/ x" YNRI-          -0.020833333
# E! m- t. N! S5 A: ZPr(Up|Case)    0.0340909096 h0 c. ]& N+ t6 e5 \+ M
Pr(Down|Case)  0.011363636
3 i; X* q& n% v  w8 XPr(Down|Ctrl)  0.013888889
) Q* S, }7 W" i, y# z1 c4 VPr(Up|Ctrl)    0.0347222223 E- Z$ x% B. u$ P' t6 ?

; H" g+ x2 I( kNow in bootstrap..
: ~' Q  ]% f" K5 W3 E
# r2 J/ Q8 m$ W1 s7 r& sPoint & Interval estimates:
3 W. G" ~" ^7 @7 X) z& R6 m, D                  Estimate   Std.Error        Lower       Upper, u! o/ O5 [+ s8 z, T5 }! m% Q
NRI            0.001893939 0.027816095 -0.053995513 0.055354449
& c( a/ l, B! m2 u# G+ Y" ?" V  a& R% B+ xNRI+           0.022727273 0.021564394 -0.019801980 0.0657894745 t* L! X4 [4 G& j" ~
NRI-          -0.020833333 0.017312438 -0.058823529 0.007518797
& g+ b$ h9 \; W0 U3 HPr(Up|Case)    0.034090909 0.019007629  0.000000000 0.072164948" [. O4 _7 y$ b
Pr(Down|Case)  0.011363636 0.010924271  0.000000000 0.039603960
: v5 ?/ f5 e: nPr(Down|Ctrl)  0.013888889 0.009334685  0.000000000 0.0352112683 p( R3 g; I" _; L  T9 {$ f
Pr(Up|Ctrl)    0.034722222 0.014716046  0.006993007 0.0661764718 Y, O. n! Z- U9 i( G" t4 Y
$ i1 [( t- V- X) {  t
1
! l" y0 _$ P4 A$ N% ]! U) e! f首先是3个混淆矩阵,第一个是全体的,第2个是case(结局为1)组的,第3个是control(结局为2)组的,有了这3个矩阵,我们可以自己计算净重分类指数。" F2 S  z/ T  X3 o: B

9 ]2 C9 a" @- h- r: n0 s& D看case组:  y. V* [4 a% y- n8 R

7 ?4 s# e. M) q* [净重分类指数 = ((0+3)-(0+1)) / 88 ≈ 0.022727273
! b9 B+ z6 ~" z' V% ~! j) ^# C, v  U: x  Y
再看control组:
8 s$ R! w8 j9 g# N9 w/ B3 `0 t' F
净重分类指数 = ((1+1)-(4+1)) / 144 ≈ -0.020833333  a" g- Q4 R8 Q+ G$ C- e

9 G6 M8 [1 o  {1 [& `* X9 b相加净重分类指数 = case组净重分类指数 + control组净重分类指数 = 2/88 - 3/144 ≈ 0.000315657
$ N* o  e* ^9 F
2 e! r$ p/ u2 e; s4 \  g2 M再往下是不做bootstrap时得到的估计值,其中NRI就是绝对净重分类指数,NRI+是case组的净重分类指数,NRI-是control组的净重分类指数(和我们计算的一样哦),最后是做了500次bootstrap后得到的估计值,并且有标准误和可信区间。0 Q4 \2 b- T5 }2 y1 T
' U$ M4 j0 u# d. f1 p- n
最后还会得到一张图:
4 V- J. N: G: L! g1 v! F7 N% U' u+ m( s' O& d" F, U8 L8 v2 {
这张图中的虚线对应的坐标,就是我们在cut中设置的阈值,这张图对应的是上面结果中的第一个混淆矩阵,反应的是总体的情况,case是结果为1的组,也就是发生结局的组,control是结果为0的组,也就是未发生结局的组。
4 X& \4 {- E6 j/ g3 n" @  g
0 K- X; M$ ]- `  n1 ^2 zP值没有直接给出,但是可以自己计算。! l# `" z6 q# E/ W( `+ B3 @7 o
; N. a! K- a  l! D* D" K8 S( h
# 计算P值
: p3 s, w  M# h* a* x) U+ oz <- abs(0.001893939/0.027816095)
# _4 k+ \9 X5 R3 E' Kp <- (1 - pnorm(z))*2
4 V% [+ f2 n. t% t( b7 [2 n: Kp! p' C  v: j' A! A# m* w' n, h
1
6 |; `' T* U! P# m## [1] 0.9457157$ S  A& k# j. Z5 o: ^3 Q1 @6 O( M2 e
1
1 r+ d+ ?7 c/ FPredictABEL包! i$ ^$ V' P# K5 c* f' ]5 o7 B
#install.packages("PredictABEL") #安装R包3 u+ X9 P" p) K7 I# r2 X1 E4 E
library(PredictABEL)  , }0 n/ q) R4 W7 i
7 x4 m1 ~: ^# _9 u4 g
# 取出模型预测概率,这个包只能用预测概率计算# {0 o/ ?1 h+ n( T3 f
p.std = mstd$fitted.values7 R  D4 d/ I; N, z3 Q
p.new = mnew$fitted.values 2 a# q6 X' j( n# @! ^5 L3 W
14 u" O" S6 f# d# T0 \% L! v
然后就是计算NRI:# c" \' ]" ~! D( J1 Z

" q# u: C2 e/ u' \dat$event <- event
6 @' g# K0 R4 S# e% d
+ g. r4 a) @1 @: k- jreclassification(data = dat,' D2 o+ {" L  Z) |/ V" y' v1 w+ C
                 cOutcome = 21, # 结果变量在哪一列2 Y' t+ a7 {. A8 P2 g( S$ h( W
                 predrisk1 = p.std,$ I2 h: A* y+ E9 Y' ?1 F8 ~/ F1 r
                 predrisk2 = p.new,
( n& \2 b2 H# {. }8 r9 [  i                 cutoff = c(0,0.3,0.7,1)
8 r0 d- y# k( m: m9 S3 H+ G+ u                 )
/ X. V3 F1 B" y; L# q' |" \, ~3 j! [1
7 f! X" g5 s6 E' g##  _________________________________________
3 Z2 a8 A) |" }1 b##  7 n. t2 U/ P! c# \7 s3 _  j9 N
##      Reclassification table   
% w1 l2 V( D1 j: Y+ Y##  _________________________________________, E. |  r$ _+ h
##
0 z+ p+ |' C* S. \: S4 f  R##  Outcome: absent
# q5 u5 Y& f# ~##   
9 i' J5 y: A8 m7 ?' U# n) y##              Updated Model+ f7 X) g) W4 f5 s
## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified7 \; v3 k  F- D
##     [0,0.3)       121         4       0               3
$ d. A# q0 h5 O##     [0.3,0.7)       1        13       1              13: D6 D0 l5 E" u/ K* m0 N
##     [0.7,1]         0         1       3              25
2 f5 E+ O2 O4 v( A## / z+ u% u: A7 _6 r
##  
3 |$ J& ~; P6 Y##  Outcome: present + c5 a5 i" p! Q2 f
##   + e6 w+ ^8 a' ?  ~9 u
##              Updated Model
/ q. {8 n1 p1 i/ d6 ~- r) X## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
* ~% K$ a6 J. a  a6 S! P1 ^##     [0,0.3)        14         0       0               05 h" z" N5 j$ N0 \
##     [0.3,0.7)       0        18       3              14
' \2 ~2 G6 U3 ^##     [0.7,1]         0         1      52               22 D# [/ O: G* I5 H7 z
##
# M0 r, d, A( a8 o6 e% |##  - M) d# r5 S  f/ K' M# z
##  Combined Data 3 Q6 r5 G9 B6 q
##   % B7 a. q6 E+ b5 V
##              Updated Model
$ B/ S$ [- s; D( e3 F' m## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
# }+ o/ c3 S. v  k/ e# l##     [0,0.3)       135         4       0               3) i# z9 S* C# N7 s0 I7 s) n5 ~
##     [0.3,0.7)       1        31       4              14. y  p: [- y7 u, @1 _3 \
##     [0.7,1]         0         2      55               4; r$ t; z  L9 ]
##  _________________________________________8 }& u- z( O* Y3 @+ ^5 \' T
## ; ], P3 J. K2 O7 O; k9 [# E& u, p
##  NRI(Categorical) [95% CI]: 0.0019 [ -0.0551 - 0.0589 ] ; p-value: 0.94806 7 x  ^' c) h, a
##  NRI(Continuous) [95% CI]: 0.0391 [ -0.2238 - 0.3021 ] ; p-value: 0.77048 # D% p" s; o7 m, X8 a
##  IDI [95% CI]: 0.0044 [ -0.0037 - 0.0126 ] ; p-value: 0.28396
) a% z$ ]- I3 b5 ^/ J+ J6 \8 N: m! q0 c
# d1 s* T8 B. O3 B+ `1* u2 |/ M1 |' I# Q
结果得到的是相加净重分类指数,还给出了IDI和P值。两个包算是各有优劣吧,大家可以自由选择。$ W9 j0 ~1 C% M4 {8 h% A6 B
& _/ Z  t9 C) [1 C  @5 J
生存分析的NRI
4 v" k7 u! S1 X# M( H; t/ c  }还是使用survival包中的pbc数据集用于演示,这次要构建cox回归模型,因此我们要使用time这一列了。: H1 E6 w3 z* N

& F0 D( j2 k9 D# Hnricens包
9 z2 |" s8 H2 M. ~6 ?# Ulibrary(nricens). x  m: ^$ k& W2 i/ ^3 Z: |0 s; E5 a" r
library(survival)
" y: F2 T7 C1 @# D
& Z( }0 s3 H  s) \3 c3 cdat <- pbc[1:312,]1 }" ]- [) X4 e/ L
dat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡# |4 z: E8 C& A! \4 `- }) J0 U
1
+ Q" |. z8 d4 i# i4 B0 Z; }. k6 ^$ G然后准备所需参数:: E4 e& i- |$ _" X8 R
$ p+ g  Q; o3 v0 x7 r" u# Z
# 两个只由预测变量组成的矩阵
; K! F! p) ?& l, B  h- n: Hz.std = as.matrix(subset(dat, select = c(age, bili, albumin)))0 j0 e  b9 F# ?* d) j# D6 V
z.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))
8 [7 w" E! ~# b# }6 k+ F* Y( i1 A; i  p. Q. k
# 建立2个cox模型+ I  I! P2 I9 M9 J$ B  n
mstd <- coxph(Surv(time,status) ~ age + bili + albumin, data = dat, x=TRUE)2 V; A9 w% P% A" i
mnew <- coxph(Surv(time,status) ~ age + bili + albumin + protime, data = dat, x=TRUE)- ~3 f, w% w8 h+ X# q! p, g- b3 M
* `6 i0 a7 z  J( W* k
# 计算在2000天的模型预测概率,这一步不要也行,看你使用哪些参数3 Z) b, P7 m& \) S/ S5 m3 u* A5 o
p.std <- get.risk.coxph(mstd, t0=2000)
; Z& C5 X+ O8 W& B' k0 n) Up.new <- get.risk.coxph(mnew, t0=2000)) s8 a: L9 ^' i( i5 V
1
: w; L( f+ {+ I) {. f# N! E( U计算NRI:
+ d& z& e+ p, R2 r$ t: S2 y
9 w" Q. V0 N& A# u: I8 S4 a8 W# ynricens(mdl.std= mstd, mdl.new = mnew, 5 q6 ^# |% N9 r# X2 V( B
        t0 = 2000, $ l$ u' N) q- H' C1 A1 W
        cut = c(0.3, 0.7),6 o+ r5 ?* c( N1 _9 ?2 o
        niter = 1000, 1 |1 p7 x4 {0 b5 Q/ j& Z- L
        updown = 'category')6 k9 o- F1 @9 {4 X$ O

8 }/ e) O  H2 V% q  V* [UP and DOWN calculation:" t+ O5 k2 o2 Q1 R' g& Z. @: `
  #of total, case, and control subjects at t0:  312 88 144; o  b( @4 F0 X/ g

2 f) q% ]3 |) ?5 p. ?  Reclassification Table for all subjects:
; V' |7 Z: \! e* {        New
$ Y! r% f( p% r  y& E3 @Standard < 0.3 < 0.7 >= 0.7
# c5 }' b; w3 s) [% n2 `* W3 l7 V  < 0.3    202     7      0
9 J8 _1 x* M8 f. S  < 0.7     13    53      6* F2 J5 u% T' ^' Z6 \4 B( Y2 X0 S0 P  O
  >= 0.7     0     0     31
* h( @+ u3 f3 i1 i7 ?9 S2 t1 O; n( W1 Z$ g( v- n
  Reclassification Table for case:
) O) m# [" Z5 P- {' C" y        New
  k5 s: Y6 c3 ~* g" r7 ~6 g5 @Standard < 0.3 < 0.7 >= 0.7
4 I5 Q; ~* @$ i; N) X  < 0.3     19     3      0& @' u/ N2 n: q( {  F0 f9 K6 a
  < 0.7      3    32      4
9 q/ T% @) k4 E0 }  >= 0.7     0     0     270 i4 j' a6 S$ w4 t' g$ Z

: w' W, b; j7 \" \  V  Reclassification Table for control:
+ g0 Z) S  `2 i1 t. R8 I: s0 S& k        New
" b/ o, a8 y- OStandard < 0.3 < 0.7 >= 0.71 \1 X0 g# X+ Q; ^$ [1 l9 r* ~
  < 0.3    126     3      02 f8 T+ M( v' ~" b$ w
  < 0.7      5     7      2
) ?5 A, m9 T& j8 Q  >= 0.7     0     0      1! j; c+ s" R3 n) p( h

5 s+ c9 x1 l  x7 m8 V; ANRI estimation by KM estimator:
* H. t/ W. f2 ?5 Q) ]7 i4 Q% d
# E$ a3 E8 j0 x: O! @# ]5 p& zPoint estimates:4 B) T7 ?, _9 M5 g4 A1 ^
                Estimate
0 w& x+ p1 T" A, B5 E0 TNRI           0.05377635: S* }, h. W/ r  B7 j
NRI+          0.03748660
% J1 }/ o# K7 h) J( lNRI-          0.01628974
) H7 E* P5 C& F8 x1 e4 B! ZPr(Up|Case)   0.07708938
# E, ~: w; n( e( x7 o$ XPr(Down|Case) 0.03960278* f9 n/ Q1 x4 Q5 H& i) D& U# K
Pr(Down|Ctrl) 0.04256352  W7 @6 Q' r$ {; [) r
Pr(Up|Ctrl)   0.02627378
( K# U/ J, L) ~  d( v" r3 ^3 q6 \5 F2 E) ?. D0 A8 |' a
Now in bootstrap..
% s. X# }5 g3 \4 j
# S1 R" H0 v( D+ rPoint & Interval estimates:* O0 y! m2 o2 x) b6 \  I
                Estimate        Lower      Upper
$ R+ Q- I. \9 t+ Y7 ?& r+ P; QNRI           0.05377635 -0.082230381 0.16058172- \- I2 ]. {5 X* H7 |& m
NRI+          0.03748660 -0.084245197 0.13231776% V( \/ R* Z9 T3 q% u4 {' X# X
NRI-          0.01628974 -0.030861213 0.06753616
3 d  L& X! w; e/ Q, @  @Pr(Up|Case)   0.07708938  0.000000000 0.191022913 q- d/ q6 [6 x0 C) }& k
Pr(Down|Case) 0.03960278  0.000000000 0.15236016
1 p% E! C- r& n6 d0 c0 R2 Z7 q" V$ v9 @Pr(Down|Ctrl) 0.04256352  0.004671535 0.09863170
( U) `- n: _7 x' Q3 Z4 \) APr(Up|Ctrl)   0.02627378  0.006400463 0.059984249 |/ F- `- X9 J; L& y

- G  s# u6 X3 Y* ?% n2 X1
9 v) x7 |# B2 p3 j3 U( }0 V! w$ h
- @/ f  v& _2 M0 FSnipaste_2022-05-20_21-49-388 Q) l: f' U, ^- B& ~: g
结果的解读和logistic的一模一样。
7 J! r# j# A! Z* Y. M; S" g! y
' _2 v( }! O1 u  \- Q3 BsurvNRI包+ i( h% c8 c6 L" J1 b0 g  w% y+ K6 B# B
# 安装R包$ }! J  w7 X/ W
devtools::install_github("mdbrown/survNRI")
( \; |! B8 e8 V16 u" {. \+ Q; u% x" v3 O5 J$ l+ P
加载R包并使用,还是用上面的pbc数据集。
/ }  B, P! O" B$ h
: G0 }8 J, ]& D  c& Elibrary(survNRI)# f9 v4 H( R8 R( r3 D- t) w
1
' Z" @- e, a/ F% d3 z## Loading required package: MASS
- Y: T' l* E5 z5 r& K. G12 t& ]1 z; M0 A# G  J3 o
library(survival)
4 b" e2 H! n6 G# I0 y  _% o
( m  O  ]: P) G# R* l8 q0 m# 使用部分数据
/ c7 j5 Y0 F: w8 _" Xdat <- pbc[1:312,]0 F" v% N+ Z" Z% s% l
dat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡. Z1 _8 G" v4 Q) }# G# {8 N" n
6 Y: R( O  w6 {/ F
res <- survNRI(time  = "time", event = "status", * l8 C* O$ Q5 {* }7 p( ^
        model1 = c("age", "bili", "albumin"), # 模型1的自变量* j; l$ k  F5 f1 o; O
        model2 = c("age", "bili", "albumin", "protime"), # 模型2的自变量
4 t. S7 P4 g6 \* P0 H        data = dat, , X: L# J/ l$ P5 S5 D
        predict.time = 2000, # 预测的时间点; w* |$ x) {) F1 Y# n6 s: y
        method = "all",
! e4 v8 M! K& a$ S        bootMethod = "normal",  
, u2 ?, {+ }! i7 C* G        bootstraps = 500, 3 l6 x. K( }" P4 E" b5 S
        alpha = .05)$ ]8 t' R, [( s
( x( a$ [+ h! Z9 D' J! R5 S# C
1
# _" u7 ]2 ^% y& p- o  q; n查看结果,$estimates给出了不同组的NRI以及总的NRI,包括了使用不同方法(KM/IPW/SmoothIPW/SEM/Combined)得到的结果;$CI给出了可信区间。
, g! q- Q  g2 \! Y# E
9 o- n5 z- s! E* y8 Eres
8 G; l4 X3 f0 m* q0 A1- Z. a' c1 e4 @" i# ?4 e9 i: f
## $estimates
: a3 \4 X' E6 c##            NRI.event NRI.nonevent       NRI
+ D6 G, T, L. T% g; d## KM        0.20445422    0.3187408 0.5231951
' E- _& @! `! z5 Z+ i! c& Y## IPW       0.22424434    0.3273544 0.5515987+ {& W4 K9 x9 T* w# u; M; L* a
## SmoothIPW 0.19645006    0.3144263 0.5108763
2 A7 R+ @7 `6 m& \3 e9 d% o' A1 W## SEM       0.07478611    0.2632127 0.3379988" ^- {4 C* `1 K6 q5 j/ ?( D1 u
## Combined  0.19633867    0.3143794 0.5107181
' \# A9 D' Y  X7 I* E##
# z! C" [3 H6 x. g; c5 Y## $CI
# n, n+ J8 L+ S5 w3 p' U  k## $CI$NRI.event/ P. X( T' y$ k
##                     KM         IPW   SmoothIPW        SEM   Combined
" {8 `# f3 K* |- {## lowerbound -0.03915924 -0.02185068 -0.04724202 -0.1162587 -0.0473723
3 L8 D4 K: m7 l" s## upperbound  0.44806768  0.47033936  0.44014214  0.2658309  0.4400496
- P9 r+ w/ ~/ z* ~% \1 w##
. T- K. B3 }: w! y; M' E## $CI$NRI.nonevent
: Z8 a- B2 c, Z( c& V) I8 @. i##                   KM       IPW SmoothIPW        SEM  Combined
! U* j; d  D" L## lowerbound 0.1317108 0.1396315 0.1286685 0.08638933 0.1286426- \: a- G% E, t
## upperbound 0.7102251 0.7393216 0.6966341 0.51482212 0.6964549
0 z1 C' i: T: n1 y##
: X% I! t  r) W$ N& F" G7 D## $CI$NRI# R" y; t+ z8 q9 b5 Z. d
##                     KM         IPW   SmoothIPW         SEM    Combined
) t/ v4 w7 @( ?3 @7 z" y2 L## lowerbound -0.05112533 -0.04569046 -0.05439863 -0.04132364 -0.054434095 ?% W* _+ H2 ^0 t6 Y: C, f, e, ?
## upperbound  0.89306122  0.92464359  0.87970125  0.64253510  0.879531538 ^7 r3 n0 g; y& U- P3 P
## 8 B8 y2 Y# q7 |
## $ B& t" H3 }  z1 \" X' j
## $bootMethod3 ]- D. n. D' s. d
## [1] "normal". z+ ^1 x8 ?* h$ q% @; L
##
2 q  S6 l( m8 O9 i+ e- O% J## $predict.time
9 ~. Q- N; ~$ i# l& n; ~, N  o* W5 F## [1] 2000
7 ?1 M  x3 E! d/ I% ^' i, Q##
: _2 K2 C) \. n3 @## $alpha
+ l5 o: O) l; _- ?, c## [1] 0.05# N0 S: L6 k4 T
## $ P4 B3 K7 T( h
## attr(,"class")+ G( R3 \; y3 Z1 N' d' S- T& Z* b# U. Q
## [1] "survNRI"
% L8 }+ ?1 k$ X( B# w, ]8 X
- d) Y! _: z, G$ `" a% p  m1. J$ X! _" V1 z6 i' f/ i
OK,这就是NRI的计算,除此之外,随机森林、决策树、lasso回归、SVM等,这些模型,都是可以计算的NRI的,后面会继续介绍。大家如果有问题欢迎在评论区留言。  J# X  |% B7 \0 G) F% X
+ g# w2 A" I- p8 @3 f
本文首发于公众号:医学和生信笔记2 x8 Z* J  `4 t

) w) H- ^- Z" [! U% [“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。
$ F3 W  o* Q9 O# g$ {# C* H' G' c本文由 mdnice 多平台发布$ y) V+ F$ u! ~/ ?" O& C3 y
————————————————
! E0 b! W  D. S9 P5 R" a版权声明:本文为CSDN博主「阿越就是我」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
- t  z, `) k9 u8 H5 w  P原文链接:https://blog.csdn.net/Ayue0616/article/details/126768006
; k9 v8 \7 @: P# L* y8 M) Y' t: h# o/ t4 I* ]7 |  w
& _" z2 `& [( a4 U5 O





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