数学建模社区-数学中国

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

作者: 杨利霞    时间: 2022-9-12 18:43
标题: 净重新分类指数NRI的计算
* H  R* k7 v% k" Q5 X( n% B
净重新分类指数NRI的计算- W3 N8 x8 V" {, d$ o
“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。! l+ Z) g. h% r
NRI,net reclassification index,净重新分类指数,是用来比较模型准确度的,这个概念有点难理解,但是非常重要,在临床研究中非常常见,是评价模型的一大利器!) y7 Z- `7 j, Z* S. M
( y9 _' b3 a! m. y
在R语言中有很多包可以计算NRI,但是能同时计算logistic回归和cox回归的只有nricens包,PredictABEL可以计算logistic模型的净重分类指数,survNRI可以计算cox模型的净重分类指数。
+ Z( E* n# l1 \9 [' u4 ]" q; X5 v3 J* C
logistic的NRI. R  u: X6 E# _' F# {9 ~* \
nricens包$ \1 [  y! B( \' d
PredictABEL包
5 v& W$ j$ g! y7 ~# M" l生存分析的NRI
; {! U1 d# W# a2 x9 qnricens包6 Y6 g# X+ q# X3 b* O
survNRI包: ^. B, O. ]. P, S  I$ I
logistic的NRI
* U; c& ]6 R" J3 c0 snricens包) U9 j; c4 e  v' n& P' T
#install.packages("nricens") # 安装R包- R& a% u3 i8 q" r' f6 e* s* s
library(nricens)
/ I+ b# P" o/ W: d; ~1% l4 r5 m6 ~! F( }' k5 H- j7 p
## Loading required package: survival
. S. K4 d  \% d. c1
8 O9 C6 c/ `1 E使用survival包中的pbc数据集用于演示,这是一份关于原发性硬化性胆管炎的数据,其实是一份用于生存分析的数据,是有时间变量的,但是这里我们用于演示logistic回归,只要不使用time这一列就可以了。* O7 G2 x- }" I  f9 \

