数学建模社区-数学中国
标题:
净重新分类指数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 E
PredictABEL包
4 ]9 w" H( T& y
生存分析的NRI
2 n) R- J& i" u* C: R: @5 Q
nricens包
: g' v5 N, d& h: i1 B4 F+ `: f
survNRI包
9 o1 d K" Z. q
logistic的NRI
9 p& f% T; a- {8 J2 C2 Q
nricens包
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 Z
1
, 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; P
library(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 o
str(dat) # 数据长这样
& l1 z1 h7 S6 g. D. H8 z
1
" 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 q
1
# 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% r
1
" 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 r
z.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 E
p.std = mstd$fitted.values
% A0 u, ~# _+ K5 G
p.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 w
nribin(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, M
nribin(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 h
1 ~; 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! ^) v
niter是使用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 144
3 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 [
New
6 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* n
Standard < 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 52
1 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 3
6 \/ Q2 P9 y2 s" G0 `4 R9 \
# a& J, l( `6 k" b) b A
NRI estimation:
q8 t' y# |9 U* ?. i
Point 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 Y
NRI- -0.020833333
9 F: N8 L- b* d' J
Pr(Up|Case) 0.034090909
* w v& p* [ O* @6 t" r5 l2 g
Pr(Down|Case) 0.011363636
" G. F' s9 o' j7 {
Pr(Down|Ctrl) 0.013888889
8 u$ n ]% e6 f$ ]: [ [
Pr(Up|Ctrl) 0.034722222
- F9 ]/ d! @) M; {* O) t
4 L& O6 o& S8 I" Q# W) W
Now 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.055354449
6 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; G
Pr(Down|Ctrl) 0.013888889 0.009334685 0.000000000 0.035211268
1 t6 s% U4 |! U0 j7 o
Pr(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+ |( {, D
1 ]" 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 k
P值没有直接给出,但是可以自己计算。
+ 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 V
p <- (1 - pnorm(z))*2
: Z( g! q8 M9 N
p
1 u. g1 `1 I, Z) I; }
1
4 T4 n. X6 @' ~& [% o
## [1] 0.9457157
3 X3 k4 V$ `- ^& W1 p7 M' x% r8 F
1
U p9 F: O+ g' v* [: c
PredictABEL包
% { 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 A
reclassification(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 2
2 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 4
5 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 N
1
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
生存分析的NRI
2 w" c+ J6 r. |
还是使用survival包中的pbc数据集用于演示,这次要构建cox回归模型,因此我们要使用time这一列了。
. v. n% F4 U1 G( Y0 `, q
) v# H$ ^/ E3 w8 ~% D4 F6 N
nricens包
! Z) B4 `7 K2 T- S& k5 z7 z
library(nricens)
$ s3 }- V$ m" V
library(survival)
) M* K. U2 f8 `
- I h% S* _4 @: e4 r
dat <- 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 @ \* {
1
2 _% 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 Q
z.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& H
mstd <- coxph(Surv(time,status) ~ age + bili + albumin, data = dat, x=TRUE)
$ a) d3 z9 j/ E6 k
mnew <- 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 X
p.new <- get.risk.coxph(mnew, t0=2000)
2 _, m7 ~' `$ l/ g
1
+ ^. I9 D* Y2 r/ y
计算NRI:
# ~1 `- K5 d4 d1 f, W) c T
' j, Q+ T. }1 Q
nricens(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- M
UP and DOWN calculation:
0 x7 Q+ ?& p) c5 X' |
#of total, case, and control subjects at t0: 312 88 144
3 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 T
1 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; y
Standard < 0.3 < 0.7 >= 0.7
! _+ k( ]* }( Q3 w: a
< 0.3 19 3 0
( K: {& T( U$ j# @
< 0.7 3 32 4
5 x& r) ]7 m; d( j& z
>= 0.7 0 0 27
1 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% S
Standard < 0.3 < 0.7 >= 0.7
+ o2 y' q& D0 ^9 \
< 0.3 126 3 0
1 W8 p$ w3 u% ^: m
< 0.7 5 7 2
8 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# [" } G
Point estimates:
- _/ M/ o. m4 X" E: \. [
Estimate
Z8 F# B+ ^( E/ @ g! s
NRI 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 r
Pr(Up|Case) 0.07708938
0 o* J# T9 X, N: C, J
Pr(Down|Case) 0.03960278
5 v }/ A/ q1 K- w( e
Pr(Down|Ctrl) 0.04256352
5 w9 a7 a" o& ]
Pr(Up|Ctrl) 0.02627378
- g1 G! c8 ^1 P+ Q: f# m/ V
7 e, {; j: y% d9 j }: h
Now 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 Q
Pr(Up|Case) 0.07708938 0.000000000 0.19102291
1 m; g3 k; Y+ H
Pr(Down|Case) 0.03960278 0.000000000 0.15236016
9 c8 T+ ?5 b2 A0 A
Pr(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$ J
1
3 M9 _. V3 Y9 B `5 h9 H
: |" i: @. ^& I; ]" p
Snipaste_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 {" z
survNRI包
! \; 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 g
library(survNRI)
/ }. \1 O) V, @7 I/ Q4 g$ _
1
3 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% f
dat <- pbc[1:312,]
3 G0 ?7 q& S9 m9 C$ W# b
dat$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& E
0 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 ^& P
res
3 q; L- Q- N9 O& k s& I. |
1
7 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.5231951
3 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.event
1 `/ 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.nonevent
4 \1 X, G' @3 X& U
## KM IPW SmoothIPW SEM Combined
2 ^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.6964549
7 B& y( ^3 z9 K; W- R/ A" x
##
6 |# P" q* t6 z$ I2 h& C( v
## $CI$NRI
1 r4 ~ ~/ h: v$ T
## KM IPW SmoothIPW SEM Combined
8 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] 2000
9 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.05
2 _" \) 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( H
OK,这就是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