- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 569584 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 176098
- 相册
- 1
- 日志
- 0
- 记录
- 0
- 帖子
- 5313
- 主题
- 5273
- 精华
- 3
- 分享
- 0
- 好友
- 163
TA的每日心情 | 开心 2021-8-11 17:59 |
|---|
签到天数: 17 天 [LV.4]偶尔看看III 网络挑战赛参赛者 网络挑战赛参赛者 - 自我介绍
- 本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。
 群组: 2018美赛大象算法课程 群组: 2018美赛护航培训课程 群组: 2019年 数学中国站长建 群组: 2019年数据分析师课程 群组: 2018年大象老师国赛优 |
; B8 H; Z R$ Z5 q1 q& q) d# F
净重新分类指数NRI的计算3 F* `9 ^" p8 G) b' H9 b
“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。
9 U2 F1 P6 a8 U U9 u0 |9 tNRI,net reclassification index,净重新分类指数,是用来比较模型准确度的,这个概念有点难理解,但是非常重要,在临床研究中非常常见,是评价模型的一大利器!
( ~' R. u5 U' w( G* `9 x! {- w1 V9 K7 s" V2 x9 W2 q
在R语言中有很多包可以计算NRI,但是能同时计算logistic回归和cox回归的只有nricens包,PredictABEL可以计算logistic模型的净重分类指数,survNRI可以计算cox模型的净重分类指数。7 A6 i! a E$ M. A
: c8 o. O# I! V- R5 J# [: ~8 Alogistic的NRI
/ X7 M5 {5 p1 w) e2 y& ?nricens包0 N% Q8 i+ C5 G6 b+ }
PredictABEL包
3 C' k* R* y, I" ]& h生存分析的NRI8 \8 @% P- `5 D6 k$ x0 t! P
nricens包% }8 y% V7 n6 Z" u
survNRI包; Y* H) S+ n- o1 a: m N9 G9 [
logistic的NRI
* K2 S( o( _/ Snricens包
K5 B7 A/ g0 ]( G* a1 ]% \1 F7 j#install.packages("nricens") # 安装R包0 }$ J+ c( h: }* M6 R: Z" A) F4 m0 r
library(nricens)
2 Z) W1 P% N/ |) f1
; H- J+ N- @, C## Loading required package: survival
* c, f# n9 h7 a* t1( x& H- y( }* x2 W( p) p
使用survival包中的pbc数据集用于演示,这是一份关于原发性硬化性胆管炎的数据,其实是一份用于生存分析的数据,是有时间变量的,但是这里我们用于演示logistic回归,只要不使用time这一列就可以了。- D4 k& R M, ?$ b& @2 _! r% o
& [2 g; _) ?/ q* Y6 N
library(survival), L/ r* s8 I0 x" I
' k# g2 o$ R6 ?- G/ T( w* q9 ~# 只使用部分数据, b% m0 l C* f( w5 \$ B
dat = pbc[1:312,] 1 H, ]) C8 v: r: j- d" n
dat = dat[ dat$time > 2000 | (dat$time < 2000 & dat$status == 2), ]0 B1 S+ h6 x- D3 s( N
, K2 }5 b. C, ^( F) V0 |. e9 rstr(dat) # 数据长这样, E7 i. Y0 K6 s
1# Y! I. o' m% v: N. T+ w' K
## 'data.frame': 232 obs. of 20 variables:
! c h, o; S- v8 [## $ id : int 1 2 3 4 6 8 9 10 11 12 ...
" y. [+ a$ a6 H* e## $ time : int 400 4500 1012 1925 2503 2466 2400 51 3762 304 ...% G r* I" [4 P& Q
## $ status : int 2 0 2 2 2 2 2 2 2 2 ...
U( s+ \$ x/ f# M, q) C## $ trt : int 1 1 1 1 2 2 1 2 2 2 ...
+ N% T+ r2 b, r. c& f: k# L## $ age : num 58.8 56.4 70.1 54.7 66.3 ...
# s5 i0 L" H' F6 q7 d% p# G, [## $ sex : Factor w/ 2 levels "m","f": 2 2 1 2 2 2 2 2 2 2 ...
8 j+ W- Y W$ D5 l: _7 E## $ ascites : int 1 0 0 0 0 0 0 1 0 0 ...
+ D; k) U' k7 X- q## $ hepato : int 1 1 0 1 1 0 0 0 1 0 .... P* ~6 P X0 q9 G: ]9 X' K
## $ spiders : int 1 1 0 1 0 0 1 1 1 1 ...- \4 b$ U O" w( J4 i5 u* P) |
## $ edema : num 1 0 0.5 0.5 0 0 0 1 0 0 ...
* l! I* Z2 T* O## $ bili : num 14.5 1.1 1.4 1.8 0.8 0.3 3.2 12.6 1.4 3.6 ...
* B }: V0 M0 l0 t2 Y/ c# \## $ chol : int 261 302 176 244 248 280 562 200 259 236 ...
6 I' T" H- M5 t3 ~' p. v$ g( P O## $ albumin : num 2.6 4.14 3.48 2.54 3.98 4 3.08 2.74 4.16 3.52 ... ?$ p0 z* h1 o( p
## $ copper : int 156 54 210 64 50 52 79 140 46 94 ...
, a) F# F" r" W( C% z! o& `## $ alk.phos: num 1718 7395 516 6122 944 ...
3 F6 i* g7 s) C7 R% q8 C## $ ast : num 137.9 113.5 96.1 60.6 93 ...
3 b* z7 u& w# o# z. \* s## $ trig : int 172 88 55 92 63 189 88 143 79 95 ...9 V6 d* X1 }: j1 L; x7 B3 u
## $ platelet: int 190 221 151 183 NA 373 251 302 258 71 ...7 T" B0 T9 u9 Y4 q$ G8 M
## $ protime : num 12.2 10.6 12 10.3 11 11 11 11.5 12 13.6 ...
, t: V* c5 D0 w5 y. y## $ stage : int 4 3 4 4 3 3 2 4 4 4 ...
7 O: w) r1 M+ `
$ L j9 L9 C1 P3 k: Z8 G1
" i& U# N, W" f1 ~# [4 r; |dim(dat) # 232 20
+ W% K( w2 m* x8 @/ r" O/ c- W1$ W8 s8 k6 c1 l" H
## [1] 232 20' G/ T$ ]! @1 {4 [+ R* r. h" B" n
1
7 B: O/ {3 E- I" C4 K: E @然后就是准备计算NRI所需要的各个参数。9 {) n! K: K' d3 Y" m7 i
q u! N+ K' D" `9 |# 定义结局事件,0是存活,1是死亡! R' B5 L2 T0 A3 F; H
event = ifelse(dat$time < 2000 & dat$status == 2, 1, 0)/ w: N, w: y3 B# X! R! X! @3 L9 x) y
2 V2 _* {3 K1 e( v }" E& P# 两个只由预测变量组成的矩阵
, N2 L/ D& S# W. yz.std = as.matrix(subset(dat, select = c(age, bili, albumin)))+ c" R8 }7 n; A1 \. _
z.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))
3 Y* H. o+ t9 S7 D& H) T2 k6 c1 l( F0 m, f) N* J. \
# 建立2个模型
) w' A/ ~0 M. ~1 O( amstd = glm(event ~ age + bili + albumin, family = binomial(), data = dat, x=TRUE)
' G% o2 e$ f+ T, q* xmnew = glm(event ~ age + bili + albumin + protime, family = binomial(), data = dat, x=TRUE)
8 y" y4 k. e' t$ O6 {; w9 Y2 M% {( m9 K! ?
# 取出模型预测概率' b9 C' t- I' t, A- ]
p.std = mstd$fitted.values
: }. \1 w/ y. i( N* @9 r1 Op.new = mnew$fitted.values% U1 W. U- o2 V, c) m
; B* r7 ~( Q* E$ q Y; K; v
1$ A) P( E+ p8 d0 r4 A
然后就是计算NRI,对于二分类变量,使用nribin()函数,这个函数提供了3种参数使用组合,任选一种都可以计算出来(结果一样),以下3组参数任选1组即可。 mdl.std, mdl.new 或者 event, z.std, z.new 或者 event, p.std, p.new。. d( j0 c8 O% w3 k
$ D% x" `3 m5 J
# 这3种方法算出来都是一样的结果- a" i$ i9 }& {) F/ j1 ~/ _. ]
& g4 G) R5 e: q- @" K2 q5 p
# 两个模型1 U4 m P$ \ D! B
nribin(mdl.std = mstd, mdl.new = mnew, % ?$ }. ~) ^( ]
cut = c(0.3,0.7),
: v8 o% b! O5 O+ s. w7 J niter = 500,
4 k; c/ _! ?! b# b; b updown = 'category')
2 d4 u- i$ E% V9 z2 d! U/ g. r- ^" K# A9 A
# 结果变量 + 两个只有预测变量的矩阵/ Y; l4 t: z' H/ U0 [
nribin(event = event, z.std = z.std, z.new = z.new,
+ l' v) N" U3 s! D/ q! ] cut = c(0.3,0.7),
; P! x$ U1 h* l* r4 {: V" i$ ?; u niter = 500,
# N5 Y' u4 m& e updown = 'category')
( }) D- F$ j8 y( P5 ~8 H9 k ]8 U4 Q% g: G2 `7 [
## 结果变量 + 两个模型得到的预测概率! _) D* \! W/ @6 n. G3 R
nribin(event = event, p.std = p.std, p.new = p.new, " s/ C8 z& t5 B$ e$ F
cut = c(0.3,0.7),
( P' T$ `1 d. K$ y7 H( n niter = 500, 6 O' w( l o% p/ ^, R. d
updown = 'category')9 I& f; H9 \: e4 C5 I
) z* \4 @5 F9 U$ l
1
2 q7 x v4 A8 n* p: \5 S b( h其中,cut是判断风险高低的阈值,我们使用了0.3,0.7,代表0-0.3是低风险,0.3-0.7是中风险,0.7-1是高风险,这个阈值是自己设置的,大家根据经验或者文献设置即可。 B4 D9 z4 p9 ~8 a$ B" Y/ ^
x, A: S q, X- a! m+ Kniter是使用bootstrap法进行重抽样的次数,默认是1000,大家可以自己设置。 i. p* g# H5 n' Q* [- \
+ C; W+ \0 [" ^
updown参数,当设置为category时,表示低、中、高风险这种方式;当设置为diff时,此时cut的取值只能设置1个,比如设置0.2,即表示当新模型预测的风险和旧模型相差20%时,认为是重新分类。# h4 |6 z) v8 g6 j! ~! \4 p
* m0 U7 a9 v% d5 Y+ C3 V _上面的代码运行后结果是这样的:! b$ ?* A* G7 ~% f+ o, ^
~9 d/ t0 Z& F% a3 E
UP and DOWN calculation:
0 N5 K1 Z; ]- ~, T& S* `9 Z #of total, case, and control subjects at t0: 232 88 1446 H0 x/ e3 ]3 v' K
; R+ z/ N" d- x0 J, S
Reclassification Table for all subjects: Y& n( Q* k1 F% a3 F
New
( y4 T5 X0 B) V: I8 V( P9 B9 _9 `Standard < 0.3 < 0.7 >= 0.7. `9 S& l0 S. l
< 0.3 135 4 0' }7 U- ? I9 U2 J1 l% x
< 0.7 1 31 4
6 S% U9 i+ Q: W7 \9 M3 Z% i N! z >= 0.7 0 2 55
9 s+ @% t+ U W# V; Q% W8 R
& s/ z, r; X% d$ f& g7 Z Reclassification Table for case:% X0 O5 q) W. O
New
1 U4 I' e& R/ Y3 N! O+ nStandard < 0.3 < 0.7 >= 0.77 s: P; A& x* I6 S3 B. M) n
< 0.3 14 0 01 \+ b6 W% G3 R w& G3 _2 t
< 0.7 0 18 39 S+ ~7 r6 t1 X3 g% S( }
>= 0.7 0 1 52
& R( C! \- ~2 m: Q ~* A; U
; f. k9 L7 d2 r2 {+ X* T' a Reclassification Table for control:
3 [) u0 p7 b4 [9 I$ O, h6 H& Y* Y; C New7 F3 ]1 _6 M2 [
Standard < 0.3 < 0.7 >= 0.77 R7 q, s) {7 P' {3 n, D F
< 0.3 121 4 0
7 k; F: T" i( \+ t1 A/ I < 0.7 1 13 1 A4 `9 p+ V3 [% L' ]/ `+ I
>= 0.7 0 1 31 k! e4 _' `9 o8 D. b
6 t2 \) F* X9 p( z& Q5 j: m' INRI estimation:6 E2 a% m0 r0 m) v1 l- k, B
Point estimates:
5 M4 L- E2 |. m% I% P4 K+ x `: j Estimate; Z" O0 @* ], y" E! r5 |
NRI 0.001893939
) f8 Q0 }, ~& x5 L' ^! W- DNRI+ 0.022727273: o: h1 v! ]/ Q% L8 l; d% S7 M# h
NRI- -0.020833333, P8 J9 K& |& z9 |2 ^3 p1 D
Pr(Up|Case) 0.034090909
! E5 [. ?4 Q6 e7 C! j8 ~Pr(Down|Case) 0.011363636
- v# z( c6 Z# O" m# yPr(Down|Ctrl) 0.013888889) D( B9 Z2 @$ l7 _
Pr(Up|Ctrl) 0.0347222223 x1 L- S! K6 Z# f: s2 M; }# X+ w
a7 q1 G- P" l* Y5 a l5 ?) s
Now in bootstrap.." B- Z0 f# b4 @' [
. G4 Q; W \, B2 jPoint & Interval estimates:
+ ]9 r9 m5 E1 J# w Estimate Std.Error Lower Upper
) H( r$ G6 X5 F5 }/ W' N; D8 MNRI 0.001893939 0.027816095 -0.053995513 0.055354449
, _# H, u- }1 l/ m) J* d1 xNRI+ 0.022727273 0.021564394 -0.019801980 0.065789474
! r1 ^; X! K6 n1 x5 G3 ~0 O* B# ONRI- -0.020833333 0.017312438 -0.058823529 0.007518797; b$ t, h, R/ x1 B6 ~- g2 g
Pr(Up|Case) 0.034090909 0.019007629 0.000000000 0.072164948
+ \6 y6 _: l# b* ~; xPr(Down|Case) 0.011363636 0.010924271 0.000000000 0.039603960: N# W$ {% Z, r0 {* v0 G1 s! E3 R
Pr(Down|Ctrl) 0.013888889 0.009334685 0.000000000 0.0352112686 G2 _' r3 Y" s( Q! w
Pr(Up|Ctrl) 0.034722222 0.014716046 0.006993007 0.066176471( G: {4 b6 A& H% K
' d; Z) b) @5 r* h. U N1# v: n4 C( [; Z5 N3 F9 K: l# D: {
首先是3个混淆矩阵,第一个是全体的,第2个是case(结局为1)组的,第3个是control(结局为2)组的,有了这3个矩阵,我们可以自己计算净重分类指数。
1 y( H- T4 f. S! D0 |0 w$ O% z5 \: x+ f; p$ v6 t0 o0 m
看case组:. X9 ?7 z/ }' e5 B4 U
5 d( S2 M) G% J2 L6 B9 t1 {" Y
净重分类指数 = ((0+3)-(0+1)) / 88 ≈ 0.022727273
5 t# {0 H3 ~# Y# E. }- L% K
& |, L e/ {" j! ^7 q, B再看control组:
' s2 d" @* V; J5 q
% z+ @2 ]% V, R' P净重分类指数 = ((1+1)-(4+1)) / 144 ≈ -0.020833333
. w. G' a1 f$ o# m
7 ?1 Z/ v* @9 L$ |' F相加净重分类指数 = case组净重分类指数 + control组净重分类指数 = 2/88 - 3/144 ≈ 0.000315657
/ r) _! z2 D8 G4 s/ o: D
$ l$ f0 k3 _( a6 U再往下是不做bootstrap时得到的估计值,其中NRI就是绝对净重分类指数,NRI+是case组的净重分类指数,NRI-是control组的净重分类指数(和我们计算的一样哦),最后是做了500次bootstrap后得到的估计值,并且有标准误和可信区间。
5 m1 U' H; Y/ Q7 r# m- V; t- s7 S7 b
最后还会得到一张图:- y( m) l( Z% s) U+ Y
y! }4 H3 p) W0 @0 Y9 q! G& r/ F
这张图中的虚线对应的坐标,就是我们在cut中设置的阈值,这张图对应的是上面结果中的第一个混淆矩阵,反应的是总体的情况,case是结果为1的组,也就是发生结局的组,control是结果为0的组,也就是未发生结局的组。
0 y6 m& S# Z9 a2 O" O7 k
9 D& n" o K4 c8 E. qP值没有直接给出,但是可以自己计算。' \/ {7 P. X- R
' d) Z4 I' ~# g1 a; i/ ]# 计算P值* G9 s$ Y( p V( l. k
z <- abs(0.001893939/0.027816095), a. t; [' X2 P. j& C% ]' P
p <- (1 - pnorm(z))*20 O7 j5 E, `1 b" |' N' K
p
/ j0 g9 a$ Z* U1
- w" V0 n/ k+ L7 J$ |## [1] 0.9457157- o5 f. V( Z2 ?
1
& P) G8 T8 u( r' ]9 _PredictABEL包/ ?" R$ b- ?, L; ^
#install.packages("PredictABEL") #安装R包' u- M* u* O/ L7 {$ ~' z- d
library(PredictABEL)
4 f! q: x$ I4 A( C7 e. {7 A5 g- Q) ?- }) T
# 取出模型预测概率,这个包只能用预测概率计算; t# t7 t/ A- L5 ~/ n' V, y
p.std = mstd$fitted.values- \3 o6 S: s! B U- c7 M
p.new = mnew$fitted.values , x$ t5 a2 h* D+ p$ }0 d1 [! C' Z
1
% g k8 X2 c' S/ x1 |6 v然后就是计算NRI:
0 K+ {5 {" {) H: r. B% ]- O( ]! y- h5 B5 X) a" [5 f' D
dat$event <- event
' L4 a2 O% d' [+ ]1 D/ q2 Z$ Q* g9 s% }
reclassification(data = dat,
2 }3 G9 K3 M- D& D! E cOutcome = 21, # 结果变量在哪一列2 g% d+ L- o b& v" ~+ }0 T3 ~
predrisk1 = p.std,
& I Y) V$ X: B4 A: H. S predrisk2 = p.new,
# V3 K3 N+ U; q! s* ]; s cutoff = c(0,0.3,0.7,1)
5 Q1 p K' j/ F )
: f; P4 O% Q& g. k' l# \1 ~1+ D+ @! F; A' N, M/ d, q' R# {1 E+ u
## _________________________________________
: {) {+ ?1 O4 C7 Z" q##
Y% B0 O/ |5 O9 o## Reclassification table / ~, r, W! Q# M9 C. X: d0 \/ U
## _________________________________________
' [3 T4 G- P/ O+ F% D# A4 i6 A## - ^/ d. U6 B% V2 c. A; x" ~" }: ^6 q
## Outcome: absent 5 m" Q7 \5 [) ]" Z( c
##
7 K$ U( p6 e0 M* t, P6 i## Updated Model
/ g7 ^, r0 }. Q/ E0 c- X## Initial Model [0,0.3) [0.3,0.7) [0.7,1] % reclassified2 e2 h3 ~3 o: V n; G" V0 c: }
## [0,0.3) 121 4 0 3* G( k9 R; y9 P! F" t: ]
## [0.3,0.7) 1 13 1 13
' p9 k. ]2 S, s# E- R8 n; O## [0.7,1] 0 1 3 254 H7 X( W; X/ s+ ?. y7 c; D
##
7 T+ ~! R8 z8 |5 R. D! W## U( [( A7 u" s( T& K
## Outcome: present
( \8 r: T- l. x2 z## 1 c' Z5 {( ?0 _/ w0 [
## Updated Model
# L0 b& h. q) {9 f; l. e## Initial Model [0,0.3) [0.3,0.7) [0.7,1] % reclassified
, W- Q1 C4 ?9 _4 O## [0,0.3) 14 0 0 0
{; A- [* `: C1 e5 o7 `## [0.3,0.7) 0 18 3 14, ?$ I* ^$ p5 f/ {- q
## [0.7,1] 0 1 52 24 H1 R4 n) v% Z) v) r/ C( L/ ]4 B* W
##
* p6 N% ?0 D: O% b" G0 r2 {* }1 q##
2 d3 H2 F+ G% z4 V## Combined Data
( E! ^' N9 l) S! @##
! _4 X( @ C" t: A+ A# }9 a## Updated Model+ _& T r2 ~7 L1 a* g/ ~; w1 q
## Initial Model [0,0.3) [0.3,0.7) [0.7,1] % reclassified
* h7 v! {, K0 M( J4 ]- F## [0,0.3) 135 4 0 3' R1 T1 ? \" l, d7 c u$ m, T
## [0.3,0.7) 1 31 4 14
9 K5 J( h/ l" ~# y## [0.7,1] 0 2 55 4. @: {$ t4 Z3 g$ v4 b
## _________________________________________' t; k9 U9 O `+ s u! V) K
##
( J5 P$ L* m: I1 t2 ?- k## NRI(Categorical) [95% CI]: 0.0019 [ -0.0551 - 0.0589 ] ; p-value: 0.94806 C2 ^& p) L) W5 m$ K
## NRI(Continuous) [95% CI]: 0.0391 [ -0.2238 - 0.3021 ] ; p-value: 0.77048 ; P* u }7 {" }4 e
## IDI [95% CI]: 0.0044 [ -0.0037 - 0.0126 ] ; p-value: 0.283967 ~9 K; `( ?$ A! Q. K' }
! ]7 t. B+ e$ w m5 [3 ^1/ J5 J7 N) `1 m2 I. y" @, y
结果得到的是相加净重分类指数,还给出了IDI和P值。两个包算是各有优劣吧,大家可以自由选择。
" `& k/ l {8 [ k/ K* h1 q+ N7 x. k' u! l
生存分析的NRI8 c7 h$ V* }! u/ q5 h! @
还是使用survival包中的pbc数据集用于演示,这次要构建cox回归模型,因此我们要使用time这一列了。
" \6 e5 l' s8 R5 D" H1 Z" h1 I- V, u7 d9 D
nricens包
( o; X+ Q; J4 X1 g) xlibrary(nricens)% n8 X4 o: o: \: A8 Q' `, `
library(survival)5 y) C5 R2 b. Q. ]! F2 l7 W
9 W* f8 s4 o4 u! I+ J0 X4 Odat <- pbc[1:312,]
3 L6 K3 y( n8 ^/ }dat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡, D& M% o3 Z) K* d* D6 k
1
( U$ V# Q, o ~. q7 U3 Y然后准备所需参数:0 \2 Z( I; y( e* f
8 W1 q; F8 g0 @# 两个只由预测变量组成的矩阵 K6 t! W$ k2 S* u) ^
z.std = as.matrix(subset(dat, select = c(age, bili, albumin))). M5 @# ]9 B4 ?. J" y2 \' |1 n+ _
z.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))( Q5 Q t" @' ]$ `8 x( X' T
$ ~$ y& D1 @2 ], \4 C0 B6 Q9 _
# 建立2个cox模型
' Y: u1 a$ c: ?8 Ymstd <- coxph(Surv(time,status) ~ age + bili + albumin, data = dat, x=TRUE)1 U. P2 }+ U) S. z0 [8 }0 q
mnew <- coxph(Surv(time,status) ~ age + bili + albumin + protime, data = dat, x=TRUE)/ a$ G9 T! Y5 y+ F% m
. ]0 r( {0 V3 K( _ N# 计算在2000天的模型预测概率,这一步不要也行,看你使用哪些参数# S! z, @- i( D" L3 T S k* {
p.std <- get.risk.coxph(mstd, t0=2000)
0 a* l" V4 U% z0 dp.new <- get.risk.coxph(mnew, t0=2000); E4 r* n' j5 L1 L
1
# G9 o# o% ^2 J K* Q& P计算NRI:, J( t) F$ C. V- U. B% S9 z
/ h2 ~8 X1 ?: A# g/ |
nricens(mdl.std= mstd, mdl.new = mnew, ' Z) \$ r: j3 K! t, w3 i7 `
t0 = 2000,
, Z0 g8 i3 I9 \* f7 B | cut = c(0.3, 0.7),) L% @5 H2 Q3 L- a& O" ~3 M
niter = 1000,
) x a+ N+ R C6 j updown = 'category')1 ~2 ?9 d, u4 l: o$ u- p
C, p, u2 H1 I4 V1 W
UP and DOWN calculation:
- L; R4 [( T5 ` #of total, case, and control subjects at t0: 312 88 144! N ~, |9 h' L% h9 }1 F
1 i, x0 u" x t; e Reclassification Table for all subjects:1 w( p$ t% O4 X6 t" M
New$ t+ B" F4 P9 p% N) e4 b
Standard < 0.3 < 0.7 >= 0.7
2 d" `2 }/ L0 Q. M < 0.3 202 7 0; l( z+ d$ M% E2 [% B) W* U
< 0.7 13 53 6
" w9 [8 T! K. I# B) E" k- s >= 0.7 0 0 31, i, ~0 a& q# ^
) ]6 j1 i* F/ i: t) a% Q: i" I Reclassification Table for case:
6 I& }# |7 K! R& W; p/ B New
- e1 S0 l8 O+ M& `% U1 eStandard < 0.3 < 0.7 >= 0.7
. ?+ l) n; m) W8 |- f- y < 0.3 19 3 0
2 w5 W) o2 N* K/ w$ p; A < 0.7 3 32 4/ p8 c& c& C- S# L) s6 V* J
>= 0.7 0 0 27
7 X0 j& m9 M+ |6 y: a0 P% C( T4 F- l' Q$ k7 b4 b
Reclassification Table for control:
* [/ F3 [5 X% ? New8 B: d9 {. y( A* E" R
Standard < 0.3 < 0.7 >= 0.77 n' ~" k( W1 V5 D9 @
< 0.3 126 3 0" n$ d7 b! |+ ]) H- W7 L
< 0.7 5 7 29 P/ j: f6 X j6 c3 M( e9 P" ?: N8 v
>= 0.7 0 0 1
- I" ^ d" g' |6 V% V B6 F2 v# |; v2 V, K* t
NRI estimation by KM estimator:# B* C4 W$ c5 E$ w
! N' F" X, w: q3 B& MPoint estimates:
. M- B6 a5 [& S Estimate
; E Z0 j! W6 U/ p- ^7 ZNRI 0.05377635( v! j7 Y" ~, @. M: Q( a
NRI+ 0.03748660
( `, W7 X2 V! WNRI- 0.01628974
- ?- p/ W2 A; w; B6 w1 P( k9 aPr(Up|Case) 0.07708938
$ |6 M4 {% j" iPr(Down|Case) 0.039602785 Q0 w( F8 g' C3 W. o: {4 g
Pr(Down|Ctrl) 0.04256352) u1 ?$ r8 m% r2 o7 i" h% Q
Pr(Up|Ctrl) 0.02627378% }, R# b4 p2 Y# w% n. ]
7 J8 _3 u0 Y9 T4 ]9 D; [8 bNow in bootstrap..8 K8 b, T) ~* S; v9 \! t3 o, g9 Y- w: ~
2 n3 V5 i2 @. ] l6 mPoint & Interval estimates:
: P7 ?! K8 Q7 d" F4 l Estimate Lower Upper
& \( Z0 d* [ p4 e3 O: rNRI 0.05377635 -0.082230381 0.16058172
9 ~; t% W+ c: `9 P/ Y+ PNRI+ 0.03748660 -0.084245197 0.13231776 f' I6 B9 ~0 y# w3 |% s# L, }
NRI- 0.01628974 -0.030861213 0.06753616! o6 o$ ?" u3 R
Pr(Up|Case) 0.07708938 0.000000000 0.19102291
- e8 K" h1 Q5 E/ vPr(Down|Case) 0.03960278 0.000000000 0.15236016
7 T) Z- T# X: A$ RPr(Down|Ctrl) 0.04256352 0.004671535 0.09863170: d! J3 W: z, B# E
Pr(Up|Ctrl) 0.02627378 0.006400463 0.05998424& g9 a8 F" _7 c$ z' F; _2 _$ O% X
1 D; {) D7 h' q6 a% L
1
+ U6 f: _6 D& m( d; w. W! G9 P# c2 a* s. Q4 b2 ]& R2 ?, C% T
Snipaste_2022-05-20_21-49-38
" ]+ i* J9 q$ w1 T, Q结果的解读和logistic的一模一样。& @' f* c X$ H8 G
8 h7 z2 I% R ?2 M: q( usurvNRI包9 G# K: r6 a4 V4 u8 T- R/ S
# 安装R包
) `, d/ [3 `1 y0 t! D8 v" hdevtools::install_github("mdbrown/survNRI")2 n% b% C: b( s' Y
1
$ t8 X# z( K' l0 \& r/ ?1 u加载R包并使用,还是用上面的pbc数据集。( O1 t+ T) Z* y; {# ~
. @2 }7 F% _7 s. ^, q8 H- nlibrary(survNRI)4 w# z$ ^1 P% z+ ?9 G; M) d
1' f2 F b* T9 J+ J5 O9 T5 X
## Loading required package: MASS
: I5 z/ U+ i7 `2 k7 m1
% _$ D q7 i% H0 J2 xlibrary(survival)$ e/ z4 b8 f/ p
9 X$ c0 V1 [. p- ?8 v- H3 d) O" k# 使用部分数据
4 A6 H& m0 m1 B4 s4 D2 {dat <- pbc[1:312,]* p( P {$ F! M3 k9 y; F% S
dat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡& i @0 q; O" q; K
- [2 ]% l3 V8 g# ~2 N' M7 e& t" Kres <- survNRI(time = "time", event = "status", ! \- D, r# F4 f- X
model1 = c("age", "bili", "albumin"), # 模型1的自变量
1 f1 }( K, C4 S model2 = c("age", "bili", "albumin", "protime"), # 模型2的自变量) O& P, L! m1 ?+ ?! t
data = dat,
( }" i9 P* e+ J! ]( r# t* G. \ predict.time = 2000, # 预测的时间点
1 ? V& i; s3 j) k/ ~4 F3 c. V method = "all",
3 |9 Q$ R+ N" s O0 B: A bootMethod = "normal",
: d7 G- ^( T/ ~/ V9 } bootstraps = 500, # P( G& r' I$ Q1 @# p
alpha = .05)
* h$ t6 F. ]5 I1 g: w6 d7 ?3 g
1' l6 c; W2 B1 q7 G
查看结果,$estimates给出了不同组的NRI以及总的NRI,包括了使用不同方法(KM/IPW/SmoothIPW/SEM/Combined)得到的结果;$CI给出了可信区间。, H7 b0 ^6 I- Q ]" L, x- c
) z) g% i2 W1 Q$ I. mres) t9 w! N! j) v; ? q; T- X
1
; ~- C9 x, z% L' }- s## $estimates
8 g1 ?# z! U+ T) U5 }6 k# E## NRI.event NRI.nonevent NRI2 p, V3 [0 U% z+ e1 q ]. }, i) ]
## KM 0.20445422 0.3187408 0.5231951; F( q3 T5 ^. g T1 i8 p* B& y
## IPW 0.22424434 0.3273544 0.55159874 O) J) c( T/ Q) F! y6 g. c
## SmoothIPW 0.19645006 0.3144263 0.5108763
. @8 c8 h/ D8 N/ h" B, b## SEM 0.07478611 0.2632127 0.33799889 J: [5 h2 M4 F) \
## Combined 0.19633867 0.3143794 0.51071810 S5 N: p' v$ G4 @8 A8 z
## : I# e7 s! A) Z
## $CI
$ p6 d1 l1 @. E* u& H% G## $CI$NRI.event. t1 c0 T1 @- I- F) T6 a
## KM IPW SmoothIPW SEM Combined
) a" @( W" m' K+ }# _8 K## lowerbound -0.03915924 -0.02185068 -0.04724202 -0.1162587 -0.0473723
) X9 g$ B& P' J% D4 j* l4 q& e" @## upperbound 0.44806768 0.47033936 0.44014214 0.2658309 0.4400496, O; A N6 z4 e Q7 j% G
##
, }$ [' R9 l8 Y## $CI$NRI.nonevent
" {" }5 ^, j" R6 h& o## KM IPW SmoothIPW SEM Combined
; J- E/ v. a8 |* K/ S; F$ o( D## lowerbound 0.1317108 0.1396315 0.1286685 0.08638933 0.12864268 |. ?7 y, t6 Q3 [% V' p
## upperbound 0.7102251 0.7393216 0.6966341 0.51482212 0.6964549. U& O+ Q* ^+ a- b) a( a' U- E Z3 X2 p
## ) a! ?* r, Y5 v! S" b& i$ r g
## $CI$NRI0 E o: |# e- }% g9 _& B3 L
## KM IPW SmoothIPW SEM Combined) c; T/ I2 ^6 l7 f* ?. X! g& F$ d
## lowerbound -0.05112533 -0.04569046 -0.05439863 -0.04132364 -0.054434099 w) c( i, m* e. O) c+ Q' K
## upperbound 0.89306122 0.92464359 0.87970125 0.64253510 0.87953153% F* m9 j3 {' C6 w: N7 y
##
+ x& \7 u8 c. u+ Z7 z##
1 O0 r/ r0 z8 p' i" O* n& q## $bootMethod
$ v" x" w+ ^$ w/ n4 S: Q3 A* u## [1] "normal"
# J" s3 q) X* a' p% ~##
" T/ l$ t6 N+ f! j## $predict.time' `; {# ?- J' a7 a! H3 {% Q! h8 {9 r9 a
## [1] 2000
- p' B X/ z3 @, _8 D4 R##
7 z3 O$ z% o7 Z## $alpha/ R8 [9 [5 N" C/ M/ I' R5 K
## [1] 0.05' Z, r/ z5 a! a! [8 t2 U" W
##
2 a- e- w: h5 `! e1 S7 ^7 p## attr(,"class"). E2 Y1 Z) E2 t4 z9 ~
## [1] "survNRI"0 L' m3 I! m6 ]6 L( V# W
' B. O) f5 p) b0 c0 b; s; y6 ?
1; T' p6 I1 b! S" @9 u% G0 S* i1 L- a
OK,这就是NRI的计算,除此之外,随机森林、决策树、lasso回归、SVM等,这些模型,都是可以计算的NRI的,后面会继续介绍。大家如果有问题欢迎在评论区留言。
' u3 l3 g/ m& Z! r7 m) Z* w. Y7 ?& M2 t6 L3 Y) w
本文首发于公众号:医学和生信笔记. \4 R- K! f$ v8 x( h5 i" K1 e
% i4 V3 y! r$ d- _. B& ]1 ?4 F
“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。( l9 b/ z8 K( D6 [4 i4 j& E& [
本文由 mdnice 多平台发布
' [! P( g+ V+ u% n( ?————————————————
6 Y8 G* u M6 N- x2 q4 r/ I版权声明:本文为CSDN博主「阿越就是我」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
1 X' X( g9 E: [! ?: F$ d* \; n, ~原文链接:https://blog.csdn.net/Ayue0616/article/details/126768006" V9 D( U3 h& {' `" b
/ d: t9 y# x# D2 o
, I/ u' r) J" a |
zan
|