- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 564445 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 174556
- 相册
- 1
- 日志
- 0
- 记录
- 0
- 帖子
- 5313
- 主题
- 5273
- 精华
- 3
- 分享
- 0
- 好友
- 163
TA的每日心情 | 开心 2021-8-11 17:59 |
|---|
签到天数: 17 天 [LV.4]偶尔看看III 网络挑战赛参赛者 网络挑战赛参赛者 - 自我介绍
- 本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。
 群组: 2018美赛大象算法课程 群组: 2018美赛护航培训课程 群组: 2019年 数学中国站长建 群组: 2019年数据分析师课程 群组: 2018年大象老师国赛优 |
4 f, j! U& X) U5 U, c7 ]+ W
净重新分类指数NRI的计算' f3 @4 I% t7 u x. G
“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。
1 o; S( }3 ]9 Z0 hNRI,net reclassification index,净重新分类指数,是用来比较模型准确度的,这个概念有点难理解,但是非常重要,在临床研究中非常常见,是评价模型的一大利器!1 b) d- b7 q9 Y) }/ ?& y# O
0 F, l( X7 H$ x) z
在R语言中有很多包可以计算NRI,但是能同时计算logistic回归和cox回归的只有nricens包,PredictABEL可以计算logistic模型的净重分类指数,survNRI可以计算cox模型的净重分类指数。# P1 \ b/ |1 t) d3 F
1 X. n# d7 s! o m' e5 ]
logistic的NRI
2 e4 x) w1 j" z* }5 H' f& {* l( dnricens包
5 D; h( {& i4 O0 l7 j8 NPredictABEL包6 k: c7 y9 w9 X/ E
生存分析的NRI; M1 }# j: G" d5 ?3 m
nricens包' `$ j+ k8 I& x# f a' ?
survNRI包9 g, I) O8 m7 M& a& f7 Z+ q
logistic的NRI
0 ]6 M3 m- [1 l6 S% L9 gnricens包# [% I9 Y- ]) q" c
#install.packages("nricens") # 安装R包 y, B. D) I3 I" r0 M
library(nricens)
7 ]9 n! W, G0 N" V% {% j9 C1; S, Q0 b6 D6 e# ^
## Loading required package: survival: R9 a/ ?, j9 s) L
1
+ F! T: Q' ~* P- J: a9 ]( ]使用survival包中的pbc数据集用于演示,这是一份关于原发性硬化性胆管炎的数据,其实是一份用于生存分析的数据,是有时间变量的,但是这里我们用于演示logistic回归,只要不使用time这一列就可以了。
. {3 |0 `5 U1 m1 f
A% q' s/ K! i" L$ elibrary(survival)6 b' a: G6 m5 \) p# I) G. q1 V2 j; W
- G. |! `+ s: d# G# 只使用部分数据8 v+ U) _% a" M/ M, @# c) {" `
dat = pbc[1:312,] 2 A+ }4 B$ f9 C
dat = dat[ dat$time > 2000 | (dat$time < 2000 & dat$status == 2), ]8 W- Z6 e7 }$ x; ~" k" }9 B( m
* b3 H9 `: K2 c" K3 v, P; f
str(dat) # 数据长这样2 ?, f* p' ]- ]3 B: G
16 v4 e2 ^' p$ c% y0 X, i
## 'data.frame': 232 obs. of 20 variables:
/ u9 U0 b1 F0 O. J, f. t## $ id : int 1 2 3 4 6 8 9 10 11 12 ...
7 Q! t2 t' E6 t" v) e## $ time : int 400 4500 1012 1925 2503 2466 2400 51 3762 304 ..., b# U. N: |- w
## $ status : int 2 0 2 2 2 2 2 2 2 2 ...
; _* F# d+ E$ M## $ trt : int 1 1 1 1 2 2 1 2 2 2 ...
& R$ b' {8 g$ K% T$ ?3 F: I## $ age : num 58.8 56.4 70.1 54.7 66.3 ...
: e8 A5 M; d; L. H1 u5 n## $ sex : Factor w/ 2 levels "m","f": 2 2 1 2 2 2 2 2 2 2 ...: O v$ q3 p" s$ x& s L4 e
## $ ascites : int 1 0 0 0 0 0 0 1 0 0 ...9 [$ c4 B5 I2 G$ L
## $ hepato : int 1 1 0 1 1 0 0 0 1 0 ...0 ?; Y) s$ ^/ f& {% p9 S, n9 m
## $ spiders : int 1 1 0 1 0 0 1 1 1 1 ...) O6 w V' q% }, b
## $ edema : num 1 0 0.5 0.5 0 0 0 1 0 0 ...* p) w9 _. q8 y" \1 f; f2 A
## $ bili : num 14.5 1.1 1.4 1.8 0.8 0.3 3.2 12.6 1.4 3.6 ...# Z" `- g) o- C" y, P f
## $ chol : int 261 302 176 244 248 280 562 200 259 236 ... U" P* R2 {) b& s! j4 ?
## $ albumin : num 2.6 4.14 3.48 2.54 3.98 4 3.08 2.74 4.16 3.52 ...
! l [2 m$ ^( v; L! T## $ copper : int 156 54 210 64 50 52 79 140 46 94 ...
0 n0 C; h' }3 E7 W! K }* @7 e## $ alk.phos: num 1718 7395 516 6122 944 ...
; K9 w- O `, } E2 y## $ ast : num 137.9 113.5 96.1 60.6 93 ...' |) A* W* [) i
## $ trig : int 172 88 55 92 63 189 88 143 79 95 ... ?* L) x& ^* N0 P1 a o
## $ platelet: int 190 221 151 183 NA 373 251 302 258 71 ...
* b& B4 s, V8 `0 U$ G' s## $ protime : num 12.2 10.6 12 10.3 11 11 11 11.5 12 13.6 ...
- z& E, v$ v) N4 P* y## $ stage : int 4 3 4 4 3 3 2 4 4 4 ...
8 Z: ?9 y( J" Z* k/ i% W4 b, O, M p8 V t
19 |; z4 S" Z" N6 z
dim(dat) # 232 20( O: F% x4 K' X- m/ s. V
1
3 _& [4 M, w$ Z2 [## [1] 232 20' ]( d2 w2 ?# a
1
$ }' D: F0 S6 ^9 z: m1 j! _: k7 Y然后就是准备计算NRI所需要的各个参数。% t: r0 M: B" j3 h9 j
3 Y7 ~# j* T3 j5 K8 Y
# 定义结局事件,0是存活,1是死亡
+ x! a# z+ o( k* xevent = ifelse(dat$time < 2000 & dat$status == 2, 1, 0)
2 E: U. l ~9 \7 Y- H' W% `; L, ]7 S3 A
# 两个只由预测变量组成的矩阵+ c8 e ?# D# S; @+ S, D
z.std = as.matrix(subset(dat, select = c(age, bili, albumin)))
) C# t! [; ?8 k0 v2 S( Gz.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))# [' S$ |' P1 f i% D) T* u
' Y+ s% f$ C; w! v4 ]' K0 @
# 建立2个模型
- Z: M! F" C9 O X" n8 R$ E7 mmstd = glm(event ~ age + bili + albumin, family = binomial(), data = dat, x=TRUE)
' P" K9 h' w3 f; I, wmnew = glm(event ~ age + bili + albumin + protime, family = binomial(), data = dat, x=TRUE)0 P9 O7 o$ o% L/ e( `( P
. h' {# g& z8 P J# 取出模型预测概率; l) h2 H+ w. P$ e- g6 _
p.std = mstd$fitted.values
, h- i, N6 s3 H8 p8 ^p.new = mnew$fitted.values( [& [, c( C! x, n9 k% m8 J
& z3 F5 r: d# f) m" c: c, v
1
& D* [9 Q* `* i* {* o: B然后就是计算NRI,对于二分类变量,使用nribin()函数,这个函数提供了3种参数使用组合,任选一种都可以计算出来(结果一样),以下3组参数任选1组即可。 mdl.std, mdl.new 或者 event, z.std, z.new 或者 event, p.std, p.new。, ~" r, K" U( n% a( u* }* D
$ ?. n: j: ~2 d- r( P8 v6 n
# 这3种方法算出来都是一样的结果+ F1 m6 A1 C8 v7 O! _
( H, o$ O9 Y+ n8 f# j2 [0 {
# 两个模型
$ x% N! x" i2 q2 r6 {nribin(mdl.std = mstd, mdl.new = mnew, / q$ [1 `3 m; @5 X8 v4 f
cut = c(0.3,0.7),
0 n5 v/ A! f# w5 ?- Q niter = 500,
* e0 r L$ f& W0 q) T updown = 'category')
: C0 U9 Q& t+ u$ k4 h' I7 H5 x0 G' \
a! S" v; C4 C. ]. e5 ]9 \# 结果变量 + 两个只有预测变量的矩阵4 Z" X- _1 m6 z. P) f
nribin(event = event, z.std = z.std, z.new = z.new,
- z" s9 z# m1 x P3 c$ ^ cut = c(0.3,0.7),
( m- n# K, g" Z5 I9 H niter = 500, 6 B9 N, Y( E! X8 { P. ]2 A" _
updown = 'category')
% h# I7 A2 V# d
Y5 a6 }. {9 K$ Y) {7 f## 结果变量 + 两个模型得到的预测概率) U% x1 j: r' [( t& ]
nribin(event = event, p.std = p.std, p.new = p.new,
& _- W; Q4 I0 O: O9 _ cut = c(0.3,0.7),
, |. S$ F# _, p2 j niter = 500, 2 y4 r! F. D7 i2 [
updown = 'category')7 s: Q. d8 M- {, A$ ^# c$ e
' E; @+ A* Y; R9 m o0 r2 [
14 D1 l# i8 F- q" j0 b4 a% t( W
其中,cut是判断风险高低的阈值,我们使用了0.3,0.7,代表0-0.3是低风险,0.3-0.7是中风险,0.7-1是高风险,这个阈值是自己设置的,大家根据经验或者文献设置即可。
) [% N% i, R( e
8 V0 E. n" e7 D0 gniter是使用bootstrap法进行重抽样的次数,默认是1000,大家可以自己设置。
/ \' K4 Q& V( E2 B* X9 v# h l( p1 m, L. i- n
updown参数,当设置为category时,表示低、中、高风险这种方式;当设置为diff时,此时cut的取值只能设置1个,比如设置0.2,即表示当新模型预测的风险和旧模型相差20%时,认为是重新分类。6 E n9 \3 q8 R1 d+ P
, h5 _0 |2 k9 K$ i" ^: ^上面的代码运行后结果是这样的:
4 X& B0 N. _: _" l# s- p9 c/ q* L( H+ R4 Q+ P9 V- G
UP and DOWN calculation:
" [8 j! t1 n+ W #of total, case, and control subjects at t0: 232 88 144
9 e8 x7 ]9 q* y$ W' c6 V' y% X) z% N5 p" K* A( d) }( ]
Reclassification Table for all subjects:
: ~3 H+ [# l! g& D { New
7 M' \. T* K" G+ V2 fStandard < 0.3 < 0.7 >= 0.7# F4 }3 R: H: ]9 [3 a3 Q# Q/ l" v2 W
< 0.3 135 4 0
$ _- F! O3 _+ O# D < 0.7 1 31 4
3 f. r! `; c. p' R- e >= 0.7 0 2 55
8 w% m) u5 ?$ r- i) X) H8 d6 P* b' f& U+ p1 a3 D+ a5 O
Reclassification Table for case:8 I$ l/ \5 T) l4 C" x# G; a6 \: c
New
5 a [9 y& v" J9 K* AStandard < 0.3 < 0.7 >= 0.7
% f0 O, \ t& g* ~1 ^8 K% E < 0.3 14 0 0; e8 q& m: a# |8 L9 C: c6 n
< 0.7 0 18 3
3 _; _& E, {7 N# m >= 0.7 0 1 52
4 Z; D2 j/ k9 o: s0 F% J- E) f, h" Y. ^- W( n
Reclassification Table for control:* u2 ^' x" {8 v) l6 @0 }0 h- @6 J1 _
New
; H7 p# _- W" P6 Y" HStandard < 0.3 < 0.7 >= 0.7
# }0 P2 c5 h9 p! ^ < 0.3 121 4 0
" v8 O' q& b2 Z/ Y& P. Q& m < 0.7 1 13 1
3 ?% J* f' h* l$ s, Z) H >= 0.7 0 1 35 r& o: d0 K& y' D6 o4 y" G4 d
1 U$ q- k) K3 ^8 T2 \; @
NRI estimation:4 D" o% T( @4 O5 N7 X
Point estimates:! E/ y: C+ ?1 k: G4 @) b
Estimate8 j z1 s" Q. f% o; [2 v
NRI 0.0018939390 d7 T# }! ?5 w9 `" f1 R
NRI+ 0.022727273 L1 |3 P; I( m4 x4 p& l1 O
NRI- -0.0208333333 [) a9 H3 Y9 b5 Q/ M* u
Pr(Up|Case) 0.034090909
$ Z- P5 w5 y. l% mPr(Down|Case) 0.011363636- i8 W5 v: {! R# ]
Pr(Down|Ctrl) 0.013888889( z4 M4 }4 x1 o! |7 h8 H! C
Pr(Up|Ctrl) 0.034722222
+ z7 x0 A( t n+ _' B1 T, |% \* v5 }* `: W& E7 x8 h2 S" p
Now in bootstrap..7 G+ ~9 s( E1 D2 [
# y8 j* L% X0 }6 a
Point & Interval estimates:+ F, Y |# [* o+ k4 H4 r
Estimate Std.Error Lower Upper5 U+ B ]: u. A* k" o
NRI 0.001893939 0.027816095 -0.053995513 0.055354449
* T- y3 w4 T7 G: h4 e) n* c$ {0 ZNRI+ 0.022727273 0.021564394 -0.019801980 0.065789474# r- r2 u9 `( y/ h
NRI- -0.020833333 0.017312438 -0.058823529 0.007518797
7 G4 @8 o+ b3 A) pPr(Up|Case) 0.034090909 0.019007629 0.000000000 0.0721649482 U. b- E2 O9 C4 O9 B
Pr(Down|Case) 0.011363636 0.010924271 0.000000000 0.039603960
0 k/ r6 O$ Q R+ M3 QPr(Down|Ctrl) 0.013888889 0.009334685 0.000000000 0.035211268' D0 R z* I/ o0 o8 Y8 S+ k9 y8 @
Pr(Up|Ctrl) 0.034722222 0.014716046 0.006993007 0.066176471
: X! i7 j: V2 W4 e# W( _
; U+ E; j# E, R" K. ]. W1# l+ @; c- s9 b8 n( w( t! n! \
首先是3个混淆矩阵,第一个是全体的,第2个是case(结局为1)组的,第3个是control(结局为2)组的,有了这3个矩阵,我们可以自己计算净重分类指数。; Q* e) ^- E8 i# \
4 v. D* m; N, K% p9 I7 y
看case组:; g8 B1 d7 s' n- H. n
, G. H4 V4 u! R/ m X7 M' T3 F
净重分类指数 = ((0+3)-(0+1)) / 88 ≈ 0.022727273
5 n. j' t" j" w0 F
) |' y3 r$ Y& D" g5 O( x& ^再看control组:
6 d3 q. F( d* p
. j, _! T4 G* d" n; g; P; Z; N净重分类指数 = ((1+1)-(4+1)) / 144 ≈ -0.0208333333 o. ~* b3 ~6 l! F* B6 ^0 v2 O3 C
1 R6 Y \- g( K/ W1 B$ t6 F" Q相加净重分类指数 = case组净重分类指数 + control组净重分类指数 = 2/88 - 3/144 ≈ 0.0003156577 ?; e/ l9 x! c1 F* ^$ f9 H( y
/ f) |5 U' S# B% j( B1 L6 M; Z再往下是不做bootstrap时得到的估计值,其中NRI就是绝对净重分类指数,NRI+是case组的净重分类指数,NRI-是control组的净重分类指数(和我们计算的一样哦),最后是做了500次bootstrap后得到的估计值,并且有标准误和可信区间。+ [" [3 c9 B2 r# m# b0 [3 f" _4 c [
' n) e) L$ I9 r' K2 ]1 W最后还会得到一张图:
/ c# P1 A% Y) y* n1 _) s( t! r
1 _3 p2 ^2 w7 F. n; ^: p* _8 a4 B4 _这张图中的虚线对应的坐标,就是我们在cut中设置的阈值,这张图对应的是上面结果中的第一个混淆矩阵,反应的是总体的情况,case是结果为1的组,也就是发生结局的组,control是结果为0的组,也就是未发生结局的组。
* e I& F, O; t5 i" m2 i. ?% I9 t4 Z; W. ^2 j/ l. o0 r
P值没有直接给出,但是可以自己计算。9 B, a8 M; b8 ^
; |5 g% o" S" j6 C/ R/ ]7 z# 计算P值5 r0 M7 j( C5 J. l2 M
z <- abs(0.001893939/0.027816095). m6 H) l; w E2 ^3 c6 I
p <- (1 - pnorm(z))*2
5 i! F/ j1 x2 ]5 t) M7 \p
4 p8 w( ~$ V. I0 g( W( b1" v4 e% ?# i) K3 r4 c. ^& s
## [1] 0.9457157' ?, M5 m3 K8 R
1
" M# I8 `0 Y' y5 {# F% UPredictABEL包
' R; n* O0 ^' a/ F* k* y7 Q#install.packages("PredictABEL") #安装R包8 S5 k7 t% P c1 t
library(PredictABEL) 0 u4 [% u+ M/ @
: P8 r Z; f5 x4 K$ K0 z: i7 c: ?: y# 取出模型预测概率,这个包只能用预测概率计算
/ B3 x2 k5 E' O' [p.std = mstd$fitted.values
) @4 U1 Z9 Z* x* w: S% Pp.new = mnew$fitted.values # g' A& `. s$ t: l! m0 r+ ?
10 U9 N9 D( b8 G! R n
然后就是计算NRI:
; H$ {8 M( C0 x# F- e% q2 a1 z M- W
dat$event <- event
$ Y9 C4 m& P* F$ `& C$ m0 ~* Y. T' m! Q' L" S0 w. g
reclassification(data = dat,
, L/ I$ Y# U* F. @- H cOutcome = 21, # 结果变量在哪一列/ ?; J% H' r: k+ B6 y0 x4 f1 v
predrisk1 = p.std,
8 Y% ~% e2 k5 H4 W predrisk2 = p.new,
6 ^" t* ]% `) L) w: w ] r1 e cutoff = c(0,0.3,0.7,1)# ~$ e t& y# ]# V4 L
)
( n- F( U, L9 }$ o7 j1: B0 I' D: `. J' r0 X9 A
## _________________________________________
( @ H$ G/ G+ J& X6 Q) L' ]## . E Z/ g9 U! I4 b* k4 t
## Reclassification table 2 a7 O2 |9 E" T
## _________________________________________8 } N- N# O) m/ P, i
##
( E, ^( |% ~: O% E" y## Outcome: absent ' @8 @9 _5 f* ]
## E$ G0 k2 _* Z0 s* I
## Updated Model2 s$ x# ]& }. I- w
## Initial Model [0,0.3) [0.3,0.7) [0.7,1] % reclassified W( n7 O4 S9 g; {
## [0,0.3) 121 4 0 3
; B4 G6 F, j7 L9 f( \ N7 x: w: W## [0.3,0.7) 1 13 1 13
: M! a+ ?% X" b) h- L2 _## [0.7,1] 0 1 3 25) t: F' ?$ w5 U" ^
## 1 |4 y$ N$ ~& _; g& ^
##
# Z8 ^4 h# ^( o9 Q% ^4 f## Outcome: present
+ w0 Y* m& v6 C( s## : l- m% C& e0 n! L2 |# k" @
## Updated Model/ J: a# F: v. t8 f' `
## Initial Model [0,0.3) [0.3,0.7) [0.7,1] % reclassified F( d3 G. }3 G! d( ]; a
## [0,0.3) 14 0 0 0; Y6 b9 Q+ C+ K
## [0.3,0.7) 0 18 3 14/ M' e; n' ~8 S9 C/ z. F4 O3 l
## [0.7,1] 0 1 52 2
* ~# y4 U% o" Z6 x' ]5 K( U* O##
* l4 f( m9 t+ e, z! f##
: ^& V# s! f% N' z+ a# K# e## Combined Data
. Z# }7 `/ n' U## + y7 h x% ^' L7 U
## Updated Model& m- p/ K+ n% T6 J% h, E3 s
## Initial Model [0,0.3) [0.3,0.7) [0.7,1] % reclassified
6 X" R I) R D## [0,0.3) 135 4 0 3
/ m4 M5 { p4 l/ u) s8 i## [0.3,0.7) 1 31 4 14
7 S: m' O( z; |0 K# G## [0.7,1] 0 2 55 4+ L/ u4 H k1 k2 v! d2 W4 N
## _________________________________________
$ x4 r* `$ C# P8 h$ }; O- r% K## + L8 ~5 W! L* c8 G
## NRI(Categorical) [95% CI]: 0.0019 [ -0.0551 - 0.0589 ] ; p-value: 0.94806
+ b) X9 i8 k7 `## NRI(Continuous) [95% CI]: 0.0391 [ -0.2238 - 0.3021 ] ; p-value: 0.77048
7 s8 \! n# E3 E5 l## IDI [95% CI]: 0.0044 [ -0.0037 - 0.0126 ] ; p-value: 0.28396' {* c0 N1 H- T- \
5 m' q$ g! [3 F' M. n1' e+ F5 h1 O+ G, }* x
结果得到的是相加净重分类指数,还给出了IDI和P值。两个包算是各有优劣吧,大家可以自由选择。; r4 ~. R8 T, h# O5 L' a# ?
, s0 T% J# v7 X9 U y: N8 W生存分析的NRI; W+ F m5 O* p6 q) i) K# n
还是使用survival包中的pbc数据集用于演示,这次要构建cox回归模型,因此我们要使用time这一列了。
7 a1 ] v5 X4 y, h9 _$ z5 u1 k2 ~! ^+ X' ]
nricens包& C3 ]3 e# j; Z$ j
library(nricens)$ ]2 l' h7 U! p
library(survival)
3 E" D, r4 d& X& [ b, A3 I' s- n! W# i8 x; A b: q
dat <- pbc[1:312,]2 G2 [. b. R& A
dat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡
: R: Y! F& W: ^- K$ o8 F' Q* Z1& I" C9 d% a* v6 @
然后准备所需参数:
5 @, j+ N) h* ]4 E/ `. n" V' n, L4 w, c( L7 D( S
# 两个只由预测变量组成的矩阵; k: V" m$ j* t8 }' A
z.std = as.matrix(subset(dat, select = c(age, bili, albumin)))
3 b1 I; _, M$ i! Ez.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))7 q h5 U& c W
/ @0 |7 k5 R' Q9 l/ U* \1 ]2 l# 建立2个cox模型) |* w0 F) I% r( z" ~
mstd <- coxph(Surv(time,status) ~ age + bili + albumin, data = dat, x=TRUE)3 O2 `' v Z) q; E
mnew <- coxph(Surv(time,status) ~ age + bili + albumin + protime, data = dat, x=TRUE)7 F; u+ E) y2 f
g1 [! N& ~- _) L" T1 Y* ^# 计算在2000天的模型预测概率,这一步不要也行,看你使用哪些参数
3 F+ y% C, I- ?! X- e0 @p.std <- get.risk.coxph(mstd, t0=2000)8 W" N% M1 C4 f9 o$ Y
p.new <- get.risk.coxph(mnew, t0=2000)* z- o4 l$ ?7 G ]
1, ~/ j% }4 a( E, _, [
计算NRI:
7 I! R, F- u o( A( Y+ N
# [: m% i" E7 r' |. f" ~nricens(mdl.std= mstd, mdl.new = mnew, ! z7 T# ~, R7 c/ S/ ?5 S
t0 = 2000, " B) G& V9 B* i- f' \
cut = c(0.3, 0.7),
N1 U& C& W8 f' u niter = 1000,
, }$ b1 ~- V) X updown = 'category')- _. i8 a& v9 s/ n' m/ a
% {* g* M0 L, g' k9 n: d/ y
UP and DOWN calculation:
+ n5 S, ]/ K- s+ j+ E5 E6 g" S #of total, case, and control subjects at t0: 312 88 144. R' {0 ^5 ]7 a% e* g
# s5 ~5 E4 W4 W! H$ \# u
Reclassification Table for all subjects:- Z9 ?" \& C: ]8 n: \0 V" R
New ^2 Z! t4 i% g6 p6 g- U
Standard < 0.3 < 0.7 >= 0.7
5 N) C( S$ T8 D% @ < 0.3 202 7 0
0 h5 n; Q9 g: D9 K k9 _ M < 0.7 13 53 6, N; y: ]$ K9 }$ f
>= 0.7 0 0 319 W" \8 {) B: F8 D) T, D9 }4 s$ N- k w
$ e' J1 w, E/ P; ^( \
Reclassification Table for case:
5 G% t/ z5 i1 s* O% Z D New
; [4 ^+ l5 p2 @ qStandard < 0.3 < 0.7 >= 0.7/ p/ k; e( E0 _: @; j" I. U- s
< 0.3 19 3 0' M) |6 K! ~ h) i Y
< 0.7 3 32 45 M3 X6 g' ^, X
>= 0.7 0 0 27. Y6 n, n" x* K7 @7 s4 o
5 A" y2 e( f+ @, e) y$ b Reclassification Table for control:
4 \! d5 }2 K1 A, @3 S) \- `9 W0 s New; I& N1 b3 Z3 f7 t3 u+ T" ^# B7 |
Standard < 0.3 < 0.7 >= 0.7
+ j4 K p3 c$ Z, L3 i < 0.3 126 3 04 `# c. l! y$ ]4 s7 E
< 0.7 5 7 2
& z( t( g. F' L >= 0.7 0 0 1- D* [0 R6 }. w! J; G
' x: i0 x6 {# T1 D2 [NRI estimation by KM estimator:
7 k+ E% Y' C, F: i0 A* B* r3 j. v6 h4 v( I" m6 U5 J, ~+ l
Point estimates:
, {. K! q0 }) o& O' s$ F9 ^ Estimate7 w4 F4 r _' O Z# [2 `6 I
NRI 0.05377635
! M, W( v' w: @NRI+ 0.03748660
0 @9 F. x0 Q' w- `2 KNRI- 0.01628974
# S/ h( D7 E! zPr(Up|Case) 0.077089380 L2 o3 Y `$ g
Pr(Down|Case) 0.03960278. w+ Y) r7 t/ S7 n* v6 U; u
Pr(Down|Ctrl) 0.042563526 J, r. B; K# R1 G$ q2 i, m
Pr(Up|Ctrl) 0.02627378
6 w6 `: B) A; Z
$ q! k" s9 r4 i; ~- P& t2 Q) p' J6 `8 U9 bNow in bootstrap..& T& B0 V6 N, I _7 H# w# w
1 A p4 e* K5 X* b6 |Point & Interval estimates:0 Q1 @4 p4 O1 Y8 ~1 }3 J
Estimate Lower Upper6 b. k, {1 t1 W# s
NRI 0.05377635 -0.082230381 0.16058172
0 @- l- n7 o. {) j$ RNRI+ 0.03748660 -0.084245197 0.132317761 D4 K! E& ]6 O
NRI- 0.01628974 -0.030861213 0.06753616
- E$ r+ y1 y! d- Z: }Pr(Up|Case) 0.07708938 0.000000000 0.19102291
* g+ L+ O/ R: p( F7 u" j( A KPr(Down|Case) 0.03960278 0.000000000 0.15236016/ E5 P8 _0 q7 D# j# x1 T6 u B
Pr(Down|Ctrl) 0.04256352 0.004671535 0.09863170
5 I. U& `9 Q6 Y* b! PPr(Up|Ctrl) 0.02627378 0.006400463 0.05998424 {( z# d2 e0 f$ B
; e0 h7 t; }" L p, G) K
1
! J* r& t) B9 B# u4 K' c! ?
6 t. T+ y7 D4 y5 Q7 h# O! C, K- z7 cSnipaste_2022-05-20_21-49-386 t; O6 v6 m7 _: R! }! s! T
结果的解读和logistic的一模一样。- s3 t2 H3 A6 l
: A0 A& E5 A6 J! i8 {; E- L
survNRI包
: h/ @$ b+ e Y9 ~6 Z& ^0 {1 w# 安装R包
/ s e9 D* a; M# t3 S8 \6 vdevtools::install_github("mdbrown/survNRI")
5 Y4 O8 P6 @) O9 p1
9 D5 ?6 L4 K$ F( h0 {; P; _, j6 e加载R包并使用,还是用上面的pbc数据集。
: h% U2 {+ n& b9 ?* K- A5 C( I! H% l. J- A% @0 U8 \
library(survNRI)
- d+ J6 u+ ~9 T% i1( @4 n- X$ q, o4 m% r _
## Loading required package: MASS
) H% I' E9 S7 @: x1* D; n- I( ^$ b h
library(survival)) |- @' j; ]2 k+ c. l1 j: _
- N3 y- J& N1 b. c# 使用部分数据
/ x0 L! K* i6 s) `; jdat <- pbc[1:312,]
# L; K! w% P2 w Y, r. k6 rdat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡6 @8 M8 y" Z4 G# Q) I0 `0 ?) K* p4 z/ ?
9 l0 i d. e0 r9 @( Cres <- survNRI(time = "time", event = "status",
6 T6 s( z% O1 j: i5 O5 m6 P! a model1 = c("age", "bili", "albumin"), # 模型1的自变量
& a- x$ x7 b; R: g5 L model2 = c("age", "bili", "albumin", "protime"), # 模型2的自变量
& ?6 x( v' o2 i* O W0 k" v data = dat,
0 u. {) _2 ]' F' d0 |( s) o predict.time = 2000, # 预测的时间点
( `' t* `: y+ n7 [, }* @- Q method = "all",
" ?) g6 Z- B- N' {0 c bootMethod = "normal",
2 C- w: m$ N8 T! h+ J# A5 [ bootstraps = 500,
: P* x E/ P/ r" d! q8 Q! ^7 ]' g alpha = .05) [% w7 _ P/ ~: S4 H7 w
1 D: A+ ` O+ @' E( k0 j% R+ g; g) q18 v! A: m* V3 i8 j% Y5 W7 S
查看结果,$estimates给出了不同组的NRI以及总的NRI,包括了使用不同方法(KM/IPW/SmoothIPW/SEM/Combined)得到的结果;$CI给出了可信区间。! U+ o; J4 t$ p3 t
. A. K* O8 W) b, ^, V" l: y( bres( O! T% L; r/ K2 K
13 q( ~# a+ \% i4 |
## $estimates, g+ \4 X# A) Z) W* ]: M
## NRI.event NRI.nonevent NRI
+ U2 C% o0 i6 V4 c5 A Z## KM 0.20445422 0.3187408 0.5231951
' f: ~* P- }; ^0 _" _+ l2 L: t## IPW 0.22424434 0.3273544 0.55159877 t$ F$ d, [1 J/ q* U9 T5 G
## SmoothIPW 0.19645006 0.3144263 0.5108763
" H) n1 I8 A& p/ S) v) |## SEM 0.07478611 0.2632127 0.3379988
4 J! M1 q( n j% I( I## Combined 0.19633867 0.3143794 0.5107181$ b) X' i7 @3 V# w! C, y
## 4 {' @- @9 c( ^5 s& S7 l( X( u( G5 U
## $CI) m: U' ]. ~' E' ?: ?
## $CI$NRI.event; a# Z9 R# Z- A7 u6 N' L
## KM IPW SmoothIPW SEM Combined
' ]% E3 X |$ C4 W- d, y## lowerbound -0.03915924 -0.02185068 -0.04724202 -0.1162587 -0.04737237 O" g3 O9 t3 @$ _ q8 r
## upperbound 0.44806768 0.47033936 0.44014214 0.2658309 0.4400496$ N+ k3 w Z- s! p* u
##
+ z0 g" Q0 z$ p- @! L( _## $CI$NRI.nonevent
0 s' t) ~( E1 H# [% d+ L$ v## KM IPW SmoothIPW SEM Combined ~. Y( ]# J) l) f3 z7 ]
## lowerbound 0.1317108 0.1396315 0.1286685 0.08638933 0.1286426& y, v/ C3 @) i, K/ _
## upperbound 0.7102251 0.7393216 0.6966341 0.51482212 0.6964549
% k6 O, T9 L2 c8 j- ^0 b##
) G5 s! c+ Q; j) } N8 j5 E## $CI$NRI
3 z* K4 l# p0 }% S( K# g## KM IPW SmoothIPW SEM Combined
: a/ X/ K A) m## lowerbound -0.05112533 -0.04569046 -0.05439863 -0.04132364 -0.05443409
1 h/ d& v3 u5 y0 }5 A- H; f## upperbound 0.89306122 0.92464359 0.87970125 0.64253510 0.87953153
! P. p ~2 n, M5 r##
- M0 L) \' _% @: ?##
. [, ], e" M+ _) u1 `" g6 j- p## $bootMethod
0 r3 N' p6 X' {) u## [1] "normal", f% t6 M1 _! g, q
## 8 o; i' m5 v3 Y D1 ^- m
## $predict.time
' @0 Q# R- U# s$ m2 V7 @## [1] 2000
4 V0 q! G, l% r- n& a## 0 l, q; A0 z5 E4 b; I
## $alpha6 ~+ `4 Q9 E4 s2 _( U8 s
## [1] 0.051 {$ t. Y" P' f
## 0 j3 T: \; X& R. P' Q
## attr(,"class")
! W* M4 ]+ x& I( s! ~ `) B## [1] "survNRI"
, e7 z) c1 i" J$ s3 j! G4 A
# t7 N. _+ y. r0 N9 Z0 A1- K7 m+ y! ?- b
OK,这就是NRI的计算,除此之外,随机森林、决策树、lasso回归、SVM等,这些模型,都是可以计算的NRI的,后面会继续介绍。大家如果有问题欢迎在评论区留言。
7 \# x. b0 N1 r& ?/ a( i0 q: }: L$ b% S! l
本文首发于公众号:医学和生信笔记$ W* x: V; M: d
: U$ _+ f, |3 ]$ }+ C9 O8 _“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。
/ D! L) P9 u7 p4 a& a% f本文由 mdnice 多平台发布
3 R& U2 m: o. B————————————————
$ \) P% U) p2 x; I3 [3 H版权声明:本文为CSDN博主「阿越就是我」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
2 P& g% e! i u9 h2 u原文链接:https://blog.csdn.net/Ayue0616/article/details/126768006
' c/ v0 P, I" q: f) H4 X! C" ~/ H$ s( h: |2 O' E& d7 Z- u
- n' m% J; q% Z2 o) b1 _; O1 P8 s |
zan
|