3 k! Q' V2 W, c( H7 V! clibrary(survival)# @5 q5 @# S# ~3 B
6 K9 R  Z! T$ b: Y5 v1 l
# 只使用部分数据9 p. |$ d' G( ~$ ?5 h  S
dat = pbc[1:312,] 3 s& @( T# ^+ V4 M1 \" A3 B
dat = dat[ dat$time > 2000 | (dat$time < 2000 & dat$status == 2), ]( I0 P7 z, }* M" A3 R

/ B) Z6 i% w! i) X. Z+ t% Astr(dat) # 数据长这样
% L( C1 h( I( D/ K6 ~# b* E1( c. N+ q5 H1 D% S2 v- T& O
## 'data.frame': 232 obs. of  20 variables:
; G5 f9 P/ E. \$ v7 i1 T7 F##  $ id      : int  1 2 3 4 6 8 9 10 11 12 ...
! ?  ]9 w$ R& N+ b7 l##  $ time    : int  400 4500 1012 1925 2503 2466 2400 51 3762 304 ..., L- u& U7 j* Z
##  $ status  : int  2 0 2 2 2 2 2 2 2 2 ...3 v. w% G2 Z3 M7 S4 l- A/ V
##  $ trt     : int  1 1 1 1 2 2 1 2 2 2 ...* C" k0 y% b$ Q. I
##  $ age     : num  58.8 56.4 70.1 54.7 66.3 ...
+ a( A/ O2 g  b2 S##  $ sex     : Factor w/ 2 levels "m","f": 2 2 1 2 2 2 2 2 2 2 ...
3 r# t8 ?  f/ {. b5 e) A  S2 S##  $ ascites : int  1 0 0 0 0 0 0 1 0 0 ...
% T1 [: N) t) J- Q& E9 Q3 |##  $ hepato  : int  1 1 0 1 1 0 0 0 1 0 ...
! D1 x# }! l3 V; \##  $ spiders : int  1 1 0 1 0 0 1 1 1 1 ...2 m" `) ~! K9 z2 Z
##  $ edema   : num  1 0 0.5 0.5 0 0 0 1 0 0 ...
4 \! e/ c% [, _$ \) i  n##  $ bili    : num  14.5 1.1 1.4 1.8 0.8 0.3 3.2 12.6 1.4 3.6 ...
6 |# b" L; @/ g##  $ chol    : int  261 302 176 244 248 280 562 200 259 236 ...
' ?, _" U$ G" |) d3 U##  $ albumin : num  2.6 4.14 3.48 2.54 3.98 4 3.08 2.74 4.16 3.52 ...
0 n# [+ ?" V5 ]1 y' y; Q##  $ copper  : int  156 54 210 64 50 52 79 140 46 94 ..., |0 ~. F$ p) ]$ Z: [( h, Q& X
##  $ alk.phos: num  1718 7395 516 6122 944 ...
8 @4 w7 _7 s  e0 T, R8 ^/ d6 G+ b2 @  [##  $ ast     : num  137.9 113.5 96.1 60.6 93 ...0 B& i$ \. n3 l! }: s6 J+ N* u$ r
##  $ trig    : int  172 88 55 92 63 189 88 143 79 95 .... d6 s; }1 s6 l) d
##  $ platelet: int  190 221 151 183 NA 373 251 302 258 71 ...6 \2 K- L9 Y  C/ H6 `0 G: u
##  $ protime : num  12.2 10.6 12 10.3 11 11 11 11.5 12 13.6 ...9 o+ Y8 ]; _/ H1 z5 N1 Z
##  $ stage   : int  4 3 4 4 3 3 2 4 4 4 ...
8 S/ {1 `* w( s; n2 X3 A
2 e1 J4 S2 ]' h1
& G- @5 G" p& I) E  W6 }- Qdim(dat) # 232 20
& P  b$ c! G( o9 `- z& j1
4 ~9 q) {! @1 ^% v: s* ^## [1] 232  206 s7 A- f3 l  p$ a6 ]- n% h  o
1
: g$ s9 |. Q4 E1 H% {- F: r6 J然后就是准备计算NRI所需要的各个参数。
+ |( F$ Y) C# ^) B! u$ B4 n
& O! m( u# G4 T& i. G6 X& e# l# 定义结局事件,0是存活,1是死亡
: V; Q, U8 v! ]2 V$ D6 Yevent = ifelse(dat$time < 2000 & dat$status == 2, 1, 0)
9 F  H, S; i  L( l5 r' C- P# z3 B
, N  ~* X8 A! ^0 p) _' n' ~; h# 两个只由预测变量组成的矩阵
& _: r2 [, \- _  h0 Ez.std = as.matrix(subset(dat, select = c(age, bili, albumin)))
6 r& J3 e- }5 I; Q  Q: xz.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))
! D* }! b1 \" R% J2 W
+ O3 ]' P+ n6 ?1 i- E: o9 }# 建立2个模型1 z" N4 w/ W  f. B" O
mstd = glm(event ~ age + bili + albumin, family = binomial(), data = dat, x=TRUE)4 B8 d; C3 b) X0 l, i4 Q$ B
mnew = glm(event ~ age + bili + albumin + protime, family = binomial(), data = dat, x=TRUE)
" L; D! G! [) w/ X7 g1 S
$ ~* R. P7 n0 x4 K# 取出模型预测概率
5 Q9 b" l2 X6 r9 z  L& ~' ip.std = mstd$fitted.values* b5 Q1 W: @3 M
p.new = mnew$fitted.values9 ]( G5 @- P7 D: X# u1 J1 J
9 e% y' m/ M  e; n3 f, t, f
1: J: g" i9 b" R2 H- j7 v4 z
然后就是计算NRI,对于二分类变量,使用nribin()函数,这个函数提供了3种参数使用组合,任选一种都可以计算出来(结果一样),以下3组参数任选1组即可。 mdl.std, mdl.new 或者 event, z.std, z.new 或者 event, p.std, p.new。
. Q' |( j, |* e/ B/ F
4 x+ i& Z- h3 v( [2 u3 M# 这3种方法算出来都是一样的结果
! R& _; A8 ]& {% [" _1 p# i5 P# @" r) w7 S) \% _8 I
# 两个模型" x4 L1 V) \0 Y  U# R
nribin(mdl.std = mstd, mdl.new = mnew, 7 x* O1 W  O* X) L
       cut = c(0.3,0.7),
6 m' {* F% _; ~! n9 d, H3 ?       niter = 500, ! y8 {( E. W/ s4 L4 Q" e% s
       updown = 'category')
: i  \2 |! H3 Q$ J2 N0 S1 A( |
7 b; O' o0 n* {/ f" N! l# 结果变量 + 两个只有预测变量的矩阵
$ D4 ^0 h* a3 v3 |0 `# Dnribin(event = event, z.std = z.std, z.new = z.new,
; a. f# Z5 J9 f5 ^  N! n) T# E       cut = c(0.3,0.7),   I+ C% O* r& k; P  M7 p# N
       niter = 500,
6 a% N6 B, l$ D/ B, m       updown = 'category')5 [/ F7 b7 B9 X% z* }. l) {
/ p+ o- A8 ~8 T5 j  f% x
## 结果变量 + 两个模型得到的预测概率5 J! D1 `& U9 \% K
nribin(event = event, p.std = p.std, p.new = p.new,
& v) D3 t9 l9 T& O' P* I       cut = c(0.3,0.7),
7 |& \4 ]; J. l& J# \4 h  c) L       niter = 500, ! Y8 H3 E% ^3 C! j
       updown = 'category')
