- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 566252 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 175098
- 相册
- 1
- 日志
- 0
- 记录
- 0
- 帖子
- 5313
- 主题
- 5273
- 精华
- 3
- 分享
- 0
- 好友
- 163
TA的每日心情 | 开心 2021-8-11 17:59 |
|---|
签到天数: 17 天 [LV.4]偶尔看看III 网络挑战赛参赛者 网络挑战赛参赛者 - 自我介绍
- 本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。
 群组: 2018美赛大象算法课程 群组: 2018美赛护航培训课程 群组: 2019年 数学中国站长建 群组: 2019年数据分析师课程 群组: 2018年大象老师国赛优 |
3 N, S! `3 T) v# s9 h+ g净重新分类指数NRI的计算, w3 r- {8 O( Z
“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。
; x3 z1 b1 t$ c' o+ u# tNRI,net reclassification index,净重新分类指数,是用来比较模型准确度的,这个概念有点难理解,但是非常重要,在临床研究中非常常见,是评价模型的一大利器!1 O& e: d9 v7 t2 v
, Y: B/ Y# R' \1 D/ m- W: ]4 J
在R语言中有很多包可以计算NRI,但是能同时计算logistic回归和cox回归的只有nricens包,PredictABEL可以计算logistic模型的净重分类指数,survNRI可以计算cox模型的净重分类指数。
# v+ i' i+ w* _( t% f
/ q: m/ k4 I: qlogistic的NRI
. X5 ?( Y9 Y8 M) \/ enricens包& C4 O( E6 m: q# K- Z+ w
PredictABEL包
t- m0 i+ L# N) D& _% V8 v生存分析的NRI
, o9 ~, T; @6 c# j) `nricens包- J% `( s' Y: u+ {! W3 y- Z
survNRI包
1 z5 {) ~- x) `; ]( c a9 ?logistic的NRI
# x* H2 D4 |+ B0 B, u. [9 U% Qnricens包
$ ]: P; d0 n p#install.packages("nricens") # 安装R包& r" a1 g w$ X5 }8 Q3 w+ {1 v
library(nricens)
9 D2 {. R3 L# z) g' a+ ? R1$ w/ {& m; y% h/ t# k5 {" b
## Loading required package: survival
0 w0 E( d0 t% o1
" ]- f8 `1 t+ @' Z% J. t" c使用survival包中的pbc数据集用于演示,这是一份关于原发性硬化性胆管炎的数据,其实是一份用于生存分析的数据,是有时间变量的,但是这里我们用于演示logistic回归,只要不使用time这一列就可以了。
6 P$ w) K7 m9 X1 I/ C
2 q$ C; [6 U: O) H/ q( @: Ylibrary(survival)
; B& H- E7 F( g! z8 Y/ g! p
0 E" Q9 |$ {, l+ S# 只使用部分数据
( C" M0 y/ i5 j- x- G% [dat = pbc[1:312,] " ` ]. q" s" g' N6 Z/ D
dat = dat[ dat$time > 2000 | (dat$time < 2000 & dat$status == 2), ]4 S G6 m( m5 y1 R% v4 A2 n
8 |7 }7 S( ]8 H) x* r$ O% n8 Z
str(dat) # 数据长这样
* ]0 q r" E+ d7 f* V8 }; Q, T1& q. r7 P- V E- p- [2 ]5 N1 q
## 'data.frame': 232 obs. of 20 variables:
3 _. @+ g" t# s## $ id : int 1 2 3 4 6 8 9 10 11 12 ...
' H. {/ L' ^ O6 h4 k% T## $ time : int 400 4500 1012 1925 2503 2466 2400 51 3762 304 ...
+ j1 U& e" A" t$ W& ^! n## $ status : int 2 0 2 2 2 2 2 2 2 2 ...
) W& v8 M' A6 T: a& v4 }* m% i## $ trt : int 1 1 1 1 2 2 1 2 2 2 .../ l2 j, b E6 Y
## $ age : num 58.8 56.4 70.1 54.7 66.3 ...& Z7 I; g3 u3 x4 z
## $ sex : Factor w/ 2 levels "m","f": 2 2 1 2 2 2 2 2 2 2 ...- ]6 Y- Q+ Q5 w1 M$ i; R* c5 [
## $ ascites : int 1 0 0 0 0 0 0 1 0 0 ...4 H f6 e' t* F! {( ^
## $ hepato : int 1 1 0 1 1 0 0 0 1 0 ...! |7 U( }# M0 o7 ^. w
## $ spiders : int 1 1 0 1 0 0 1 1 1 1 ...
% ~0 a; @5 Z9 h1 q* g* C* K## $ edema : num 1 0 0.5 0.5 0 0 0 1 0 0 ..., P/ [: f. j: \. L* P: D; Q
## $ bili : num 14.5 1.1 1.4 1.8 0.8 0.3 3.2 12.6 1.4 3.6 ...+ W3 d+ c/ I' W+ A
## $ chol : int 261 302 176 244 248 280 562 200 259 236 ...
5 Z( d, u3 Q: p5 k U, ]1 R6 [## $ albumin : num 2.6 4.14 3.48 2.54 3.98 4 3.08 2.74 4.16 3.52 ...# w' u" m5 R& S" p
## $ copper : int 156 54 210 64 50 52 79 140 46 94 ...
3 L. ~) A6 s7 i4 p ?+ a## $ alk.phos: num 1718 7395 516 6122 944 ...4 n( D! b k4 t8 Z$ b9 y. o
## $ ast : num 137.9 113.5 96.1 60.6 93 ...& \/ J, d# S5 I D
## $ trig : int 172 88 55 92 63 189 88 143 79 95 ...
1 v {. U: |7 E* `## $ platelet: int 190 221 151 183 NA 373 251 302 258 71 ...
( V% z9 { y% v$ U2 T* T9 @## $ protime : num 12.2 10.6 12 10.3 11 11 11 11.5 12 13.6 ...9 |! U5 I7 K3 `$ a
## $ stage : int 4 3 4 4 3 3 2 4 4 4 ...2 S/ T& o6 ]: `1 _. c) b6 K8 d
$ H% M; a, ?7 e! D1 N3 F9 h
1" g+ p. ]% t! t+ i
dim(dat) # 232 20
. X# Y. G; c& b- {: d& T1 @1
8 J- q2 I, @' y/ M2 {3 l- ^## [1] 232 207 u; c+ r; i \3 q" X
1
6 T x2 `' l+ ^4 V# d. A然后就是准备计算NRI所需要的各个参数。" e8 Y& N: p8 @# D
% D" j7 P% v5 |. p+ U+ j# 定义结局事件,0是存活,1是死亡2 }0 p/ w0 c& U
event = ifelse(dat$time < 2000 & dat$status == 2, 1, 0)
: E3 Z! b I" j# t5 n2 H7 x" [) q& X6 W( m* B
# 两个只由预测变量组成的矩阵' s: |! m4 m* P! v: v* _
z.std = as.matrix(subset(dat, select = c(age, bili, albumin)))& J7 O2 ^6 z4 z N9 X4 L
z.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))
4 I7 S( k( }% C3 X1 Z% r3 q7 x. g
' o8 I/ n1 t3 d9 w \# 建立2个模型3 e2 e/ I! ~8 t) W
mstd = glm(event ~ age + bili + albumin, family = binomial(), data = dat, x=TRUE)
0 z0 l2 {* i: J& l! S/ `mnew = glm(event ~ age + bili + albumin + protime, family = binomial(), data = dat, x=TRUE)
C2 {8 P8 }% X5 ^4 C! g: F4 W6 }1 X5 I& n
# 取出模型预测概率; }" K0 C- e# [: G* F( z
p.std = mstd$fitted.values y+ y; D9 E8 q2 m' ]- }
p.new = mnew$fitted.values& e; `4 t9 p0 I2 |
+ I# y5 F: [8 j# ]3 w9 A7 O7 {
14 O1 j# Z! [0 X6 ]/ O) X
然后就是计算NRI,对于二分类变量,使用nribin()函数,这个函数提供了3种参数使用组合,任选一种都可以计算出来(结果一样),以下3组参数任选1组即可。 mdl.std, mdl.new 或者 event, z.std, z.new 或者 event, p.std, p.new。, r; [: D( w, _/ {
& L8 H2 i4 `+ B1 t* e* I2 A! y
# 这3种方法算出来都是一样的结果& [; a/ a Y6 x! U3 b3 f
% M/ K* ?4 n5 S
# 两个模型- n* v1 j: k' Q- B) _) Y
nribin(mdl.std = mstd, mdl.new = mnew,
0 R. F/ C* {1 f* u# h; ? cut = c(0.3,0.7), * D: Z8 |1 F' v
niter = 500,
( [9 r4 ~% ?! k% K: S updown = 'category')
/ m' L9 k- L7 p) o, R
2 l5 v% f" W+ u+ l: G1 D! H2 |( g# 结果变量 + 两个只有预测变量的矩阵
# q% C( e9 C- \4 u, R8 U3 u7 Ynribin(event = event, z.std = z.std, z.new = z.new,
7 C/ m8 M2 ~% v) i S. |/ j cut = c(0.3,0.7),
9 {8 {/ F2 N Y6 N% [$ v% I niter = 500,
+ p6 j% M0 _! j updown = 'category') d4 v" v- z0 r: r2 N9 M8 w* S
* C3 o2 h. E* z& o) O. D' |% a) T
## 结果变量 + 两个模型得到的预测概率
/ v# A1 @( B7 k1 q2 r2 S1 Qnribin(event = event, p.std = p.std, p.new = p.new, 3 \$ ~* N7 B( p9 C. p" @( D
cut = c(0.3,0.7),
" {' M8 V8 L8 P) `7 A niter = 500, 5 s7 M6 t1 X- X' _
updown = 'category')! }; z# }( |4 [. |) S. w
4 Z9 [% ~: ^: W. }" D# F1
3 w! V9 g6 o; m其中,cut是判断风险高低的阈值,我们使用了0.3,0.7,代表0-0.3是低风险,0.3-0.7是中风险,0.7-1是高风险,这个阈值是自己设置的,大家根据经验或者文献设置即可。2 v* L! C# d, s! L) [
; X6 }& n. Y8 G A# {
niter是使用bootstrap法进行重抽样的次数,默认是1000,大家可以自己设置。& R; [& y6 b* R8 z
% h& |, v- Q* p* s2 T# ~
updown参数,当设置为category时,表示低、中、高风险这种方式;当设置为diff时,此时cut的取值只能设置1个,比如设置0.2,即表示当新模型预测的风险和旧模型相差20%时,认为是重新分类。
% ~5 h" r( n4 |% s3 _4 e- v- g& J% G* |
上面的代码运行后结果是这样的:
* \( W$ b, f9 u. r9 k% G# j3 s
) v- t: k* s* q5 \+ X" tUP and DOWN calculation:
1 z: ~0 a1 }# A #of total, case, and control subjects at t0: 232 88 144# [. o6 @# B/ N+ q! Q
% Z5 i* b, t1 y2 z Reclassification Table for all subjects:
9 m5 _" x) q+ ?! z5 J. F6 M New
0 a. u- e6 s/ q7 |( C- W& _Standard < 0.3 < 0.7 >= 0.7
) _/ r+ V0 V P- B' w3 O < 0.3 135 4 0
# I. T8 E) D2 h( F9 ~8 \ < 0.7 1 31 4
/ S% L! ?" G8 F9 t/ z M2 y >= 0.7 0 2 553 M6 f: v, N! n
" S+ Z. h1 G6 J( K/ }- k7 W* ` Reclassification Table for case:: w* @& g4 T! `& ~) f6 D- n. c: h! d
New
3 T. w* b1 V6 i0 w8 Q/ n5 f! \4 e/ hStandard < 0.3 < 0.7 >= 0.7
3 E- M- |, ]7 X( \% S. U3 K* l < 0.3 14 0 0
1 y" Q' T; D7 z) e% s# J Q < 0.7 0 18 3
$ I7 P/ {2 M9 I, L9 w$ P >= 0.7 0 1 52
) l4 O8 X9 O* G: w$ p. N/ I5 c. G6 a9 H
Reclassification Table for control:+ e( U3 D' t- P8 N2 J
New: s% W# Y( d. x2 ?" p6 m4 a
Standard < 0.3 < 0.7 >= 0.76 L* S2 S" K8 o$ X$ `% ^& U4 x
< 0.3 121 4 0$ [4 K$ s$ Z' ]1 O5 _
< 0.7 1 13 1
% l) {. z7 D( ~ >= 0.7 0 1 3
6 V% \1 }3 a$ w1 m
$ t+ N1 p: S7 |( f f3 l" D2 h! z/ m2 hNRI estimation:0 w2 n# H0 J7 E' i& v' p) [1 M) w
Point estimates:" M' Z1 P1 j+ t. g' b# K' X
Estimate% W: [, ~( \; O+ k# u
NRI 0.001893939
- d6 i% F5 l' KNRI+ 0.022727273* g) W, Q0 R* O5 F% @
NRI- -0.020833333
- L/ F6 x9 }1 p% Z/ MPr(Up|Case) 0.034090909
. L9 v7 A V* Y& j. |Pr(Down|Case) 0.011363636
% V. f+ q/ Z) v) ]6 J$ i* SPr(Down|Ctrl) 0.013888889. Y* |0 P( z( ?, g, q+ v
Pr(Up|Ctrl) 0.034722222
6 d" J5 \1 B% y5 h; e9 o1 X5 m/ {7 ?; m
Now in bootstrap..
1 T) t& j$ \3 m5 ^; p% m
& w, w' x6 d: H. {; JPoint & Interval estimates:3 D; Z4 A" d4 b8 a9 R
Estimate Std.Error Lower Upper" y( w/ O! F% |
NRI 0.001893939 0.027816095 -0.053995513 0.055354449
( z3 G) R) \( x1 W4 Y9 ONRI+ 0.022727273 0.021564394 -0.019801980 0.065789474
?0 I5 i/ _7 \: g0 yNRI- -0.020833333 0.017312438 -0.058823529 0.007518797
* G; W, ^! V1 L, \Pr(Up|Case) 0.034090909 0.019007629 0.000000000 0.072164948' z$ D! p5 p9 v: S: R) v b
Pr(Down|Case) 0.011363636 0.010924271 0.000000000 0.039603960
* u; u' g+ x0 _Pr(Down|Ctrl) 0.013888889 0.009334685 0.000000000 0.035211268+ b' _8 D2 k- l" |$ X+ }) S: n
Pr(Up|Ctrl) 0.034722222 0.014716046 0.006993007 0.0661764716 X- Z5 R4 {9 Z T) h7 N
: ?. h- F8 ~+ `' Z" [2 [$ F$ N1
$ ?, y ?2 t5 R' T. C' D首先是3个混淆矩阵,第一个是全体的,第2个是case(结局为1)组的,第3个是control(结局为2)组的,有了这3个矩阵,我们可以自己计算净重分类指数。
b9 S' D" b' j/ `( P' j
: c; Z+ t. t! t看case组:
. I* @" K' q, H1 S. u/ u8 h* @ ]) c* `* Q( ]& }
净重分类指数 = ((0+3)-(0+1)) / 88 ≈ 0.022727273: {3 p. T. E& Z6 y2 X; @5 u$ ^
# F4 W9 r" r; p! ]+ }+ m
再看control组:+ S$ e# t7 U3 C$ G
/ v: s' w* d( F: {; S净重分类指数 = ((1+1)-(4+1)) / 144 ≈ -0.020833333
/ h6 |4 \+ V4 n$ I2 N" p8 y
/ x6 s2 r- n, d9 p" v" ~相加净重分类指数 = case组净重分类指数 + control组净重分类指数 = 2/88 - 3/144 ≈ 0.000315657& H, _( G3 ?# Z
- O! c# S, ?( Z, Z$ s再往下是不做bootstrap时得到的估计值,其中NRI就是绝对净重分类指数,NRI+是case组的净重分类指数,NRI-是control组的净重分类指数(和我们计算的一样哦),最后是做了500次bootstrap后得到的估计值,并且有标准误和可信区间。
/ {" n s# k2 q: t. Y1 U( z) O* p
最后还会得到一张图:
6 t2 a2 m/ V2 k" |! c( B
! \# L) m' ^) N. ~: v+ y+ l这张图中的虚线对应的坐标,就是我们在cut中设置的阈值,这张图对应的是上面结果中的第一个混淆矩阵,反应的是总体的情况,case是结果为1的组,也就是发生结局的组,control是结果为0的组,也就是未发生结局的组。
* r5 L& Q( R* p g/ \7 _9 l" y6 a$ o- A# [6 [; O$ S3 R
P值没有直接给出,但是可以自己计算。6 `& R- k1 [( r; Q/ p
, l% E/ l3 ?- V% j" W5 I0 o9 E# 计算P值
7 ^& Q6 S' E+ j9 H% e- `9 |$ Q) tz <- abs(0.001893939/0.027816095)
1 n. ^: X" @/ pp <- (1 - pnorm(z))*2
6 G) |% D$ e% \0 w3 Ep
# {& {) X( _* l; x6 j( A; i1
7 \+ W) z4 G1 H7 P4 x## [1] 0.9457157
; P8 @7 D1 e1 ?6 u! D16 M; j4 w! h5 w, h1 }9 W
PredictABEL包
' o' {! E! |- ]2 N5 j1 h+ K#install.packages("PredictABEL") #安装R包
: Y* x& R/ L3 L6 ulibrary(PredictABEL)
% x9 x7 p8 s0 s9 w/ q; z6 {: m5 S; P
# 取出模型预测概率,这个包只能用预测概率计算$ s/ i3 E6 W" }& c7 `
p.std = mstd$fitted.values
' A {) v, _6 Q a, t( D5 q% ap.new = mnew$fitted.values
# [; u, }0 ~9 \" a7 T1
7 A1 {$ V1 i5 W0 j# m( f1 J然后就是计算NRI:7 J' d+ f" U) I7 S
- g; H) n4 |. e
dat$event <- event- T$ a' O$ p8 M5 z3 e
: y; O9 H) C% J8 E
reclassification(data = dat,
5 F" I' _$ L- ~9 x cOutcome = 21, # 结果变量在哪一列
$ H5 F) m1 j$ S predrisk1 = p.std,
2 ]7 L; k2 s: P9 r% g# d% j predrisk2 = p.new,
6 H$ A8 O" r; G cutoff = c(0,0.3,0.7,1) R7 o, F: V" h/ m/ k, ^" s
)
" U+ e4 h K- t3 `12 @! Z, _- \+ W' Z% z
## _________________________________________7 p- P: s5 i Y
##
% K E; |9 }( C) ~) F, Y$ w## Reclassification table
! u6 o4 c: t& b+ Y$ C## _________________________________________" J! k/ S& b+ o Z7 v: X
##
/ h+ F Q0 i6 ~. M0 Q5 b## Outcome: absent
) |4 O: A# e$ d## # C: X$ N& h: ]6 I1 ]& u
## Updated Model# M* u( b1 [) E' S& z* i3 q( U9 P
## Initial Model [0,0.3) [0.3,0.7) [0.7,1] % reclassified, b, N+ M! k. j4 L7 g8 W4 a
## [0,0.3) 121 4 0 3
( w7 E( u0 i! S& }3 k" m## [0.3,0.7) 1 13 1 13! J k$ N3 g* H/ M9 z$ j* [% r
## [0.7,1] 0 1 3 25
; w6 K" X: F% [0 N6 g##
0 B9 p* N0 h( F* I## . s& T* R) W6 f# \: b, M
## Outcome: present
( r5 H4 u7 G9 `' G4 v& z##
2 ]- [% \; k/ I O8 Y! d## Updated Model8 G3 Q/ f6 \1 c4 r5 F
## Initial Model [0,0.3) [0.3,0.7) [0.7,1] % reclassified
1 j4 t. q! T i: e, k0 v2 V( L## [0,0.3) 14 0 0 0* K$ L7 S% G# d6 t
## [0.3,0.7) 0 18 3 14; p0 `& e3 ~9 h, h$ v( \
## [0.7,1] 0 1 52 2
( ]7 z" l6 w h: b6 L5 N- n& A##
7 D# i$ t/ Z4 V& t##
4 U$ g. T" ^/ T* j. Y## Combined Data
" J2 X+ B/ y: u7 a" ]4 u6 @# o##
8 D/ d& B9 p9 N5 V6 `+ \## Updated Model0 R6 [! Y9 n% b' J4 B/ S' w
## Initial Model [0,0.3) [0.3,0.7) [0.7,1] % reclassified0 p" x/ i K& V
## [0,0.3) 135 4 0 3
* l9 g/ h% m2 |/ G2 _/ Z## [0.3,0.7) 1 31 4 14
D+ f& ^9 Q! v$ l+ B$ [% v## [0.7,1] 0 2 55 4
) k3 G# m* O% v## _________________________________________
. O* R' t" a6 \$ M, J/ q+ s## / t w1 G/ c7 b
## NRI(Categorical) [95% CI]: 0.0019 [ -0.0551 - 0.0589 ] ; p-value: 0.94806
i& [6 W7 R# k6 i+ b, M## NRI(Continuous) [95% CI]: 0.0391 [ -0.2238 - 0.3021 ] ; p-value: 0.77048
% ]0 @9 i7 {$ F0 Q S r% d## IDI [95% CI]: 0.0044 [ -0.0037 - 0.0126 ] ; p-value: 0.28396; W5 U: Y! q# J+ F9 D7 l- D$ o) \
7 X% L, \2 \1 \: n1- C: z3 z6 d0 y- u3 Y& K
结果得到的是相加净重分类指数,还给出了IDI和P值。两个包算是各有优劣吧,大家可以自由选择。
( _7 O# K9 F& ^, \' @& x i# d2 f3 Z* F$ a! J
生存分析的NRI
% z: W. q$ E6 O" X$ e6 k0 e+ M" j还是使用survival包中的pbc数据集用于演示,这次要构建cox回归模型,因此我们要使用time这一列了。4 G* N8 E7 F t' v& |# A! m
& x# I/ t8 [( f enricens包 j" @- G# T+ U2 {+ i" g
library(nricens)! }9 |1 S6 O5 ]! i5 e' f- Q, s
library(survival)2 w: ^5 f6 h t0 }/ N3 }! ^
/ m1 O( q5 N: K. s/ d' i4 q
dat <- pbc[1:312,]
7 Q5 B( F% k2 i/ H# i; S; {dat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡2 N8 |' `2 ?1 l1 G
1& |$ T+ @0 N# ^
然后准备所需参数:! {# v5 _+ {& o9 j/ C
* k, d* N( G1 L$ W$ o8 s# 两个只由预测变量组成的矩阵
$ G$ l1 b! V# P! r% O) ^# Nz.std = as.matrix(subset(dat, select = c(age, bili, albumin)))* Y( S T5 w$ F) P! K9 R) U2 [
z.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))9 Z9 L: Z6 c, r4 a; F
; s; } a2 a* H: H' i6 X* X
# 建立2个cox模型" v. }' W0 j' _; Y9 ?
mstd <- coxph(Surv(time,status) ~ age + bili + albumin, data = dat, x=TRUE)
! y2 ]5 S" Y1 D" d( z' Q( C3 r: mmnew <- coxph(Surv(time,status) ~ age + bili + albumin + protime, data = dat, x=TRUE). b' R2 b0 c1 a5 T; P
1 _+ e" _0 h, s w c8 X# 计算在2000天的模型预测概率,这一步不要也行,看你使用哪些参数
1 k' ~4 {. X" a3 s1 f1 ], J* D$ Fp.std <- get.risk.coxph(mstd, t0=2000)6 M% _) s, u. B5 R. r+ p+ c
p.new <- get.risk.coxph(mnew, t0=2000)4 `9 O$ L6 v6 H7 T1 ]# J
1
$ a% U4 |! M6 x* q; r计算NRI:- d' V' p9 p( V6 s! ^
/ W) y& M3 ]- q; y7 @nricens(mdl.std= mstd, mdl.new = mnew,
& V4 }9 _; r: w; v3 B0 ^' ^" U& p: r t0 = 2000, 7 k+ r* j# e+ C4 q G& ~/ Q
cut = c(0.3, 0.7),* P1 N2 U1 M! ~% v' C
niter = 1000, 3 \: S2 q% ~0 a( O7 m3 n
updown = 'category')
( K+ _9 A- C, f
2 O' l% q3 S8 N* h$ C% [* vUP and DOWN calculation:
2 k7 V1 P' V1 E0 N #of total, case, and control subjects at t0: 312 88 144$ U- [7 J$ H& r/ \6 k% W
! ?/ h+ t# q0 }* I) a Reclassification Table for all subjects:
4 \# @8 b( F- D0 @& R; \/ q New7 f/ K5 H1 {+ R4 Q, l
Standard < 0.3 < 0.7 >= 0.7& d9 X/ O2 U' \% ]
< 0.3 202 7 0
& I# z/ D$ x& K < 0.7 13 53 6 z3 d J. D8 m" [
>= 0.7 0 0 31
9 R% i% O6 F$ q+ \ ]1 S4 l9 P( V9 R
, t4 m$ n9 V9 P3 [# ~8 V+ O Reclassification Table for case:
j: S. j5 ^- R# |) w New
/ ]4 K7 o! h- c6 C% a. `$ t9 `Standard < 0.3 < 0.7 >= 0.7
) N3 B2 x9 X" N0 R < 0.3 19 3 0
& }) s7 A3 G: d < 0.7 3 32 4* P1 Z- E- x/ ` k4 U, q8 D# {
>= 0.7 0 0 27, r0 b! L- l6 N
3 s4 b& ~( }3 J- w l+ A6 E/ j Reclassification Table for control:5 I4 q5 R( b- L$ Y" f- R, S) H
New
& Q1 g4 |0 D% [$ [% ^) K! [Standard < 0.3 < 0.7 >= 0.7/ }. l0 M6 ^- O! \) J! `; t
< 0.3 126 3 0
' m- F/ h$ Z5 t < 0.7 5 7 27 s, V: b X. B7 Z) o* `
>= 0.7 0 0 12 E4 \; E% z/ H2 P3 e
1 @ y! } B( s& o( d0 |* [
NRI estimation by KM estimator:7 B0 K6 F, o; I: K0 r' t
: N& q( s! y4 q- k' |3 |
Point estimates:
9 M* V! a0 G4 B, J Estimate
" u- {' X% ]; x. y% f9 FNRI 0.053776350 b: J" F& w9 M! L
NRI+ 0.03748660: V. ~6 ^ G$ o, ~# G! d
NRI- 0.01628974
8 c4 P+ [9 `( ]6 m M- J9 w$ iPr(Up|Case) 0.07708938
" W+ s! M* M0 HPr(Down|Case) 0.039602781 k5 N- l& E$ D9 I8 P8 D
Pr(Down|Ctrl) 0.04256352
/ e- G9 r; a& y$ o6 C, Y5 W+ MPr(Up|Ctrl) 0.02627378- V: i; c6 e: z! d/ H+ U
1 s; r/ _5 e3 Y) g& VNow in bootstrap..: t, J& W a% A1 J/ u
3 U$ j+ a, h* A1 t5 k1 [
Point & Interval estimates:# b! L" X% @# N6 U: H8 ~; [& X; b2 V
Estimate Lower Upper
, a" }5 A' {9 A0 `, dNRI 0.05377635 -0.082230381 0.16058172
) \. s5 ~9 y7 V0 E/ B9 n, TNRI+ 0.03748660 -0.084245197 0.13231776/ f4 O: O' G' H: j) E
NRI- 0.01628974 -0.030861213 0.06753616! r l# \$ s' M. E& v
Pr(Up|Case) 0.07708938 0.000000000 0.191022917 H9 I$ T9 d/ K( u8 J( \
Pr(Down|Case) 0.03960278 0.000000000 0.15236016% ]: d" m/ i3 c* O, Z' E9 E- ^- v
Pr(Down|Ctrl) 0.04256352 0.004671535 0.098631708 e7 ^2 j/ |% G+ m2 p
Pr(Up|Ctrl) 0.02627378 0.006400463 0.05998424) z# x* n3 Y" _: l/ C1 s" U' g
( L$ j) H( j& I; v$ |3 G+ F
11 @5 `9 P% M! E" n
2 r3 K& s6 g9 K! p% p
Snipaste_2022-05-20_21-49-38
" a1 e5 F% B. ~# j/ ~" v结果的解读和logistic的一模一样。4 P/ H, c( P) M: [8 T
4 J; Q3 V8 O9 x& h- O( e" P. F4 IsurvNRI包
! l' o8 Y' G# N# W+ J Q# 安装R包9 o( A0 J# B, R% h9 s
devtools::install_github("mdbrown/survNRI")' H5 q" H. h( J# X
1
& M! ^# Q9 |6 b( }# O! Z0 }; [1 d加载R包并使用,还是用上面的pbc数据集。
) X5 ]2 K; ~3 I1 P$ E- l7 S4 |! o/ A; X$ }, J
library(survNRI)' S* R1 x& n' [0 X8 l: z+ p
18 W o7 }( Q) ]7 D. m; ?( Q; e! ]
## Loading required package: MASS
3 x1 \" d$ V. O1
- q" T' z t5 Vlibrary(survival)
, v) R8 J: ?( n5 p8 \# \3 w
7 G( m3 c* v6 O( l# 使用部分数据6 u$ M& _6 @+ Z+ ` d; S- w5 H1 {- m
dat <- pbc[1:312,]
/ X, n* ~2 S2 Y* V6 w; ^# adat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡
. P, b; w8 }0 a; Y, b) @, r2 u& e# N5 Y# `7 C( y
res <- survNRI(time = "time", event = "status",
1 T# G( n& V# ]) Z& F, g4 Q model1 = c("age", "bili", "albumin"), # 模型1的自变量
4 q9 x& p6 F+ u+ k& P8 }* S model2 = c("age", "bili", "albumin", "protime"), # 模型2的自变量( U3 v N7 r @" ], x$ _- M" i. w- V
data = dat,
. J2 D v' s0 x9 O predict.time = 2000, # 预测的时间点
/ M: r) O& h& r& ^, ]- v method = "all",
5 }- i" h5 C+ h0 ]9 S5 o bootMethod = "normal", - [+ t3 f- [ `# f
bootstraps = 500,
5 o N9 B3 ?. Q( G' o) p alpha = .05)
, u X5 w! S' w7 `% c% l& y E+ h3 ?/ D9 G: N8 G
1$ E: E' U f4 b2 y7 u3 g* ~
查看结果,$estimates给出了不同组的NRI以及总的NRI,包括了使用不同方法(KM/IPW/SmoothIPW/SEM/Combined)得到的结果;$CI给出了可信区间。( Y8 m* i9 m$ P) C: {8 r0 N& V
4 u) H- }" u9 N/ dres
2 t" d2 L( _8 O& d1
; s9 ?" A! i! [% B: e2 [## $estimates7 a# e, `6 R# O& p# {
## NRI.event NRI.nonevent NRI
8 a0 } s# a3 k5 {5 m* p## KM 0.20445422 0.3187408 0.5231951* ?$ U4 w+ Y K9 m- Q
## IPW 0.22424434 0.3273544 0.5515987# H$ @) V: |5 F' |) `# e
## SmoothIPW 0.19645006 0.3144263 0.5108763 \4 s& K9 G% i2 C, O5 v1 H% I
## SEM 0.07478611 0.2632127 0.3379988
# [; m, I; n& U+ }8 p/ c. ^## Combined 0.19633867 0.3143794 0.5107181. f2 y9 E! A9 _& ?, J; r8 s( J! v5 \' m
## ' N- Z( E. ?/ h+ n
## $CI$ t- |) a9 T. s. A( ?( r C: a
## $CI$NRI.event
. l0 y* Z0 S z## KM IPW SmoothIPW SEM Combined6 j/ H1 L2 g: L5 W1 `- E4 ~
## lowerbound -0.03915924 -0.02185068 -0.04724202 -0.1162587 -0.0473723
" l0 p$ H- k O2 X# Q q. [- Q## upperbound 0.44806768 0.47033936 0.44014214 0.2658309 0.44004968 b9 @) j& q9 ?1 e; ^! B
##
% I5 z; ^" L0 r+ i. N## $CI$NRI.nonevent4 H. ^' I8 ~) e! Q n# z
## KM IPW SmoothIPW SEM Combined- w2 s q# r5 r
## lowerbound 0.1317108 0.1396315 0.1286685 0.08638933 0.1286426
- D4 L. O( ]* |3 K! k7 I. c## upperbound 0.7102251 0.7393216 0.6966341 0.51482212 0.6964549+ b, P5 \5 e# d- S9 t/ D
## % Z _7 K O2 g: V
## $CI$NRI* F( _* |8 ?- V. R+ x$ Y
## KM IPW SmoothIPW SEM Combined
1 S8 k; o t4 L W## lowerbound -0.05112533 -0.04569046 -0.05439863 -0.04132364 -0.05443409
2 y0 ]8 Q4 ^% `; q" ^: n## upperbound 0.89306122 0.92464359 0.87970125 0.64253510 0.87953153
$ I. A# G6 l+ p: U- a2 \##
# Z. s& e5 d, h: d/ @## / B2 C4 Y$ q$ W6 I) R+ U0 s- j V& c
## $bootMethod6 y- ~3 X8 D1 v" ^8 x& |! o
## [1] "normal"! b9 L( J. t/ C
## 2 R& g' ?' ?# g4 ]- V
## $predict.time
" w$ L) z: ], b0 K: X/ h## [1] 2000
$ E) G% Z. n, c' d; o$ o##
8 p% S; g* r$ c## $alpha$ z9 x+ T% N- R7 t
## [1] 0.050 W% M: Y ?) m7 o$ e; v
## * M: o Z$ `/ S) [. X/ n( U
## attr(,"class")
" n5 A$ X, h# }% M1 ~0 B## [1] "survNRI") i& ?" ?# _5 a
3 O0 g0 b+ `. B& `, S9 b$ l15 d; x5 e5 L0 L: L3 A, S
OK,这就是NRI的计算,除此之外,随机森林、决策树、lasso回归、SVM等,这些模型,都是可以计算的NRI的,后面会继续介绍。大家如果有问题欢迎在评论区留言。1 i6 f* _- U- a
' M/ m* G n% h. ^2 N) g本文首发于公众号:医学和生信笔记
. n& Q" e, f M8 g) U+ [2 W7 C" A3 G- b' B7 _$ i
“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。2 K( E% ]" Z8 l( W8 d2 w
本文由 mdnice 多平台发布; h2 w- H9 L( J5 J0 D7 d
————————————————
' }" i: R$ `" j版权声明:本文为CSDN博主「阿越就是我」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
3 }7 u+ D8 l2 |7 r. @原文链接:https://blog.csdn.net/Ayue0616/article/details/126768006
1 {' x" }5 V& M3 l/ h
' {( ]" D9 k4 i, C7 {2 L" ]5 W( S& K7 {
|
zan
|