数学建模社区-数学中国

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

作者: 杨利霞    时间: 2022-9-12 18:43
标题: 净重新分类指数NRI的计算
- T1 k+ J& k- H
净重新分类指数NRI的计算
) x" m  Q! w8 H. V“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。
+ d  Y1 x7 q) z: U) s3 lNRI,net reclassification index,净重新分类指数,是用来比较模型准确度的,这个概念有点难理解,但是非常重要,在临床研究中非常常见,是评价模型的一大利器!6 o. t" A, D8 p* `

2 |' z8 e3 v9 z/ x8 j在R语言中有很多包可以计算NRI,但是能同时计算logistic回归和cox回归的只有nricens包,PredictABEL可以计算logistic模型的净重分类指数,survNRI可以计算cox模型的净重分类指数。& Q# f) s( z; t+ v+ U/ ^
+ w' _6 J$ |6 Q
logistic的NRI, X. @* l, |% l: U' p* S8 \% X; g" V$ E
nricens包  [* E2 ?1 d+ x( \; B
PredictABEL包
2 z6 i' p0 ]# i) b# }+ E0 f& l生存分析的NRI* X7 e! T/ }, \# |; Y( p# p& Z
nricens包
  S! ^; H- h7 ^survNRI包
: t# h7 ~- B+ [5 |% ]( q1 U. Ilogistic的NRI/ {7 u) {# I, v/ Z) s
nricens包
, q5 i! c9 s, u# I. _( B4 n#install.packages("nricens") # 安装R包
3 C0 l/ e. m8 w( D' _, n2 Glibrary(nricens)
6 O& n' G( z6 }6 T* v$ B+ d9 p1
% H$ i, m+ }- {7 B8 r, J! y8 h+ m## Loading required package: survival4 |) Z/ T6 T9 H
1
1 {% y2 \8 d' b使用survival包中的pbc数据集用于演示,这是一份关于原发性硬化性胆管炎的数据,其实是一份用于生存分析的数据,是有时间变量的,但是这里我们用于演示logistic回归,只要不使用time这一列就可以了。) c, o, g( L, P/ A9 X1 S
3 b9 m$ B: B1 f# E$ N
library(survival)
; N/ A- P2 D. C
* b% i7 S3 z2 w' p( m7 o# 只使用部分数据0 l6 I; d! I7 k
dat = pbc[1:312,] ) w# c2 z8 w9 O' P- S7 o/ G0 n
dat = dat[ dat$time > 2000 | (dat$time < 2000 & dat$status == 2), ]
  u( y; u  c  {' o* g% e
, L1 `1 }6 I: V( ~* Astr(dat) # 数据长这样$ C6 |2 n, b6 @, a& {3 n
1
& K1 T6 |7 w! A& }## 'data.frame': 232 obs. of  20 variables:3 M  M: z# l2 E' V* i
##  $ id      : int  1 2 3 4 6 8 9 10 11 12 ...2 N: ?3 o  y! n4 J
##  $ time    : int  400 4500 1012 1925 2503 2466 2400 51 3762 304 ...
4 O+ d- R7 O, q; Z! b5 P##  $ status  : int  2 0 2 2 2 2 2 2 2 2 ...
: L3 h& r: W- K6 l8 r  ]* n##  $ trt     : int  1 1 1 1 2 2 1 2 2 2 ...
7 N" b' V" }1 F* l2 C, `##  $ age     : num  58.8 56.4 70.1 54.7 66.3 ...
& {" l) L% x% J& C* Y$ ~##  $ sex     : Factor w/ 2 levels "m","f": 2 2 1 2 2 2 2 2 2 2 ...
) v, e. J2 B) i5 F: c) \' N##  $ ascites : int  1 0 0 0 0 0 0 1 0 0 ..." J( f; i( u% N9 Y. D
##  $ hepato  : int  1 1 0 1 1 0 0 0 1 0 ..., y5 u* r% E) h5 \$ S
##  $ spiders : int  1 1 0 1 0 0 1 1 1 1 ...
" i: r; j: [3 a- B3 ]( |##  $ edema   : num  1 0 0.5 0.5 0 0 0 1 0 0 ...
0 b. L# d* T% N- k% w##  $ bili    : num  14.5 1.1 1.4 1.8 0.8 0.3 3.2 12.6 1.4 3.6 ...0 k4 j) v; Q" U6 O3 X1 L
##  $ chol    : int  261 302 176 244 248 280 562 200 259 236 ...$ a: L+ U) T7 I) E* l/ V1 A
##  $ albumin : num  2.6 4.14 3.48 2.54 3.98 4 3.08 2.74 4.16 3.52 ...
- y! g$ G( c' b! n7 X##  $ copper  : int  156 54 210 64 50 52 79 140 46 94 ...
# g8 F* w3 L/ g# x# u" ^& N, O##  $ alk.phos: num  1718 7395 516 6122 944 ...) [8 Z4 `7 J5 B8 H
##  $ ast     : num  137.9 113.5 96.1 60.6 93 ...' y* e0 u+ p3 D! r0 s0 ?2 g' m+ Q
##  $ trig    : int  172 88 55 92 63 189 88 143 79 95 ...
! u& T/ P9 _( K# d##  $ platelet: int  190 221 151 183 NA 373 251 302 258 71 ...7 @- B, B: _& v5 C. D
##  $ protime : num  12.2 10.6 12 10.3 11 11 11 11.5 12 13.6 ...
( g% k: o% M7 O9 [; z4 n" R##  $ stage   : int  4 3 4 4 3 3 2 4 4 4 ...
' H" n7 S# N4 w+ l# B# Y" i) l+ I0 [
1- b2 A! O8 y- S' z8 D" N) b7 v  T
dim(dat) # 232 20% T! F$ ~4 d$ N! Q+ U7 I
1
  T# J. I' Q4 u: u8 l. ^## [1] 232  20
" E1 u0 G4 s2 u1' J$ l, l* i9 Z* s2 e& M" z4 n
然后就是准备计算NRI所需要的各个参数。' h9 e6 ]7 ]8 m( i' a( {6 S% N
, d$ h0 V+ z! @/ {& E7 H
# 定义结局事件,0是存活,1是死亡
5 I' P& D! b0 H' e) O) u0 \event = ifelse(dat$time < 2000 & dat$status == 2, 1, 0)' m" t& t# _' V4 Q5 q5 u! D

' q1 L) I$ ^+ J4 `" w# P# 两个只由预测变量组成的矩阵4 b  y, R0 R" L+ l: y
z.std = as.matrix(subset(dat, select = c(age, bili, albumin)))
. i# k! [# x+ [7 K2 {z.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))
4 N/ c' @0 d: w5 }) D* c$ T; h) G  Q; X& U6 ~& v* |5 u
# 建立2个模型- p" q- E( H' K: ]9 q
mstd = glm(event ~ age + bili + albumin, family = binomial(), data = dat, x=TRUE)
8 l+ Y( `% a2 V% ~' y. I8 w& `mnew = glm(event ~ age + bili + albumin + protime, family = binomial(), data = dat, x=TRUE)
9 w' w" F; m1 r5 B5 ~. S
, i1 k/ n$ B# o9 ^' i3 P6 [4 K# L6 C: g( R# 取出模型预测概率
- h. M, P1 ]$ y) R# I, W7 Cp.std = mstd$fitted.values
; W  g# w8 b. k5 v' V" ^9 |p.new = mnew$fitted.values
, V0 ]- M/ \& Z; |: o7 X3 e( l% s. {- p2 q8 [
1
& a) A1 `9 K" i4 }* U1 G& Z& o, U( @( P然后就是计算NRI,对于二分类变量,使用nribin()函数,这个函数提供了3种参数使用组合,任选一种都可以计算出来(结果一样),以下3组参数任选1组即可。 mdl.std, mdl.new 或者 event, z.std, z.new 或者 event, p.std, p.new。2 j# ?1 G4 o0 D$ ?/ m2 T/ G! ^

; p1 k# N/ D$ o' d' V' K- l; _% q# 这3种方法算出来都是一样的结果
- G9 K+ R# _: V" S- x& q7 c: \8 R; i- v
# 两个模型' W5 Q- Z0 ~# C! C9 w5 G
nribin(mdl.std = mstd, mdl.new = mnew,
# g/ ~( o/ \+ I: M. L       cut = c(0.3,0.7), : H: R  A4 Q; z' T" ~
       niter = 500, 6 x2 S% a8 n3 m6 \6 }7 y& p2 K+ q
       updown = 'category')
" Z! ~1 C5 j" L: C
& W# y' v# G' s$ \' h6 j# 结果变量 + 两个只有预测变量的矩阵
- X+ g$ ]8 ?# v' S+ c# K2 Snribin(event = event, z.std = z.std, z.new = z.new, 2 G2 {: i/ Y" l
       cut = c(0.3,0.7), 8 W: S: T5 N# N8 P
       niter = 500, - ?$ z8 h4 c% k+ P  v
       updown = 'category')2 }2 Y; M7 k$ U, S- I4 e) K. U
/ ?* \+ Z  g- s' F( t
## 结果变量 + 两个模型得到的预测概率
  p2 ~5 G+ E) }# wnribin(event = event, p.std = p.std, p.new = p.new,
5 y. _; Q" E/ |+ [( J       cut = c(0.3,0.7), " K- j2 t3 t" i* h/ v6 i
       niter = 500,
) S' _: b6 R, K$ D       updown = 'category')
. ^+ q8 K% l, n( M1 W) L: y: r, d- Q
1+ h" Y! [2 g; R5 g
其中,cut是判断风险高低的阈值,我们使用了0.3,0.7,代表0-0.3是低风险,0.3-0.7是中风险,0.7-1是高风险,这个阈值是自己设置的,大家根据经验或者文献设置即可。
8 }" P% Z  z$ D9 f+ ~5 O- Q5 N: A1 Y
niter是使用bootstrap法进行重抽样的次数,默认是1000,大家可以自己设置。, t3 ]2 o  v2 X4 G

, N. U7 ~0 A; _/ L1 o6 Cupdown参数,当设置为category时,表示低、中、高风险这种方式;当设置为diff时,此时cut的取值只能设置1个,比如设置0.2,即表示当新模型预测的风险和旧模型相差20%时,认为是重新分类。
6 W# u" b3 m' A: h2 _1 s( m- L! y9 p! ^/ x3 o4 n, i9 T* v* @
上面的代码运行后结果是这样的:
# b( k% ^& \% O4 N4 C0 ^
+ V& ]" H/ l0 DUP and DOWN calculation:
/ ?2 f, j/ e6 o0 `& p3 c  #of total, case, and control subjects at t0:  232 88 144+ X; F0 G! U6 c% _; q/ I  d

7 f  A4 r0 E+ n- Z+ T8 d- U  Reclassification Table for all subjects:5 ?; {; G+ J  R# I
        New* Q$ {/ L7 m& F' N4 T
Standard < 0.3 < 0.7 >= 0.7! u/ `  G( b5 K2 ~, f
  < 0.3    135     4      02 H! z- g  V+ Z3 b$ D5 M0 r9 C
  < 0.7      1    31      4
. M. Z" T6 @. B& w  i  >= 0.7     0     2     55
( c" O0 W( [! D# ^
9 }. j5 D# [* x  Reclassification Table for case:
: u6 R! l; Q% Y; g2 }: x        New
! r: z: d9 K$ C0 n. fStandard < 0.3 < 0.7 >= 0.7: Z8 W% A% |6 ?. t2 n6 ]" w% w: e
  < 0.3     14     0      0
7 e9 r0 h+ u+ [, Q  < 0.7      0    18      30 Z3 b1 T. y, [* I8 F
  >= 0.7     0     1     52
5 e* b- |0 q& x: t# \- ~& h* p. ]9 _: [. f
  Reclassification Table for control:
' @, N0 t$ V6 F" j0 s& S- c        New4 ], S0 g' i3 L" m. f4 k: ~3 w
Standard < 0.3 < 0.7 >= 0.7
9 ?6 B) w* e+ S+ q6 B# h' ^' Z7 k  `  < 0.3    121     4      01 E: f6 x5 t' G4 t
  < 0.7      1    13      1
+ ~9 ]4 G( C/ _  >= 0.7     0     1      3
2 @. \5 w1 L7 B# p, [
5 s, k, ]# y5 qNRI estimation:! e% T; [+ {6 s' n! D* d1 n, d$ @4 t
Point estimates:# ~9 N  z/ L; }% c; `
                  Estimate+ g5 J$ A" R$ g( E+ _4 R
NRI            0.001893939
/ J; C- {6 ?& O0 aNRI+           0.022727273
& j; Y& z8 l/ |# \: W. w3 ENRI-          -0.0208333331 `+ o  I, |2 }' f8 o9 E7 a
Pr(Up|Case)    0.0340909090 x6 b0 i2 C- V  I
Pr(Down|Case)  0.011363636; _& p5 H1 y2 O4 [: o, ?. m7 r* ^7 a
Pr(Down|Ctrl)  0.0138888899 P$ R" }0 H6 N% q. b: ^3 |1 j
Pr(Up|Ctrl)    0.034722222
2 p: v- X/ U! ]& T1 }% d
; P* F* s5 n. \+ ?, `9 HNow in bootstrap..  n( s8 u7 A' Z0 L$ D; ]+ t$ h4 V
' W! q: _5 C+ @* k# V
Point & Interval estimates:
  t; m) {5 t& q/ @                  Estimate   Std.Error        Lower       Upper9 j- E5 b7 }4 y8 {
NRI            0.001893939 0.027816095 -0.053995513 0.055354449
( o/ n0 R! Q6 z, @; hNRI+           0.022727273 0.021564394 -0.019801980 0.065789474& Q6 O1 x* W! [& F: b) W
NRI-          -0.020833333 0.017312438 -0.058823529 0.007518797
; g4 g6 w% J0 ^3 ~: B, PPr(Up|Case)    0.034090909 0.019007629  0.000000000 0.0721649482 d4 K7 n, z3 i9 Z  w! Q' N( l
Pr(Down|Case)  0.011363636 0.010924271  0.000000000 0.039603960
2 I7 Y( X0 d( O6 r+ ]4 m. pPr(Down|Ctrl)  0.013888889 0.009334685  0.000000000 0.035211268! Z1 a5 T) f+ J; a
Pr(Up|Ctrl)    0.034722222 0.014716046  0.006993007 0.066176471* m9 L, N! z4 k+ a

. ~# k. f! t+ U! A1- |+ r( T6 a) p4 O. e- p8 c5 s
首先是3个混淆矩阵,第一个是全体的,第2个是case(结局为1)组的,第3个是control(结局为2)组的,有了这3个矩阵,我们可以自己计算净重分类指数。! x- d% ~- x# R% t, H, r# _
  s1 z) z1 |- {# s6 Q" t
看case组:) Z. P) ~; A9 X0 P

; Q4 Y% W6 [9 u: b* I# `净重分类指数 = ((0+3)-(0+1)) / 88 ≈ 0.022727273
3 m2 v, w! h  `- q+ |3 ^# ?' C& k$ e7 P. w' U. x3 |8 {9 c
再看control组:
8 y7 D7 f  @7 p) |9 L1 g6 Q0 V# S4 M/ w) Y6 B
净重分类指数 = ((1+1)-(4+1)) / 144 ≈ -0.020833333
- A- @' u9 k1 ?/ w1 i1 e; W2 \
1 ?# M. _  P! \8 |4 c. ~相加净重分类指数 = case组净重分类指数 + control组净重分类指数 = 2/88 - 3/144 ≈ 0.000315657
6 [8 p& g8 C1 @; e
7 J8 I3 V1 o  A2 l再往下是不做bootstrap时得到的估计值,其中NRI就是绝对净重分类指数,NRI+是case组的净重分类指数,NRI-是control组的净重分类指数(和我们计算的一样哦),最后是做了500次bootstrap后得到的估计值,并且有标准误和可信区间。
% O8 h: f. R6 I7 ~  h6 {* ^' ~7 X2 v1 l/ t8 U' k" G
最后还会得到一张图:
" V  s# u6 G# C: r& D* [, o, F9 L; b/ L: s( V
这张图中的虚线对应的坐标,就是我们在cut中设置的阈值,这张图对应的是上面结果中的第一个混淆矩阵,反应的是总体的情况,case是结果为1的组,也就是发生结局的组,control是结果为0的组,也就是未发生结局的组。
. t+ T1 I3 m, P% b; ?3 V1 M, T7 a* n, d8 H( A0 n1 A' X( D( U$ ]
P值没有直接给出,但是可以自己计算。
  m& @4 `0 N* y4 ^* N
* T( w0 f2 G0 E- A8 p# 计算P值
3 T4 Q7 `) G; L4 q8 L1 Jz <- abs(0.001893939/0.027816095)
9 `5 H2 G8 k, v! |2 d2 }0 }# O- _p <- (1 - pnorm(z))*27 [$ |  w1 c' g1 O
p. ?) k+ c0 w( y8 _- S
1
7 n& V" e6 }7 u' m6 ?* X7 s! S' X## [1] 0.9457157( b- y& x9 S6 n$ A8 e. n
1
: g2 h; v+ [% A2 b$ a: VPredictABEL包( ?5 D9 P: T( M' a! Y
#install.packages("PredictABEL") #安装R包
7 R0 W7 B, {+ g6 Mlibrary(PredictABEL)    d- i8 P5 ?6 z/ P3 v
5 b1 z' z/ ~9 \2 b" k0 W4 d( ?
# 取出模型预测概率,这个包只能用预测概率计算
& T" \7 Z4 h, ^$ Dp.std = mstd$fitted.values) ]$ X- _2 V* P5 y
p.new = mnew$fitted.values 7 c# ]0 o' o+ r. ^8 F# {# \: w
1
# i8 _6 ^4 I$ ?1 L7 y然后就是计算NRI:& T; n1 ]1 I: x. u

9 j- Z0 l6 V0 D& V9 e# {5 tdat$event <- event: U! z- x, C9 [% l$ u

. ~. o' M4 q% S* Dreclassification(data = dat,2 `3 A0 n1 b2 |/ E: R1 m) A$ p
                 cOutcome = 21, # 结果变量在哪一列
4 {# D" M! a7 D# c) M+ q                 predrisk1 = p.std,
# ]+ h; ~6 ^4 ~1 \                 predrisk2 = p.new,
9 b1 b* f' H, w; D5 `+ j& c0 V1 |                 cutoff = c(0,0.3,0.7,1)
' ?5 X2 n% i. [7 E2 v6 w: Y+ E                 ). p+ q* V7 q/ b9 y  G1 @4 J
1
% U9 ]8 L- x3 e$ D##  _________________________________________
5 b" h! L* K* p. J( M##  8 e7 |( I5 h" W3 e5 p  w: n5 ?
##      Reclassification table    : x# Z  j  x4 \$ [
##  _________________________________________- x6 ~( p, ~% O2 D
##
; _: L( @, g. \: Y* P* o##  Outcome: absent + l7 L, ~- `& b% `
##   3 X! o/ P" s  R, B+ f8 h
##              Updated Model
$ v# k" k* g( D7 g  O0 w## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
9 m5 }7 V( j* |8 i  x##     [0,0.3)       121         4       0               3  Y& O% Z2 ?6 ]
##     [0.3,0.7)       1        13       1              138 Y$ N5 e0 B; r2 Q. c
##     [0.7,1]         0         1       3              25
; Q# p- {5 T' B6 P- N/ }# ~## + w. r8 p6 V0 X* G% z
##  
; {4 V; e- f& F9 D# E. m3 I3 |! y##  Outcome: present 6 A* n  S) H# g- t% Y: i3 _
##   
0 d1 {+ M# a2 E% X##              Updated Model* x, {8 Q* [& F) @
## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified
, S, X9 C: P% V##     [0,0.3)        14         0       0               0
( d$ a3 N* C7 Z% n5 T7 W##     [0.3,0.7)       0        18       3              14: a5 {* n1 j- M
##     [0.7,1]         0         1      52               2$ ^- G0 z7 T2 @: }: k
##
& m# e% g4 y2 |1 r& R##  ; {1 E3 F% P% y" K" j: C" t; R0 _
##  Combined Data 3 k  J2 o  F" a. h2 P" H
##   
2 }# j; G" y) g: H  t+ _##              Updated Model( `( w- R- O+ ?/ Q2 P4 {9 c
## Initial Model [0,0.3) [0.3,0.7) [0.7,1]  % reclassified: M6 g9 p4 ?' Z, P  f
##     [0,0.3)       135         4       0               3
, t  u3 V4 Y( O$ P3 T" Y##     [0.3,0.7)       1        31       4              14# m* m% A; X, Z$ g3 L% s4 j
##     [0.7,1]         0         2      55               4
5 V9 ], S7 x4 z8 T# }6 T, Q+ D5 I##  _________________________________________
8 p0 W% I0 \" r# x4 `0 Y/ M##
6 [' d! Z  J8 F##  NRI(Categorical) [95% CI]: 0.0019 [ -0.0551 - 0.0589 ] ; p-value: 0.94806 - F  T, M1 K% l0 @9 o  s! ]
##  NRI(Continuous) [95% CI]: 0.0391 [ -0.2238 - 0.3021 ] ; p-value: 0.77048
6 g1 i, ]) J5 @4 d& Q! ]% E& s/ Z##  IDI [95% CI]: 0.0044 [ -0.0037 - 0.0126 ] ; p-value: 0.28396
  C+ W/ z+ k' S# @. S" _- u4 Q9 \% E: L9 o/ P( I3 L( @+ x
1
  o* o9 \; c& j7 {结果得到的是相加净重分类指数,还给出了IDI和P值。两个包算是各有优劣吧,大家可以自由选择。! {" L! O3 ~& N0 h1 ~/ n. x5 K

3 |7 o+ c$ k1 E; V4 r, M) |) c生存分析的NRI
& _6 B7 P% e2 R  s' S0 d5 z还是使用survival包中的pbc数据集用于演示,这次要构建cox回归模型,因此我们要使用time这一列了。
5 k* L, ?& |  i5 M; B! _1 a. m" D6 P- q: l, U- _9 Z
nricens包
  s! k6 e& N7 R$ alibrary(nricens)* Q; `7 X& e2 `0 n- L# v# u
library(survival)" W5 h# F# }0 L
( n! K+ ]1 p, e2 E
dat <- pbc[1:312,]+ C9 n0 L3 H: [' {+ K& T4 ^( t
dat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡, s, M% E  ~- `  F# r! F
1& S1 \- I4 w8 B! Q" e5 ^2 B2 i
然后准备所需参数:+ `' E9 V* [4 |9 d/ @( n* x( ]
" ]5 @+ ~& B8 t7 I1 T$ V
# 两个只由预测变量组成的矩阵( x+ q+ x+ g2 T" G! b2 O& z& ~
z.std = as.matrix(subset(dat, select = c(age, bili, albumin)))8 ]$ B" j4 q2 a# S) R$ W
z.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))4 [& w) c- W  w1 D

# I( u2 W! T" t% |  i  a. {$ b# 建立2个cox模型* \) t& _) \' o& B6 J6 ]
mstd <- coxph(Surv(time,status) ~ age + bili + albumin, data = dat, x=TRUE)' X* y# i; w( ]: e# n' X5 o$ [
mnew <- coxph(Surv(time,status) ~ age + bili + albumin + protime, data = dat, x=TRUE)
3 W! @  `  {) P) E( j5 U
1 C$ U' i( v( ~6 j, Q  X0 o8 M# 计算在2000天的模型预测概率,这一步不要也行,看你使用哪些参数3 L" ]% J* }, O+ M  R& `8 ]+ N# w
p.std <- get.risk.coxph(mstd, t0=2000)# O1 ?7 `. B2 o8 s# s- A  y# U
p.new <- get.risk.coxph(mnew, t0=2000)
/ C% k7 Z  N* _/ w1# d4 ~: b+ U  k
计算NRI:
8 U; {( s5 M$ }4 Z% u* J& @( u
0 P/ B. d4 S$ Q+ onricens(mdl.std= mstd, mdl.new = mnew, 1 H: I, ^. |) S+ V3 t6 |
        t0 = 2000, 9 ?3 v* p. y+ i0 k
        cut = c(0.3, 0.7),
4 U! L) Y6 D' }3 T, S, C1 L        niter = 1000,
* k( d' [  ~& c+ R        updown = 'category')! T5 \2 U3 L- ]/ p

9 i7 C4 ~. E6 p" hUP and DOWN calculation:% p9 U! @% J0 g$ L  s4 [* O
  #of total, case, and control subjects at t0:  312 88 144
. v# ?" S0 F% a: T% q' c( a2 Q% Y$ s6 W. I  u- h6 H2 r, k
  Reclassification Table for all subjects:
2 w# I  A* y6 `- }        New9 |8 R6 Q1 v9 _* L- T1 k5 k+ M2 Y9 r* g
Standard < 0.3 < 0.7 >= 0.7
# b' B% o0 w) m; }4 U1 C  < 0.3    202     7      0
% i7 w; R! N. \- e* y  q" K" e7 d  < 0.7     13    53      6* K+ z) j, v3 W  Y+ }- f
  >= 0.7     0     0     314 e# n6 d" H9 c0 ^2 ^
  Y3 I+ E! }0 ^
  Reclassification Table for case:- e- e1 t+ j+ ]) J4 N
        New
, q8 x: g6 {& MStandard < 0.3 < 0.7 >= 0.7
1 \( \2 d* h2 w8 C3 V4 f  < 0.3     19     3      05 l* f8 v0 h5 v  N' ]3 k7 @
  < 0.7      3    32      4* h& F& i* B2 X, J" @% m
  >= 0.7     0     0     27
/ Q6 A' F. A  {) k6 Z) F
+ ]7 r. H  e' k! j' x+ \" K- q! o  Reclassification Table for control:
1 x. C: V6 ^, Y3 _, e) F: z        New
8 r- N. w1 l9 ]  X5 @Standard < 0.3 < 0.7 >= 0.70 V2 F- v" T. K0 T7 `. x
  < 0.3    126     3      0
- l8 ^, \+ W! O5 H* Y$ q  < 0.7      5     7      2
+ u  w% }$ h+ K& T# ]# r4 @  >= 0.7     0     0      1
; V5 y9 p7 w# d7 _( e0 c) V) u
NRI estimation by KM estimator:9 i. T; E! B" _
8 p- G& f' Q6 \3 t7 R7 U% J: j
Point estimates:: f/ |' @+ X  i1 ]0 M- w. f/ q
                Estimate+ }- V8 _3 K4 d
NRI           0.05377635
3 ~  n1 V8 }0 c7 I& i' YNRI+          0.03748660: x0 a6 t( y# L- d9 Y
NRI-          0.01628974
: @+ r  B4 [" x. `9 ^( I0 APr(Up|Case)   0.07708938
1 X( _) Y7 ]: m; KPr(Down|Case) 0.039602780 Z# {+ t% H/ G, A1 p: x9 l; D( p  p
Pr(Down|Ctrl) 0.04256352
' [, Q# ~. c, I$ qPr(Up|Ctrl)   0.02627378
  S% g+ g7 Q( c
& V1 O4 z- O0 ZNow in bootstrap.., S# N4 c' O9 F) P# `

# r1 e, Z  y. lPoint & Interval estimates:
3 V1 R  Q6 g: x0 s                Estimate        Lower      Upper6 W6 z4 d. T8 g( E
NRI           0.05377635 -0.082230381 0.160581723 F7 p, M2 h4 ~+ l& k* _
NRI+          0.03748660 -0.084245197 0.13231776
6 |/ S5 i5 Y* C. sNRI-          0.01628974 -0.030861213 0.06753616, f& K  F; a! t
Pr(Up|Case)   0.07708938  0.000000000 0.191022912 [8 N& j) `9 L% ?! w" R
Pr(Down|Case) 0.03960278  0.000000000 0.15236016, C2 i$ p0 ?" B: A2 u
Pr(Down|Ctrl) 0.04256352  0.004671535 0.09863170
8 l, X8 E$ J" M! Z% KPr(Up|Ctrl)   0.02627378  0.006400463 0.05998424
( \2 d4 D5 E+ L4 W5 U: a3 H. l5 S
7 ]6 c7 `7 s# V9 E! x  S1% E% z# X+ j) D! S4 G

5 ]! |( b8 g! V) XSnipaste_2022-05-20_21-49-38" F, i7 z: ^6 e+ [6 i" L
结果的解读和logistic的一模一样。7 r. C  {1 I" Z) l

2 ~" u3 S; `9 L( R7 P$ A$ z$ x0 zsurvNRI包; }; q' G. r. X. q- g
# 安装R包
  k2 e' W1 ~- Y. Z* u4 i2 adevtools::install_github("mdbrown/survNRI"): d( [3 ^* D3 {  D
1
0 G3 G" b6 _9 c/ i. L, U$ n2 E加载R包并使用,还是用上面的pbc数据集。
( ^9 G, n2 g" T. T
$ H& _9 J) M( X2 N1 a& u! Y( Wlibrary(survNRI)
: p! L4 a9 u* Y) D  @1$ q4 D/ V7 M3 @. D5 k
## Loading required package: MASS
* j5 n1 f/ ^; d! X; c1! A8 ]# K, V  m' Y# W
library(survival)
  I* D4 n$ E3 F: C9 A
5 n  E2 i* V5 P& |2 q' i. Z# 使用部分数据9 U, x; V4 F2 F7 p7 a- G, r/ B& g4 `
dat <- pbc[1:312,]
6 M2 j0 S* e& [dat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡
7 }% U. Z+ _9 {. s
! Y7 B/ g; S9 J; Cres <- survNRI(time  = "time", event = "status", , q& `; P0 H4 Q9 N: B9 n5 |1 C
        model1 = c("age", "bili", "albumin"), # 模型1的自变量; L" R3 @4 \- U7 D8 J) o
        model2 = c("age", "bili", "albumin", "protime"), # 模型2的自变量
& m; h: ]8 H% t3 N        data = dat,
+ p# \3 w* R  }! f6 m6 h        predict.time = 2000, # 预测的时间点' v# p  ^( ^2 d. u, [2 m
        method = "all", ! Y5 J1 f6 u2 @& {8 N) L
        bootMethod = "normal",  
8 ?8 R( n0 f7 ~        bootstraps = 500,
% t. Z$ o: {  ~) V        alpha = .05)* A- N) L9 h& _+ M" [: n

. Z1 ^$ u: H3 f; R* j1 e1; j7 q6 B9 Q+ f. Z8 a& Y- Y$ f
查看结果,$estimates给出了不同组的NRI以及总的NRI,包括了使用不同方法(KM/IPW/SmoothIPW/SEM/Combined)得到的结果;$CI给出了可信区间。
3 Q6 C  t5 Z2 p6 d/ E* n
9 H" h) f5 Q, g9 ]4 w' wres& Y4 \; O- N  L2 O; I% c1 v! ], s
1
& F' j; Y0 J0 P! M4 u## $estimates
$ J; U1 w3 B: K" }7 O$ w; W7 p1 j+ U##            NRI.event NRI.nonevent       NRI$ x9 {' `4 d3 `" K, A- ?, b
## KM        0.20445422    0.3187408 0.5231951
# v0 @: i* M5 a+ B' c3 Y% h- w## IPW       0.22424434    0.3273544 0.5515987
4 ^  D5 S& s1 Z! s' o$ K) a## SmoothIPW 0.19645006    0.3144263 0.5108763' F( u, a+ Q  Y- ]5 l! W
## SEM       0.07478611    0.2632127 0.33799881 }: K3 e5 O; |' `3 X
## Combined  0.19633867    0.3143794 0.51071811 k  D5 ^, e' a; _; Y
## ; {, C( T; ]7 ^( {& Q: w
## $CI* S  n) [9 b4 m9 s% G
## $CI$NRI.event
0 u6 N9 R) H9 f, y##                     KM         IPW   SmoothIPW        SEM   Combined
9 }' R% V6 C) k4 g6 s, P. @## lowerbound -0.03915924 -0.02185068 -0.04724202 -0.1162587 -0.0473723
; _9 E' l& V, p( g. K. S! e0 u## upperbound  0.44806768  0.47033936  0.44014214  0.2658309  0.44004962 v6 @, z3 i; }  q
## 4 |% A9 k2 c! k5 h" a6 N
## $CI$NRI.nonevent
1 Q/ c, h% }. r##                   KM       IPW SmoothIPW        SEM  Combined. g+ D5 U* E; b+ K1 W+ F
## lowerbound 0.1317108 0.1396315 0.1286685 0.08638933 0.1286426( g& P2 N2 W9 A  n6 h0 Z* L' p& S
## upperbound 0.7102251 0.7393216 0.6966341 0.51482212 0.6964549; |! ~: l6 |7 k7 K
## 8 `- C0 R" M, O1 B( j$ U2 ~
## $CI$NRI
# w- n6 {0 l# D- [##                     KM         IPW   SmoothIPW         SEM    Combined
- ^* H8 w; G0 d+ N# k## lowerbound -0.05112533 -0.04569046 -0.05439863 -0.04132364 -0.05443409
/ @/ ?7 ~- |6 W; D& }, X0 d## upperbound  0.89306122  0.92464359  0.87970125  0.64253510  0.87953153+ p7 `4 u  f# o) P
## ; P7 J( X- [4 h7 B/ l" `
##
4 b+ O/ N$ X% L( Q+ b8 [## $bootMethod
- ?" G" B* s/ I! P2 a* r" m2 S7 \% j## [1] "normal"& L$ E4 M* ?/ C! q6 f% V& I4 d
##
6 }0 I) O7 l9 S+ U## $predict.time
+ v2 w1 V3 h$ z+ v9 @# T## [1] 2000
& l3 R5 P/ n5 e. N##
! V: p7 q7 G+ D## $alpha2 y3 p5 ?) J% Z. U$ x" k( p4 ]
## [1] 0.056 @/ s: @& ?' v; y  \
## * u* H0 i& l/ K: J9 P) T- F
## attr(,"class"); d( x/ o' }5 b1 Z& N* P. J
## [1] "survNRI"1 O3 \/ D7 o4 Y9 g4 e

7 m: T* C+ \6 u% b1
- u2 t# t" i0 w6 J! b$ cOK,这就是NRI的计算,除此之外,随机森林、决策树、lasso回归、SVM等,这些模型,都是可以计算的NRI的,后面会继续介绍。大家如果有问题欢迎在评论区留言。- K2 O, r% V* H9 p5 c* C3 O

: n1 c7 H5 S3 J  Y" z, Z0 g本文首发于公众号:医学和生信笔记" q4 U+ ~) j% ]" ?  D0 t8 a1 z  o

% y# D, e/ ^: l& ^“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。1 T3 C1 Y$ p. [
本文由 mdnice 多平台发布  [% h& P6 Q7 A
————————————————, U6 c6 o1 \0 g2 I
版权声明:本文为CSDN博主「阿越就是我」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。% u- W2 D& o& A- _; k2 a3 o: c
原文链接:https://blog.csdn.net/Ayue0616/article/details/126768006
% j9 n1 T" S1 K0 t9 E
, v9 [, ^# ~, N* Z: {# ?* n0 [# [, B" i





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