6 c, ?* K; p5 p6 v# ]/ p6 o7 E# s, c3 [( c* \4 M2 u
1
& H+ q" ^1 J7 h* D2 X其中,cut是判断风险高低的阈值,我们使用了0.3,0.7,代表0-0.3是低风险,0.3-0.7是中风险,0.7-1是高风险,这个阈值是自己设置的,大家根据经验或者文献设置即可。, V* j: `) P0 N0 X2 a3 m' S) _" R
, x) j2 Z1 {" K: j1 q, z' j4 v; S
niter是使用bootstrap法进行重抽样的次数,默认是1000,大家可以自己设置。
7 W8 f: x" k" h5 S
7 E9 {0 S, c, ?2 ]; @updown参数,当设置为category时,表示低、中、高风险这种方式;当设置为diff时,此时cut的取值只能设置1个,比如设置0.2,即表示当新模型预测的风险和旧模型相差20%时,认为是重新分类。
  B: I# _* H' K5 L" V: [% K; U6 @
1 Y0 O6 G/ e- O( P) U上面的代码运行后结果是这样的:
0 F, s  \/ u! ~& }% M0 q0 G2 w
( r/ O* \6 }' ?" o. P7 `0 w8 NUP and DOWN calculation:
5 E' h! A$ h" q5 J7 l5 I% o! U5 O  #of total, case, and control subjects at t0:  232 88 144
( B7 ^( [! V% c, i
' [4 A4 l7 }8 `$ [  `' U  Reclassification Table for all subjects:
  l2 z0 G8 ]0 U. l        New
& B- n% a5 V1 |# W& h% |- dStandard < 0.3 < 0.7 >= 0.7$ k4 j: M- ]5 u9 P' O% J* P: j
  < 0.3    135     4      0+ t! r1 J0 g0 G& ]5 V
  < 0.7      1    31      42 n9 X- p$ m% J+ L. f2 v
  >= 0.7     0     2     553 W  n3 {& N. C: U

4 e! r+ R7 G! Y1 K6 x4 e5 m+ K  Reclassification Table for case:& N! c+ H9 R" ?) V. {, s
        New
, E: ?+ B! o2 t$ D9 c* p# `Standard < 0.3 < 0.7 >= 0.7
: Q  l9 g% n/ u- O1 i4 H8 Y  < 0.3     14     0      02 o. D9 W9 ~) D# {& @! b
  < 0.7      0    18      3
1 j% c3 v- q% t. x7 D  >= 0.7     0     1     52
/ K/ v5 v* Y% b* W" j1 a0 f* I" X: W% Y  K9 f6 Y( A* X4 m5 V
  Reclassification Table for control:
, L6 v" I4 J* A  U2 V        New
6 `; N: K! }3 ^2 D  i( MStandard < 0.3 < 0.7 >= 0.7
- V, |2 }; H# D4 l2 b  < 0.3    121     4      0
" T2 D6 M& }$ |  j+ k% w  < 0.7      1    13      1
1 W2 d" R5 T3 Q( `; E' p  >= 0.7     0     1      3: T/ ]6 A7 E. n" Y' o
8 ~6 E7 k7 w: f% R/ X% L/ D% Q
NRI estimation:0 X2 e$ {6 r7 h- b7 z2 q& x
Point estimates:& j0 V$ q2 a: J; O/ m+ h3 t
                  Estimate4 N7 \, }# Y- o
NRI            0.001893939
) W0 l- R' p( s. p5 G% U6 N- oNRI+           0.022727273
3 @/ A+ t% c& ^: ^* F: l% }) hNRI-          -0.020833333
" [  K% H6 \' n5 \Pr(Up|Case)    0.0340909096 b+ y+ e1 s  X
Pr(Down|Case)  0.011363636$ a; F9 ~" m7 J  f: ]
Pr(Down|Ctrl)  0.013888889+ D: j* G) T7 I1 W2 l" w
Pr(Up|Ctrl)    0.034722222# W& ^. q& _, J! T6 M  l- ~
7 N4 \2 @+ R( V5 y, T. V) X7 a( |
Now in bootstrap..# c9 |# W& @9 I

/ P& x) V- j" S$ o, |Point & Interval estimates:
" @" e2 x+ g  E: p. P$ `                  Estimate   Std.Error        Lower       Upper' s8 L3 X+ Y( C
NRI            0.001893939 0.027816095 -0.053995513 0.055354449: t2 |- F* o, f4 D  N0 w
NRI+           0.022727273 0.021564394 -0.019801980 0.065789474
8 k( v# Q0 Y3 v" jNRI-          -0.020833333 0.017312438 -0.058823529 0.007518797
( t- D6 H( ~* h( [Pr(Up|Case)    0.034090909 0.019007629  0.000000000 0.072164948; h! m6 w- k' D' |$ o& c6 |1 D
Pr(Down|Case)  0.011363636 0.010924271  0.000000000 0.039603960
0 E5 ]& q+ R; }; i( `' k4 D. fPr(Down|Ctrl)  0.013888889 0.009334685  0.000000000 0.035211268
- H5 s* F3 s- S3 t3 h+ VPr(Up|Ctrl)    0.034722222 0.014716046  0.006993007 0.066176471
+ h' M$ ^4 B' g6 u/ z2 O! g
: s8 s5 B! \1 S- w1& l# o2 Z( g1 C8 N& m7 ]
首先是3个混淆矩阵,第一个是全体的,第2个是case(结局为1)组的,第3个是control(结局为2)组的,有了这3个矩阵,我们可以自己计算净重分类指数。
; _: |0 C/ d" J! z: t& y! l* @
8 B8 e- x" s+ w- C, J" N1 h看case组:. e+ g; a6 u- N2 w4 w" ?

