- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 565631 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 174912
- 相册
- 1
- 日志
- 0
- 记录
- 0
- 帖子
- 5313
- 主题
- 5273
- 精华
- 3
- 分享
- 0
- 好友
- 163
TA的每日心情 | 开心 2021-8-11 17:59 |
|---|
签到天数: 17 天 [LV.4]偶尔看看III 网络挑战赛参赛者 网络挑战赛参赛者 - 自我介绍
- 本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。
 群组: 2018美赛大象算法课程 群组: 2018美赛护航培训课程 群组: 2019年 数学中国站长建 群组: 2019年数据分析师课程 群组: 2018年大象老师国赛优 |
' z$ V) K6 c& U y% ]4 p8 Y净重新分类指数NRI的计算
5 G" g! X5 U, W$ `, B“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。+ e; o+ e+ u5 m( k
NRI,net reclassification index,净重新分类指数,是用来比较模型准确度的,这个概念有点难理解,但是非常重要,在临床研究中非常常见,是评价模型的一大利器!
# N g( T1 G- b+ i* Y9 d8 m9 M' d( s& ]1 t* q7 o# i/ i+ F& G, d4 Z
在R语言中有很多包可以计算NRI,但是能同时计算logistic回归和cox回归的只有nricens包,PredictABEL可以计算logistic模型的净重分类指数,survNRI可以计算cox模型的净重分类指数。
1 B) s0 u- j7 L5 r. |8 `* {/ Z/ z) w+ D& S
logistic的NRI# `4 T. H, S7 F$ [* H/ e
nricens包
$ y' \, K: g. W4 M+ e jPredictABEL包
( }8 e" G; r- Z0 B O- x7 [# A生存分析的NRI
" k0 E0 w" Q1 G7 f. _4 s8 ]3 @nricens包, V8 z5 ]4 {4 d& N( P, b! B% u1 M9 G- c. ^
survNRI包0 K: M5 s9 f/ A$ B
logistic的NRI/ E- t2 J8 B3 J
nricens包( y. C9 d! j, ^% [" u- ^
#install.packages("nricens") # 安装R包
4 E8 V& Q8 N {: P( M+ e3 C! Qlibrary(nricens)
5 j& ~! h: V' }% v1 |0 [# G1
2 D, ?1 w# r8 P3 q v" m4 A## Loading required package: survival9 z) W7 Z. e* Q! L- o) Q
16 f5 d1 x: U8 X+ }% l: j
使用survival包中的pbc数据集用于演示,这是一份关于原发性硬化性胆管炎的数据,其实是一份用于生存分析的数据,是有时间变量的,但是这里我们用于演示logistic回归,只要不使用time这一列就可以了。7 p4 ?( p+ ]' p4 q* m
/ q' o9 E# L+ k2 c- A! Y3 S
library(survival)0 r1 M2 N) o0 V/ V; e
9 q9 ]' o9 E t3 m
# 只使用部分数据8 G( @: m4 G# s8 F J
dat = pbc[1:312,]
$ W7 [+ y, G9 Ndat = dat[ dat$time > 2000 | (dat$time < 2000 & dat$status == 2), ]+ |& v4 E- r8 w/ v- _4 ?) T* W4 S
% B- g5 j, q% G- b d" _! C) P" {4 j
str(dat) # 数据长这样/ e+ _- F/ T4 R/ t( S3 S
1( v8 p" M7 a+ ?4 l5 \5 t: i
## 'data.frame': 232 obs. of 20 variables:, m8 [ u, o2 P' C! [
## $ id : int 1 2 3 4 6 8 9 10 11 12 ...' l7 }' I, X- K
## $ time : int 400 4500 1012 1925 2503 2466 2400 51 3762 304 ...
7 A( Z0 d8 F0 u1 |## $ status : int 2 0 2 2 2 2 2 2 2 2 ...
' ?. A2 ^5 [$ Q: X ^2 O1 o5 e# Q## $ trt : int 1 1 1 1 2 2 1 2 2 2 ..., `: _ F) @4 U9 f8 `/ r/ k! j7 `
## $ age : num 58.8 56.4 70.1 54.7 66.3 ...
: a8 F& a! O4 i4 g* P$ H9 R$ [## $ sex : Factor w/ 2 levels "m","f": 2 2 1 2 2 2 2 2 2 2 ...
6 S/ S o1 G1 a* t% g" v## $ ascites : int 1 0 0 0 0 0 0 1 0 0 ...
- `4 g, A" x2 ^3 x& e## $ hepato : int 1 1 0 1 1 0 0 0 1 0 ...
: I% L4 O% ~. F( r- G1 G## $ spiders : int 1 1 0 1 0 0 1 1 1 1 ...
2 U/ g+ A/ r8 h3 q9 Y F## $ edema : num 1 0 0.5 0.5 0 0 0 1 0 0 ...
) z3 C' J3 B6 y! u3 T" n## $ bili : num 14.5 1.1 1.4 1.8 0.8 0.3 3.2 12.6 1.4 3.6 ...9 o) O6 ]) U9 @- }1 U0 f
## $ chol : int 261 302 176 244 248 280 562 200 259 236 ...* x$ _) u3 t3 B- h
## $ albumin : num 2.6 4.14 3.48 2.54 3.98 4 3.08 2.74 4.16 3.52 ...: ~- l4 t! A! G$ ^3 T2 G/ ] o
## $ copper : int 156 54 210 64 50 52 79 140 46 94 ...3 ^. J- L: {5 A; I# g
## $ alk.phos: num 1718 7395 516 6122 944 ...1 T1 C& F, _0 I0 W; o
## $ ast : num 137.9 113.5 96.1 60.6 93 ..., N6 |7 {0 ^7 V1 u8 V0 P
## $ trig : int 172 88 55 92 63 189 88 143 79 95 ...
& a$ {# I$ ?( `) v( u6 m% J## $ platelet: int 190 221 151 183 NA 373 251 302 258 71 ...! W0 f2 t3 I$ X' {2 E9 r6 k
## $ protime : num 12.2 10.6 12 10.3 11 11 11 11.5 12 13.6 ...5 f" L1 X5 V5 j+ h3 L& \
## $ stage : int 4 3 4 4 3 3 2 4 4 4 ...
! `& r; R. `( r& J# L
2 W3 {- w: n) p0 \- h! H: ~- C1
1 }8 h: v D$ N3 q9 y9 Cdim(dat) # 232 20! C5 D# w3 q+ p) R9 w
1 m* V- U7 \# {9 C W4 Z
## [1] 232 20% x* C. E# r! C+ ^. H# i
11 C4 \( ]9 R5 ~* u7 U9 j: W" A! K
然后就是准备计算NRI所需要的各个参数。
0 H/ q, T7 \; Q9 t# P0 G3 B
7 U y) P/ L* [# 定义结局事件,0是存活,1是死亡
6 j0 L; k, U, B z" n8 }' ievent = ifelse(dat$time < 2000 & dat$status == 2, 1, 0)
1 j o# f) J6 R% l
% ~: p# V, t- C# 两个只由预测变量组成的矩阵
, Y& n7 m! J( _1 U# I/ iz.std = as.matrix(subset(dat, select = c(age, bili, albumin)))
$ A+ o7 ]2 u$ y. b J, Q; F2 \z.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))
/ @- k2 c4 g9 r6 C, s6 K2 l+ m
% e6 h5 j/ u9 D# 建立2个模型
# H+ m( i4 v+ k/ V. G" V; |3 umstd = glm(event ~ age + bili + albumin, family = binomial(), data = dat, x=TRUE)4 h1 n+ y a, ~7 R% ]5 }
mnew = glm(event ~ age + bili + albumin + protime, family = binomial(), data = dat, x=TRUE)
2 [: E$ i7 @. {$ @2 x* I$ B K
. ?4 p* Y( I) R* @# M! u) ~8 Y, X. @( T# 取出模型预测概率
' `- y6 F! z. M# T% yp.std = mstd$fitted.values
* P1 b" q! u) A2 hp.new = mnew$fitted.values4 v& X/ a F+ E+ a$ e/ P
8 W* y3 N+ V ~9 M' h/ t0 j) I+ u
1
& T: {) D/ C( y5 n# j然后就是计算NRI,对于二分类变量,使用nribin()函数,这个函数提供了3种参数使用组合,任选一种都可以计算出来(结果一样),以下3组参数任选1组即可。 mdl.std, mdl.new 或者 event, z.std, z.new 或者 event, p.std, p.new。
: m* Y( {3 E J d' |1 o7 N% h$ q# n* L$ z( i
# 这3种方法算出来都是一样的结果1 ~0 j4 Y* ]& O
* I- r4 i: U R9 P
# 两个模型
: [5 c6 O! x4 ^# H' \0 {( l/ r/ _1 {$ qnribin(mdl.std = mstd, mdl.new = mnew, 8 @. S* V( m# v0 `" y
cut = c(0.3,0.7), % e- I' X# Z8 X1 o; [) S4 D$ F
niter = 500,
$ L( z3 j+ @; A3 V7 J+ g updown = 'category')
* U) m$ I* T" G( a. z: ?/ s: L
0 z( P+ F1 h6 l1 m# 结果变量 + 两个只有预测变量的矩阵$ X: f$ d! W7 U' b, R5 ~
nribin(event = event, z.std = z.std, z.new = z.new, ; t. K) z3 q# n( K
cut = c(0.3,0.7),
$ b5 S5 C+ U, `9 }( i5 t2 I4 g niter = 500, * j$ g, g0 U/ N) |6 {/ f! s
updown = 'category')
1 o9 V @ t5 J& _# o1 K0 ? r
- Y. i( H( O" r8 V## 结果变量 + 两个模型得到的预测概率1 [" `8 @, O" z* L' v. L; A
nribin(event = event, p.std = p.std, p.new = p.new, ) c' }4 l- h; K- T9 b1 F
cut = c(0.3,0.7),
3 z6 g+ d$ c6 h% k' _3 _ niter = 500,
( g) t F2 u+ a updown = 'category')
5 E! T- x' m/ w& ^8 t8 x/ ^$ c/ O; ?! d7 L; y+ Z0 p8 ^4 v0 l
1& W) h: [! F! J8 e
其中,cut是判断风险高低的阈值,我们使用了0.3,0.7,代表0-0.3是低风险,0.3-0.7是中风险,0.7-1是高风险,这个阈值是自己设置的,大家根据经验或者文献设置即可。
0 l# }! r; l6 x z
/ _# I/ L1 C3 x! wniter是使用bootstrap法进行重抽样的次数,默认是1000,大家可以自己设置。
) t8 `) E$ r! L0 n" d
" |3 v, k, k) n" F; @5 Wupdown参数,当设置为category时,表示低、中、高风险这种方式;当设置为diff时,此时cut的取值只能设置1个,比如设置0.2,即表示当新模型预测的风险和旧模型相差20%时,认为是重新分类。
$ N/ X. s6 Z% L
r( _0 r# I* }% V& t- S上面的代码运行后结果是这样的:
' M8 h. |# @- K/ L; [* f! c( s U' v8 ~/ l ]
UP and DOWN calculation:
! B6 B7 O. P$ N$ G2 ^ #of total, case, and control subjects at t0: 232 88 144% O% l5 ^0 ^" i7 G/ D7 o* g6 F, y7 N' r
( [. O9 f- t& E1 m, T Reclassification Table for all subjects:
3 U2 l. X% E, x% w0 O New
* s. Z ?- b3 y- n4 EStandard < 0.3 < 0.7 >= 0.77 x) u5 c- q% P1 E+ i( u" X. O
< 0.3 135 4 08 P G* U) g9 ^3 J1 L3 w
< 0.7 1 31 4
2 k7 P, |( K" q& [ >= 0.7 0 2 552 F& G0 u* M8 p. _% I: u1 Y) g
2 }4 d* K$ I2 ~) i; z+ M Reclassification Table for case:
' w+ X" P1 M( \- e. p$ _1 h- O9 q7 B New4 m8 ]& O' S' x2 H9 a
Standard < 0.3 < 0.7 >= 0.7+ t/ u( j1 T' I" i
< 0.3 14 0 06 M. f2 z8 r! ]2 a; m @
< 0.7 0 18 3
! h+ F# W2 k' S0 {6 m# K" z; [ >= 0.7 0 1 522 v' O0 O# N% u' q
' _4 H3 z% \% m+ u, e
Reclassification Table for control:
4 a: N T3 ~, e3 H2 H- } New' D# h0 R, y% N
Standard < 0.3 < 0.7 >= 0.7
8 A! O I1 _' q7 X < 0.3 121 4 00 _* c" t' d+ P
< 0.7 1 13 18 S: @9 U" Y8 ^0 G2 l3 d
>= 0.7 0 1 3
! v8 ?9 A5 @7 ^+ w$ x1 n
" z F, ` B$ ZNRI estimation:5 G& V8 e& ?* {. h8 q% B
Point estimates:
+ \* ]4 _8 |* j3 T9 T. o Estimate' j$ n1 a2 L" B2 B8 v; x6 K# d
NRI 0.001893939
, e* x0 G3 [6 q& ANRI+ 0.022727273
Z9 A2 m1 D; \# v) \NRI- -0.0208333335 Q3 d$ \ n+ \
Pr(Up|Case) 0.034090909
$ z& h p% ]% R7 A( gPr(Down|Case) 0.011363636
: F6 q$ i! c: _" sPr(Down|Ctrl) 0.013888889
0 W3 C0 J* j9 _" ?' h' b) A) d& hPr(Up|Ctrl) 0.034722222
. `$ N4 w' k1 {8 U7 o
; B% D* r- K2 F# @3 WNow in bootstrap.., L, ]4 S) ` J( I# g- I" N6 f) b
) M3 P t, M. M3 }
Point & Interval estimates:( i- ^0 W& ]- O: W
Estimate Std.Error Lower Upper* [& U( D' r4 \. E
NRI 0.001893939 0.027816095 -0.053995513 0.0553544495 w( R7 s9 _* Q$ I
NRI+ 0.022727273 0.021564394 -0.019801980 0.065789474
4 o5 l) f) v( hNRI- -0.020833333 0.017312438 -0.058823529 0.007518797
' x% j7 D e% _% F+ y' KPr(Up|Case) 0.034090909 0.019007629 0.000000000 0.072164948
- W) k& K" F3 j( s j+ \! ^Pr(Down|Case) 0.011363636 0.010924271 0.000000000 0.039603960
8 w2 t3 j+ n/ F8 {; VPr(Down|Ctrl) 0.013888889 0.009334685 0.000000000 0.035211268
* _+ H4 }$ N' @+ V: F+ a* LPr(Up|Ctrl) 0.034722222 0.014716046 0.006993007 0.066176471' ~: Q2 G* Q8 g- t8 J" p$ Q6 z7 ?
6 S" O) E. w, h, ?* {1 h1
! d8 r+ |) s R; M$ h( _首先是3个混淆矩阵,第一个是全体的,第2个是case(结局为1)组的,第3个是control(结局为2)组的,有了这3个矩阵,我们可以自己计算净重分类指数。
8 ~% w" p: G# J# i* t$ R3 S) L' ~( ~% d
看case组:, L4 f: y6 h b$ C/ O7 i/ K
6 b- d! P4 |6 I1 d净重分类指数 = ((0+3)-(0+1)) / 88 ≈ 0.022727273
7 E$ y: |8 ^4 G; f( B7 u- i# W8 m) o
再看control组:5 c' R: o: O( o
" ?: T2 \3 c' L5 Y; X. ?
净重分类指数 = ((1+1)-(4+1)) / 144 ≈ -0.020833333
, ^( b5 S8 I7 _1 i
- d7 g" m9 k7 A H- ]0 L- D3 z相加净重分类指数 = case组净重分类指数 + control组净重分类指数 = 2/88 - 3/144 ≈ 0.000315657; v9 Y7 Z; |+ h I5 r
3 e$ g# ?6 ~) U) D+ M再往下是不做bootstrap时得到的估计值,其中NRI就是绝对净重分类指数,NRI+是case组的净重分类指数,NRI-是control组的净重分类指数(和我们计算的一样哦),最后是做了500次bootstrap后得到的估计值,并且有标准误和可信区间。6 s" n- X* J: Y. `9 M5 Y
9 E2 @) P, O* |; l% y
最后还会得到一张图:. ^" ^9 \% e- z; t9 X
6 @1 ~+ E8 C' Z. {( c9 k; q' P% K- K
这张图中的虚线对应的坐标,就是我们在cut中设置的阈值,这张图对应的是上面结果中的第一个混淆矩阵,反应的是总体的情况,case是结果为1的组,也就是发生结局的组,control是结果为0的组,也就是未发生结局的组。5 t1 M# P5 g! I0 _% U1 T
& C6 ?/ g# [7 Q* n6 }; e6 qP值没有直接给出,但是可以自己计算。4 k' d1 D1 G; }$ M, ~" f% W! \" L
9 }( A' c& i0 p( q0 C5 O9 X
# 计算P值
7 j* d8 `' K) v, p& ez <- abs(0.001893939/0.027816095)
. |. E; E- D& e1 o# O$ R! p9 ~p <- (1 - pnorm(z))*25 H( y1 m# l" n& c$ W
p; ~/ _8 l. k4 f2 F9 V: P/ x2 I
1
4 | d* {4 t& ~$ O) Z8 R6 F! k5 P/ v## [1] 0.9457157
0 Y; y& J5 ^4 j0 _$ v1
H% w2 V! J( R4 t3 o6 m5 Y6 d Q" kPredictABEL包
) b1 p% K1 q! i8 V* c#install.packages("PredictABEL") #安装R包; l4 ^7 P5 s/ A: a! G
library(PredictABEL) 6 n$ P/ P+ N' r1 H% K
7 o1 @+ s+ I; U# 取出模型预测概率,这个包只能用预测概率计算- j* v( p1 J9 X. e0 w
p.std = mstd$fitted.values" J! q6 J/ d5 u8 O0 H% G1 _7 i
p.new = mnew$fitted.values ) D5 w5 ~4 \5 o0 ~7 w1 j* E
1
0 |# l7 y1 ~5 C然后就是计算NRI:$ }/ ^) U2 `: C: q0 O5 L8 z+ a' f, A
0 C ]# M7 D/ b$ V6 u; E# o
dat$event <- event2 v0 e$ ~2 r5 J
3 |: ^! q8 e# S* Y/ N9 K% }5 ~" |4 kreclassification(data = dat,; n1 {. O! E2 V+ L. J! i' f
cOutcome = 21, # 结果变量在哪一列
) M, W7 a1 L2 x: @" y+ y% _! G2 d: g predrisk1 = p.std,6 ]6 `1 ~& e) K8 I$ B
predrisk2 = p.new,
. o8 R: d) T2 K) d cutoff = c(0,0.3,0.7,1)
% l9 X2 G* A7 s5 v3 R2 {; \0 O )
2 B- p3 b- s5 k p O1
- M, k1 ~: Z" k" ^) X8 v/ w## _________________________________________+ r. k0 x1 |" b+ i: J
##
6 n& L: O' r% c- B: [* P+ m## Reclassification table 8 G0 N; b" q G
## _________________________________________
7 E4 D) N+ V# F! {8 |, L: R## 4 ?3 b9 i$ O3 ^/ h, {
## Outcome: absent : j2 i0 z k6 y, }4 Z" `, q
##
# S% }! G; l$ a& W5 j5 n## Updated Model
5 E9 N! X( V U8 I( n9 g( K## Initial Model [0,0.3) [0.3,0.7) [0.7,1] % reclassified
6 X* E+ Q) d; W8 z## [0,0.3) 121 4 0 3
5 H! M2 x3 @' h- w2 ~## [0.3,0.7) 1 13 1 13
2 r7 K+ g; a$ \) f$ t5 r5 {## [0.7,1] 0 1 3 25
2 o7 T3 b: r7 \1 Y/ x##
/ ^' x4 ]1 g: ]) M: i## 2 Y. K% [: r4 `6 F t8 X+ I
## Outcome: present / ^) u6 t3 b6 `& I" H" y; ~; B
## 2 V/ ^2 i+ U# Z8 O
## Updated Model# D1 v( u# w( D4 U
## Initial Model [0,0.3) [0.3,0.7) [0.7,1] % reclassified9 _( s9 _, m ]& i3 a
## [0,0.3) 14 0 0 0
8 I% Q) q9 T! D; ^% x## [0.3,0.7) 0 18 3 14
$ {5 o( \1 I5 i6 J* h0 [5 C0 w6 n2 u## [0.7,1] 0 1 52 2
/ _2 f4 Q* _% B. O## 9 `3 P$ F' d0 O8 T8 {& Q
##
" K& G3 s& `& A9 P) {## Combined Data 2 ]2 t/ _: G/ V3 @! p. c! e
## 4 L* |* q2 V# t) U3 q/ U
## Updated Model* `! j, c- y, b
## Initial Model [0,0.3) [0.3,0.7) [0.7,1] % reclassified7 |8 J6 b; ^, V+ ]0 `% Y% }" m/ K7 c
## [0,0.3) 135 4 0 3
4 M* v( p( g o7 }( {. @3 u; D## [0.3,0.7) 1 31 4 14
; c' P' s; A% P## [0.7,1] 0 2 55 4
( F+ A$ C0 }9 M## _________________________________________) j" }# O! A+ p0 I# R) ^2 ]1 m, w( ~- g
##
, o, J( X7 C( r s## NRI(Categorical) [95% CI]: 0.0019 [ -0.0551 - 0.0589 ] ; p-value: 0.94806 $ ^0 B7 D- W2 [9 \, S7 D
## NRI(Continuous) [95% CI]: 0.0391 [ -0.2238 - 0.3021 ] ; p-value: 0.77048
8 z2 ^; ?% A6 V3 z' t5 b0 |. l* M## IDI [95% CI]: 0.0044 [ -0.0037 - 0.0126 ] ; p-value: 0.28396
( V: t* H# Y, u1 ?1 g1 }7 M$ _. H& z9 ^2 H; _
1* K" h8 [+ k2 A7 n/ L6 S
结果得到的是相加净重分类指数,还给出了IDI和P值。两个包算是各有优劣吧,大家可以自由选择。 g% N# p: @5 u) m# J
7 o( z: @0 i1 H0 p5 P5 y+ P7 v
生存分析的NRI# z9 l; c( N5 d" B5 t, c
还是使用survival包中的pbc数据集用于演示,这次要构建cox回归模型,因此我们要使用time这一列了。
1 V6 Z% y6 c e, P; x4 {4 n( L; C6 H
nricens包
9 [' C* \& z# V( Zlibrary(nricens)- q8 J& t7 [7 s2 c& F
library(survival)
, B) w2 N: t3 n7 t6 I1 {6 Z. H. f. `* i6 C% f
dat <- pbc[1:312,]
# e2 N- N- n! t2 ?+ Ddat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡# {* F9 H' z" a. C# h; C, Q
1% R, e& Q* V f' s, O
然后准备所需参数:" s. I4 m1 p$ F+ z9 l. f2 `
% y& j5 p4 b" w$ Z8 q* s. ]# 两个只由预测变量组成的矩阵
. G1 m, {& m5 Z/ F. [z.std = as.matrix(subset(dat, select = c(age, bili, albumin)))
4 {, x) {! N3 ?; e; u9 q- W4 f3 uz.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))9 B; t5 k! b7 e$ l @* R
* Y, h. @$ _' u! ]
# 建立2个cox模型
2 c# q2 S7 i0 G7 g: H4 Kmstd <- coxph(Surv(time,status) ~ age + bili + albumin, data = dat, x=TRUE)
' B7 n% x7 d& Y# \0 q: rmnew <- coxph(Surv(time,status) ~ age + bili + albumin + protime, data = dat, x=TRUE)
# r( f+ c$ L- x5 M& O+ `% k/ {% h" U
# 计算在2000天的模型预测概率,这一步不要也行,看你使用哪些参数
+ z" Y" |1 @; L( I! ep.std <- get.risk.coxph(mstd, t0=2000)
+ \; X! E# {( \8 G6 K3 Ep.new <- get.risk.coxph(mnew, t0=2000)$ T, k* ~7 K/ a& W2 B! U0 J
1; E1 T& E- f4 k( a
计算NRI:+ ], _2 z- z8 q! z- q
0 P1 X! c U+ z2 y2 e, x+ |nricens(mdl.std= mstd, mdl.new = mnew,
3 s; b, k0 h) C1 D4 U& R* Y7 i t0 = 2000, " m! u- V& N3 F, e
cut = c(0.3, 0.7),4 w( k& B1 ~: X0 |: v' E
niter = 1000,
4 _+ n3 t. p% I updown = 'category')
/ t N$ e: `. l& A0 u: J% n
" o/ n4 ^0 W6 }. u3 B. TUP and DOWN calculation:( O& B0 S6 F( w4 N) X" @
#of total, case, and control subjects at t0: 312 88 144
9 O* O* x) _' {: N2 E
" E# [2 l) e: A0 _2 U u$ H8 J Reclassification Table for all subjects:! q* v5 S+ \! C
New0 L e! t- Q/ n8 ~
Standard < 0.3 < 0.7 >= 0.7
- S _" v0 a0 o) j1 V < 0.3 202 7 0
" y* _) k) E/ M! p, Q: M( T < 0.7 13 53 6; t& e. E4 | n9 p# V1 s5 t
>= 0.7 0 0 31
1 Z m% A5 `$ m/ \/ ?( [# }3 j/ X S9 o% v7 r' C" U& ~3 f
Reclassification Table for case:
& o7 s% _3 E' ^& H& z# d New
# s2 \, ^1 A; }7 _Standard < 0.3 < 0.7 >= 0.7
, q7 E8 k& {3 G& W7 n < 0.3 19 3 0; l' `# T) w; p: \# a
< 0.7 3 32 4
) U- T# A3 w- w; r2 C >= 0.7 0 0 275 F8 R5 a) y8 S% Z. D
% K) m7 O2 K$ W* {1 @% g Reclassification Table for control:
$ O, R9 {; n. H) J L New
6 _6 Y8 R6 W' v" c9 |9 W8 mStandard < 0.3 < 0.7 >= 0.7
0 @, f5 s: ^. M9 a; I- @ l < 0.3 126 3 0/ m, i; H; ~! B% e+ t( E0 e$ f
< 0.7 5 7 2
; F {3 R: O& O. \; s4 M: x >= 0.7 0 0 1
* ~, a2 p0 ?: I4 m) G7 ~3 u0 T2 B$ o; M1 U, r0 {$ h
NRI estimation by KM estimator:
7 u- B) w+ M6 G/ [: R
& ]9 X8 ^/ _ f5 oPoint estimates:
) R6 K/ T/ O0 ^3 y: t8 \ Estimate
9 h c+ N1 q4 I8 b" {NRI 0.05377635
/ b! _5 c9 F" m! JNRI+ 0.03748660
- V2 D8 o0 ]& x% _NRI- 0.01628974$ P! s1 N/ j9 B+ \+ |+ q
Pr(Up|Case) 0.07708938' \5 b* o& J V! b
Pr(Down|Case) 0.03960278$ N( G5 P4 P, q: P
Pr(Down|Ctrl) 0.04256352! }& t% \% M! E% F K& L9 D8 |
Pr(Up|Ctrl) 0.02627378+ c* D( M% f% m1 i" u$ p
o. J- `% x" H; G! c. I
Now in bootstrap..
, F7 X) L. h) g3 ~+ u z
# W4 g) [ V7 [ XPoint & Interval estimates:$ C: H( W6 f( U
Estimate Lower Upper
" y/ d( @, Z8 a* _1 H1 jNRI 0.05377635 -0.082230381 0.16058172; R" q3 t9 ^7 G$ E/ Z8 k
NRI+ 0.03748660 -0.084245197 0.13231776+ U0 A. R! ]9 J0 T, A6 I' m7 g
NRI- 0.01628974 -0.030861213 0.067536167 {9 u8 C& \- Z
Pr(Up|Case) 0.07708938 0.000000000 0.19102291* k& h& N5 A) k1 G9 j( R* m
Pr(Down|Case) 0.03960278 0.000000000 0.15236016* D. B3 x% }) w9 v" }( N
Pr(Down|Ctrl) 0.04256352 0.004671535 0.09863170
& u6 b# X0 y' y2 x% e$ j; b V$ cPr(Up|Ctrl) 0.02627378 0.006400463 0.05998424! K. Z1 z3 x1 s0 ]
! }3 U* r2 g5 `/ i- Q$ U8 v/ w* t; S3 G1
4 ~( q! X, g2 C1 f% s8 d; D h/ ]) v, W1 c' B+ B, |+ T1 [
Snipaste_2022-05-20_21-49-38
8 l- n4 u! N6 b: I) L' a结果的解读和logistic的一模一样。
0 m* M! v, F1 @/ g5 P# \: b) b0 i) d( n+ d" G" {- i$ E8 E. v
survNRI包5 l( H, P% E2 L: h* @
# 安装R包7 I) n( U# i, v( ]" A, S
devtools::install_github("mdbrown/survNRI")
8 }6 \ u, S! N" S- e! |1
* A/ U) s- x- ]. z; |( c4 p+ ~) I加载R包并使用,还是用上面的pbc数据集。* g( ~( d$ Z+ ~& p; l2 K
0 m5 ]* c) D: ]7 }& S
library(survNRI)
+ H8 R5 N a) |" {4 c9 _1
8 N$ v; a! b3 @" e. Z/ ^0 T. C## Loading required package: MASS
) G0 Y/ W1 i) `: g" N; i+ `1
6 a. s8 g( j3 o& `) s- b! x3 jlibrary(survival)5 t5 i8 Z% J3 _: t8 f. N1 Q3 r
3 {+ x+ ?9 T8 }0 a1 U
# 使用部分数据
4 d' [, U/ q/ ?5 C2 D; S* X! i+ Vdat <- pbc[1:312,]8 r# n& I5 b) v- b% x6 [5 w
dat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡
% H9 i# J8 d# X- z7 b9 z, A4 h8 b) H! q% M; ^0 P
res <- survNRI(time = "time", event = "status", 4 |. |( J- r* F& K. J5 n$ K9 U5 x
model1 = c("age", "bili", "albumin"), # 模型1的自变量8 u2 x, B4 w( O; x" e+ h
model2 = c("age", "bili", "albumin", "protime"), # 模型2的自变量
+ p* R) M( C i$ W- p' R2 O! [ data = dat, 2 U7 m: G7 a# e6 x( N' X; R
predict.time = 2000, # 预测的时间点
& m; `4 G! i! {( ` method = "all",
# `3 ^2 M/ @5 J" i bootMethod = "normal",
& d- i1 K% {# ?# W s bootstraps = 500,
6 b, E- ^' u7 k& R1 T3 [ alpha = .05)
8 k. L Y. ?+ W$ r6 q2 ?2 G9 w& u( l+ W& K
1" X/ S' i9 ^8 a0 {* i1 N
查看结果,$estimates给出了不同组的NRI以及总的NRI,包括了使用不同方法(KM/IPW/SmoothIPW/SEM/Combined)得到的结果;$CI给出了可信区间。! D( y+ S& u+ v. x
0 K4 X* e c, F1 ~
res) }2 F& y! n* j
17 ?! u% ^9 g$ G* f1 t
## $estimates. O( P" O' {2 J8 R U
## NRI.event NRI.nonevent NRI
! z7 g- m! G: S# n## KM 0.20445422 0.3187408 0.5231951
& `$ x2 p: O4 U1 r6 w## IPW 0.22424434 0.3273544 0.5515987
0 ]2 I# {. z/ {7 g" m## SmoothIPW 0.19645006 0.3144263 0.5108763
N, ~1 V+ H5 ?$ y2 x4 W## SEM 0.07478611 0.2632127 0.3379988' U4 L. z, r, n0 v
## Combined 0.19633867 0.3143794 0.51071818 a, k) z! D$ i* T' Y5 U! b
## : M9 X3 ]; \% R/ V+ q b
## $CI& i2 i l- X+ ?$ {4 f' L" R/ G* V
## $CI$NRI.event
/ Y& y8 p! c+ X# s' ]## KM IPW SmoothIPW SEM Combined u1 S4 v$ m- x% E$ x
## lowerbound -0.03915924 -0.02185068 -0.04724202 -0.1162587 -0.0473723
# F. k5 T1 a- ^5 h- t" h3 e## upperbound 0.44806768 0.47033936 0.44014214 0.2658309 0.44004967 ], M. N% p! g& s8 ~: Q# m- g: Z
## * ^* k8 r% H0 O1 E
## $CI$NRI.nonevent
( w( x" j) d5 Q" y' |" u4 _7 G/ h## KM IPW SmoothIPW SEM Combined( K; F9 L7 @9 |+ {& ?
## lowerbound 0.1317108 0.1396315 0.1286685 0.08638933 0.1286426! Z# ?- V$ B/ _% J! |' t
## upperbound 0.7102251 0.7393216 0.6966341 0.51482212 0.6964549
" J/ v5 L6 m8 D' K2 I, `) p. ?##
, x3 ?) \+ Z. `, E+ q/ r; o5 e## $CI$NRI! Q: o- q+ e- I. p* `5 U8 P/ r( u
## KM IPW SmoothIPW SEM Combined
' h3 b9 ]$ e3 j) L1 Q& Q## lowerbound -0.05112533 -0.04569046 -0.05439863 -0.04132364 -0.05443409
5 y/ V% a7 p! ?# B+ M3 B. Q1 B## upperbound 0.89306122 0.92464359 0.87970125 0.64253510 0.87953153
5 S$ p4 _& h- r+ C+ `: i## ' H7 N! F+ V' L8 S( A
## 2 S9 p# b, N5 @+ G
## $bootMethod0 Q( [3 L* e) x) o$ J B
## [1] "normal"- }. h9 k7 n7 U- d* I
##
3 G. [1 ~% g' f4 m+ x4 o2 U+ [ a& _## $predict.time
8 |* P$ j" E( [: |## [1] 2000 s7 F9 g9 w" w& ^
## . H! q7 O8 ]+ o, I
## $alpha
+ U' B7 e3 d) J## [1] 0.05
2 l0 ?# ~1 ]0 f0 I3 C' O2 j* K## / V: ?2 ^8 X" J. @2 S
## attr(,"class")+ e0 l/ E" g. J: B& ]6 l8 T
## [1] "survNRI"
. i3 p8 h, h2 e
# T, ?: M% d9 ]3 e! y3 w1- s3 a/ t) N3 z# ~
OK,这就是NRI的计算,除此之外,随机森林、决策树、lasso回归、SVM等,这些模型,都是可以计算的NRI的,后面会继续介绍。大家如果有问题欢迎在评论区留言。% Z( u7 o9 [( h* \: Q& g0 l; U2 ^
+ E4 i) J/ Y8 n5 A! G: G; n本文首发于公众号:医学和生信笔记1 Y6 i- q" T. H$ j" L v/ {
' J; y8 A% I6 T2 [- j& H“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。/ F4 h$ I4 {3 t% } a& Q
本文由 mdnice 多平台发布
0 A( O& d9 X* _4 `————————————————; V; E3 Q' ^- c
版权声明:本文为CSDN博主「阿越就是我」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。* K/ N) y A9 ~, o5 n
原文链接:https://blog.csdn.net/Ayue0616/article/details/126768006, r2 `% `; O& K; \% @. }! o& p
4 V0 ~* ] g' E4 R H1 B- X! `( D' z
|
zan
|