3 ^) H/ h3 j- l/ d: p净重分类指数 = ((0+3)-(0+1)) / 88 ≈ 0.022727273
8 w  f8 D: G  l% G& F4 R6 w$ \; P+ M. [3 t4 N. q% f8 |/ Z
再看control组:
6 @3 J3 x+ n2 i
) K; G$ q0 a$ l  w% M净重分类指数 = ((1+1)-(4+1)) / 144 ≈ -0.020833333) y6 x8 d% ^5 ^$ f* \9 L
+ f7 d7 b5 L) _& |  E* |# b
相加净重分类指数 = case组净重分类指数 + control组净重分类指数 = 2/88 - 3/144 ≈ 0.0003156572 b! `* n: F' u, |

8 Z% a0 q# T7 U$ J/ m& V+ X再往下是不做bootstrap时得到的估计值,其中NRI就是绝对净重分类指数,NRI+是case组的净重分类指数,NRI-是control组的净重分类指数(和我们计算的一样哦),最后是做了500次bootstrap后得到的估计值,并且有标准误和可信区间。
6 j& j/ K0 k7 S; t0 `) e3 e# Z8 Q/ w) J* a# T& t; P6 O3 p
最后还会得到一张图:, n; [$ e/ i* e
( g8 i0 O$ A2 p; m# |6 t
这张图中的虚线对应的坐标,就是我们在cut中设置的阈值,这张图对应的是上面结果中的第一个混淆矩阵,反应的是总体的情况,case是结果为1的组,也就是发生结局的组,control是结果为0的组,也就是未发生结局的组。
5 U/ O: U& t) p! n8 c0 q8 h  ]; d+ e: {1 o9 t1 n
P值没有直接给出,但是可以自己计算。
# {; F" g9 K# y  l0 p$ b& _4 e8 _% u% u; t0 K6 K: i, Z
# 计算P值
7 [' Q# S8 Z4 G! T6 l* `% Fz <- abs(0.001893939/0.027816095)) |; e) v# @" D! x9 s% P2 l
p <- (1 - pnorm(z))*2
; H+ V0 S; I! I! g+ A  Jp$ `2 T/ B! a5 o+ M! R% {. |
1$ y  b: o- _8 ~' C. `) \
## [1] 0.9457157( L. E/ D6 N$ F9 R6 g0 s3 I+ D: l
1
& k& k- B( w) c; b* xPredictABEL包
6 N% ^% [4 Z' N/ F0 y5 Z3 f' l/ b#install.packages("PredictABEL") #安装R包
' N* t5 V7 u* Y0 {- V9 alibrary(PredictABEL)  2 L3 ?& s/ k4 `
$ ?: O5 q9 l1 e1 I  z4 B
# 取出模型预测概率,这个包只能用预测概率计算2 g2 \( k( t; \
p.std = mstd$fitted.values
; y( L  c" a7 @- B0 A4 zp.new = mnew$fitted.values
$ C7 P0 X' r3 [7 W$ _( c: d, |16 k8 b; x2 b1 {* |3 |. c: y6 r5 {
然后就是计算NRI:
. Y9 {) T4 h1 w- o5 y  j: r
8 Q9 h8 a6 Q; n1 c& ~dat$event <- event
; L% t" ^7 N" g+ p" }  @. A8 f0 u' F
reclassification(data = dat,2 i/ O4 ~$ ~' x) |  k+ t
                 cOutcome = 21, # 结果变量在哪一列
* n! g$ f7 X( |+ |* X                 predrisk1 = p.std,
2 Q* {/ x" U* Y  s                 predrisk2 = p.new,% X( g; z9 a4 N9 J8 N' l  s, n4 L  O
                 cutoff = c(0,0.3,0.7,1)
% F( ]3 q$ B9 g0 H. m) a% l                 )0 P) p2 K' e7 e
1
. E. k9 \2 u2 E  w##  _________________________________________
' O+ f5 O! X5 ]7 X  x0 H##  + K) N1 L/ S$ }( [2 Z6 I! u  q3 @5 K+ i
##      Reclassification table   
7 x- D" l. x8 l- R  _##  _________________________________________' C! ]& \6 c2 T' y2 k
##
+ I2 ^3 J. j5 |, _. n##  Outcome: absent
7 ]/ g! H' F3 `+ {##   ; w$ c" I- k5 G' u
##              Updated Model: Q2 `1 a( Q3 S* y9 y8 g  N9 M# Z/ ?
## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified" J. i. v4 @: H/ J
##     [0,0.3)       121         4       0               33 j' I3 Q9 a1 H
##     [0.3,0.7)       1        13       1              13
5 y7 y  _% m2 @' k- |##     [0.7,1]         0         1       3              25
) }% M, o" u8 {' L##
6 J" T7 v9 m3 |1 [: H##  
7 t* u/ p2 u/ T1 O0 E4 b# X& Y3 p8 E##  Outcome: present
# u9 z+ C; ^+ c  V/ q9 o, T##   % L! {' P, _, z
##              Updated Model
4 L5 R+ s: A6 c/ b( w! d## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
8 m9 r0 x5 \7 k$ t9 L! w##     [0,0.3)        14         0       0               0
: e/ f% a2 k4 t/ `( I- [##     [0.3,0.7)       0        18       3              148 p5 R' t1 i4 z# s+ a
##     [0.7,1]         0         1      52               28 ^/ d4 `, D, w. e
##
7 u+ \  |1 l3 O) z$ u2 k##    n6 Z$ d! ^* N. N( N6 A
##  Combined Data
. v- O0 z- f5 N, e" H; k##   ) S* w5 j1 U. \
##              Updated Model
  N/ k& c6 J2 [6 S## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified9 T4 A( C% Y- R; s  x; I
##     [0,0.3)       135         4       0               36 u7 l$ U* v2 b! i& w% j% \
##     [0.3,0.7)       1        31       4              14; K9 l  K2 E; ]/ Z( n. `
##     [0.7,1]         0         2      55               4, s3 p0 V0 V/ l+ M
##  _________________________________________
8 P  J- o1 y; M5 ~7 M## 8 |1 V0 {6 a: s
##  NRI(Categorical) [95% CI]: 0.0019 [ -0.0551 - 0.0589 ] ; p-value: 0.94806 8 t7 c3 o, \* l3 B. Z2 L: c
##  NRI(Continuous) [95% CI]: 0.0391 [ -0.2238 - 0.3021 ] ; p-value: 0.77048
$ b$ o; p& B7 i& ~- [##  IDI [95% CI]: 0.0044 [ -0.0037 - 0.0126 ] ; p-value: 0.28396
  E6 j+ \" b" C! `( H1 I# M5 K
1
5 J6 o  e' B  H9 g. c- v' L# d$ O结果得到的是相加净重分类指数,还给出了IDI和P值。两个包算是各有优劣吧,大家可以自由选择。( n3 I) n& F4 p
& z6 s" U: ~6 p/ n
生存分析的NRI
9 i1 ^9 K1 k6 K$ h. d0 P还是使用survival包中的pbc数据集用于演示,这次要构建cox回归模型,因此我们要使用time这一列了。
/ _' B4 J/ ]3 d) |* X' V1 H' M* r; e  B' ^& `# O
nricens包9 O7 P7 w# B" Y+ t4 ]3 D! |
library(nricens)
8 G9 n9 f0 s8 O5 hlibrary(survival)  N  E/ a% x$ W5 ~, t. D/ e# d# u6 X

; @+ d' h( i) x4 Ydat <- pbc[1:312,]
, q; C( s% v$ i' x6 V+ Edat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡
7 W' Z; H" w2 m! ^4 r1
& b( r8 F0 W: S+ K然后准备所需参数:6 w: `* L* W" }) c' f! _3 Q

1 ?! o/ u: Y( n3 s/ F# 两个只由预测变量组成的矩阵0 j3 U! @- N4 s9 G, a
z.std = as.matrix(subset(dat, select = c(age, bili, albumin)))* ], ~$ f+ F5 R! [/ m$ h0 S
z.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))
1 k5 q. x' o- b# m( ~" G; J. a' n( [$ c; u# a- i" X5 Q
# 建立2个cox模型
6 p1 Y0 [1 s; z. i4 i3 dmstd <- coxph(Surv(time,status) ~ age + bili + albumin, data = dat, x=TRUE)# ?# ?- R% w' P; \
mnew <- coxph(Surv(time,status) ~ age + bili + albumin + protime, data = dat, x=TRUE)
( B2 X- h% l8 f( j# C0 z0 D
1 f0 j. I5 J3 v; Z# 计算在2000天的模型预测概率,这一步不要也行,看你使用哪些参数0 Z' ^9 a* J4 i8 Y
p.std <- get.risk.coxph(mstd, t0=2000)6 T2 e* E" x+ l9 x$ P0 f
p.new <- get.risk.coxph(mnew, t0=2000)+ _% L" {( R" `' V6 {
1
1 ?7 ~; G& r/ }# t! [; b/ w& @计算NRI:) I/ R" T2 c) @* B
8 x1 R8 c& @8 E3 B# f
nricens(mdl.std= mstd, mdl.new = mnew, % v4 {% ~. F$ W; |" I( D5 m( a
        t0 = 2000, 7 [' a( x- T! X* F% h% J
        cut = c(0.3, 0.7),/ a1 ^" [, e4 C  e, K
        niter = 1000, ( Y% z2 x% c. ^0 F) j# w
        updown = 'category')
: G8 L$ A; t, Q5 M6 x' m: e0 @( f9 p6 _6 v0 t) {  v
UP and DOWN calculation:  [& }) `- Q. p+ [+ z+ q
  #of total, case, and control subjects at t0:  312 88 144) F. k: |' n  \
* g, r* ?9 S3 D, P* i/ K
  Reclassification Table for all subjects:
% a; b5 G1 D0 B# ?: O# ~        New
$ e: {4 Z6 q* _$ G2 }' MStandard < 0.3 < 0.7 >= 0.79 l$ X5 H) i5 y4 {  G
  < 0.3    202     7      0
/ k) z7 c% S" u, `8 J- Y  < 0.7     13    53      6* g4 X( U8 [/ q9 P7 [
  >= 0.7     0     0     31
* @- R5 U, J+ A' L) t7 I1 v
) e9 w- y* Y* I  Reclassification Table for case:
- v! `! `4 p/ j4 b' _9 g        New
6 g0 X( p9 R. {- f$ ^4 nStandard < 0.3 < 0.7 >= 0.71 ~& Q8 H  e3 J7 ]5 @' Y
  < 0.3     19     3      05 f! E, _: W/ U5 c) `! J7 f
  < 0.7      3    32      4
- L+ D0 L2 J+ l( C3 n  >= 0.7     0     0     27
/ o- R( u9 P1 `7 }2 x: `3 v& r, b, W1 i) l3 S$ j
  Reclassification Table for control:
& _1 d; G* B! `4 o        New! W) A/ p% {+ G1 _
Standard < 0.3 < 0.7 >= 0.7
  g* V* _  S3 F% Z; U: o  < 0.3    126     3      0! O6 ]# Q+ X3 ~2 @
  < 0.7      5     7      2
0 @. ~% y3 }% {# w  >= 0.7     0     0      1
1 v5 M! c& f# @8 T" \/ A0 r5 u
# h# A5 D2 W8 }2 VNRI estimation by KM estimator:
; a# B) A: t" M' z) }
, E0 S) h1 N7 N8 hPoint estimates:. w8 A4 s, E5 {) `& T! ~3 W6 u& g* d# V/ {
                Estimate
" d7 X- o" z  t  yNRI           0.05377635
6 h. m6 ]  P" x+ P; e1 JNRI+          0.037486601 A% h5 C3 q$ _) H) Z
NRI-          0.01628974
' l( l! W, q/ K$ ^$ L" wPr(Up|Case)   0.07708938
* M5 u2 Y/ _2 {3 x% x* v  S# UPr(Down|Case) 0.03960278
8 ?0 _. x7 Y( R- e' J9 q  A) dPr(Down|Ctrl) 0.04256352
: d9 R4 H/ n4 CPr(Up|Ctrl)   0.02627378) p) M% |* C0 n% J' ]' I0 z

! Z7 Q6 z. N% G- ?5 [* }/ @Now in bootstrap..& e" A; g8 q; t3 g3 }
7 b6 b) }7 h, E- Q& O; v& l
Point & Interval estimates:' o5 G9 f1 W9 r; t, T- e
                Estimate        Lower      Upper
+ f9 g/ [" @3 M. K/ u6 w6 h3 TNRI           0.05377635 -0.082230381 0.16058172$ j  Y0 J, N' V
NRI+          0.03748660 -0.084245197 0.13231776" ?8 E+ {( w$ ^  I: H1 |8 M# K
NRI-          0.01628974 -0.030861213 0.06753616
; \* h: Q- b' t) A+ t  \6 vPr(Up|Case)   0.07708938  0.000000000 0.19102291$ T0 ~9 U+ X5 }) T5 R: \6 Z
Pr(Down|Case) 0.03960278  0.000000000 0.15236016
# h5 L3 m) h3 Q3 U1 j5 @8 lPr(Down|Ctrl) 0.04256352  0.004671535 0.09863170
, @9 r! q. B( g; m: ePr(Up|Ctrl)   0.02627378  0.006400463 0.05998424. x9 o! v+ ?6 c! @$ H! D

" Z9 R, E% [, `* Z1 N3 n$ i; k, ?1
$ ~1 [& i2 _& z
! m: B* {, Y9 F" \Snipaste_2022-05-20_21-49-38
+ E. t3 O1 O) a+ S( v结果的解读和logistic的一模一样。* A. t  Z" \4 R2 V+ R

6 u% H3 c# E' U3 H+ s" X! _survNRI包
  {7 u, U! t4 U& e) q$ x2 @, Z: Y$ t3 o# 安装R包3 L" p  Y; V9 u
devtools::install_github("mdbrown/survNRI")
* V5 M) F! Q5 Q  S/ F5 N1
$ p" C5 ~1 F9 y; Y# p- o加载R包并使用,还是用上面的pbc数据集。
, N2 f7 M0 o* w8 ]! {
( T8 s" M4 o0 q" m; ilibrary(survNRI)& Q, m% _7 d3 M+ K4 z9 {" R
1+ {4 p. M" n) ~. ]* w
## Loading required package: MASS
6 `  L/ _% u# e% i13 A# i3 T4 ~! b1 z
library(survival)2 j* K6 ~5 C& L4 [
1 R( y& u9 D9 Q+ J% x7 _7 m3 K7 C
# 使用部分数据0 c4 J4 k# K4 N" x
dat <- pbc[1:312,]' z4 G* j8 \& t; y
dat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡1 u; v2 e# Y2 m! l, X3 D' h3 s3 }

( U  h7 X+ Q. d4 o) zres <- survNRI(time  = "time", event = "status",   p8 ?" y6 i0 L  Y2 w+ e
        model1 = c("age", "bili", "albumin"), # 模型1的自变量
; }. o% ^, \( g        model2 = c("age", "bili", "albumin", "protime"), # 模型2的自变量
. ]* H/ H5 ~1 Y( w# Z4 H7 i, i) K        data = dat, # S  g, M2 n' P$ E7 e
        predict.time = 2000, # 预测的时间点
8 R) o6 N  Q7 ~' E7 P& V        method = "all", 3 _9 \% A4 t4 \8 w/ I# B9 M! l
        bootMethod = "normal",  
) ]4 d: O! R+ F1 n' v% D: `* F        bootstraps = 500, 3 ]6 B2 w' p$ b) R% h' l
        alpha = .05)2 s4 k8 t. A" o$ j- a) j

' H* k: j6 V' y6 \% n$ j2 m. B4 r1
. s: X9 y/ h# E% D查看结果,$estimates给出了不同组的NRI以及总的NRI,包括了使用不同方法(KM/IPW/SmoothIPW/SEM/Combined)得到的结果;$CI给出了可信区间。/ z5 L& _& U$ A5 c+ z

9 B& _8 n) S  G' x0 V' zres
' N3 A  Q  }. `6 D6 Q1: T# g+ G6 L8 ]' \
## $estimates
' j; Q  `* C) @$ x0 x2 P" [# P##            NRI.event NRI.nonevent       NRI
: W! i+ Q/ ~; h: C' R5 D## KM        0.20445422    0.3187408 0.5231951  p  |# h# X$ N) }5 @
## IPW       0.22424434    0.3273544 0.5515987  w$ X; X; M$ E; u' i" `7 V
## SmoothIPW 0.19645006    0.3144263 0.5108763
, _6 C; `; r* G! y5 S4 D4 E2 |' {## SEM       0.07478611    0.2632127 0.3379988
5 z* S. S" }% V' D1 r9 t6 Y7 r  e## Combined  0.19633867    0.3143794 0.5107181) m7 p4 i1 {* v. O
##
. t9 ]; _, @, f+ L+ B9 z## $CI% |) o+ T$ D  N" |: [* N0 x
## $CI$NRI.event
8 n; y7 @) F7 L9 G1 i##                     KM         IPW   SmoothIPW        SEM   Combined
4 F, w# z, K, y% ]! P$ W) L9 m) u## lowerbound -0.03915924 -0.02185068 -0.04724202 -0.1162587 -0.04737234 j6 L' E' W$ z5 U* J4 o" g9 ^
## upperbound  0.44806768  0.47033936  0.44014214  0.2658309  0.4400496
2 M* F. ?" M. e5 R( A# D##
: G& ^' w9 m- m& _# Y# l## $CI$NRI.nonevent
, T" F  t- X. @: M8 `" P* \: u  C##                   KM       IPW SmoothIPW        SEM  Combined
7 j6 Y/ ~# Y- q! O+ n  }## lowerbound 0.1317108 0.1396315 0.1286685 0.08638933 0.12864260 @% C# M- A! n# |; M* k
## upperbound 0.7102251 0.7393216 0.6966341 0.51482212 0.6964549
6 ?( p& F2 e, e: n## , P9 z+ b- Q( t' U" u8 p
## $CI$NRI* P: m$ {- T% a- t0 G  ^6 E, N
##                     KM         IPW   SmoothIPW         SEM    Combined
% w" U6 j" q0 |+ ?! X## lowerbound -0.05112533 -0.04569046 -0.05439863 -0.04132364 -0.05443409. ?# e- T( J" t, t( {) I% I
## upperbound  0.89306122  0.92464359  0.87970125  0.64253510  0.87953153
, _$ `9 z8 E  f' W##
# _7 C7 D6 ~' {" Q; T0 l; A  n## : J* f9 f# |: K4 r  u' p
## $bootMethod+ Y" C% v7 c1 U
## [1] "normal", h7 a% z: f* b
## 0 ?8 ^0 Z/ Y' d5 K% l1 R
## $predict.time
& j; s( b4 f7 z+ Y" Q. e! L+ z## [1] 2000
! e; o3 M! L# Z( |( X## $ u1 T, }! N  d( ]4 U/ O
## $alpha
- e5 l# N1 D/ g% N9 f! n## [1] 0.05% A- z& ~* n& ]! K# g
##
% R- r8 O) ?8 m! ^## attr(,"class")7 F# F; j$ p% f; V; U
## [1] "survNRI"
' G8 p8 x9 ^$ H* R+ ?+ t/ m  p. j! g# I; E% F) ^
1
8 T( Q4 h& G4 `: cOK,这就是NRI的计算,除此之外,随机森林、决策树、lasso回归、SVM等,这些模型,都是可以计算的NRI的,后面会继续介绍。大家如果有问题欢迎在评论区留言。
+ M9 r# [" s4 S  b
" y6 Z  i) \$ A4 o; B本文首发于公众号:医学和生信笔记
4 K3 f4 ~" g3 c$ u7 h" |' l7 ]9 X6 T
“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。
0 k7 n- L. @9 D! Y0 x) d/ ^- H本文由 mdnice 多平台发布
4 j5 j1 |' T% _% ]————————————————
) y8 `/ N' z5 n$ V) d版权声明:本文为CSDN博主「阿越就是我」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。% X% x+ p# M) `: j: A9 y
原文链接:https://blog.csdn.net/Ayue0616/article/details/126768006
2 Z* }8 S6 V. r* Q& F$ o  q
" Z: }9 y6 C: g# u% F% s8 p
, R$ i2 {* Q, T; H; q. r8 |




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