- 在线时间
- 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年大象老师国赛优 |
" L' Z0 G) C) d' J5 V3 x净重新分类指数NRI的计算
]8 k0 N4 o+ g1 W. Y; @ Z8 o5 z“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。
) m. l5 Z6 ?* z' pNRI,net reclassification index,净重新分类指数,是用来比较模型准确度的,这个概念有点难理解,但是非常重要,在临床研究中非常常见,是评价模型的一大利器!3 K$ H# D/ {" R6 c* M
; T% |$ G( P* |: f. ~$ `; ~在R语言中有很多包可以计算NRI,但是能同时计算logistic回归和cox回归的只有nricens包,PredictABEL可以计算logistic模型的净重分类指数,survNRI可以计算cox模型的净重分类指数。
6 B2 c7 A1 o% J. y3 V* ^! ~! {! }0 ~
logistic的NRI* B8 k( A+ t* F/ y* Z+ v2 D
nricens包
& \; u" V; T% {, Q+ Y: o* ]4 r9 cPredictABEL包% `) X' H8 `4 x
生存分析的NRI+ s5 ]: t/ |4 b2 B
nricens包
5 H. F+ r0 A& E3 w4 UsurvNRI包. D/ D4 ] e. D
logistic的NRI7 {" t* G: C8 Z" A3 s8 s5 K: ]5 U9 e
nricens包
! R! Y0 E4 _! q/ a% R#install.packages("nricens") # 安装R包
) M! c/ G6 V' O2 `! Elibrary(nricens)* x+ K$ i! Y4 @/ m7 [
1/ X' m0 g# X5 e1 E6 U& A6 y- l8 \
## Loading required package: survival# e- a- ^( l. E. y. D* g0 @
18 Q7 @+ z0 D6 a! \
使用survival包中的pbc数据集用于演示,这是一份关于原发性硬化性胆管炎的数据,其实是一份用于生存分析的数据,是有时间变量的,但是这里我们用于演示logistic回归,只要不使用time这一列就可以了。
" g! q9 H) r: m, V
, u0 a8 n0 J$ x$ L0 f1 elibrary(survival)
/ x! _$ _ x$ P7 v6 u' S; `' l# N9 R9 \
# 只使用部分数据
4 |, @0 f2 n& ~% ?7 X+ k) }dat = pbc[1:312,]
" W4 m" F2 w4 cdat = dat[ dat$time > 2000 | (dat$time < 2000 & dat$status == 2), ]9 S( z% c! p$ I$ M5 v8 d
. Y D4 y! C6 u! ?/ c0 ystr(dat) # 数据长这样! I6 v- x9 ~1 s" H# }
1$ t. `9 F) g! [ E& j/ Q$ F
## 'data.frame': 232 obs. of 20 variables:
+ G7 |* a0 f- \7 `. H' H$ |## $ id : int 1 2 3 4 6 8 9 10 11 12 ...
5 F* {( p6 u) W [) H! f## $ time : int 400 4500 1012 1925 2503 2466 2400 51 3762 304 ...; R. ?% N9 X- x: `& g9 B- n
## $ status : int 2 0 2 2 2 2 2 2 2 2 ...
5 j# g9 @- T! R## $ trt : int 1 1 1 1 2 2 1 2 2 2 ...
2 J" b4 L( K& |5 [2 g# U; u## $ age : num 58.8 56.4 70.1 54.7 66.3 ...
% B0 c# j/ i6 q, T9 s! E## $ sex : Factor w/ 2 levels "m","f": 2 2 1 2 2 2 2 2 2 2 ...' z4 [2 h" ?; m6 G* I3 r
## $ ascites : int 1 0 0 0 0 0 0 1 0 0 ...
' S0 [) i; M8 m ^## $ hepato : int 1 1 0 1 1 0 0 0 1 0 ...3 G, l- n1 E( P/ }6 B; X+ D
## $ spiders : int 1 1 0 1 0 0 1 1 1 1 ...
3 m) _, K! |+ }" O## $ edema : num 1 0 0.5 0.5 0 0 0 1 0 0 ...2 Z( z' f1 g/ t4 T8 p- j
## $ bili : num 14.5 1.1 1.4 1.8 0.8 0.3 3.2 12.6 1.4 3.6 ...
9 K- I2 x; m$ {2 T## $ chol : int 261 302 176 244 248 280 562 200 259 236 ...$ ^: L7 P) h: q$ K( A% G
## $ albumin : num 2.6 4.14 3.48 2.54 3.98 4 3.08 2.74 4.16 3.52 ...
. k6 _" S) v- O! e1 ?5 m## $ copper : int 156 54 210 64 50 52 79 140 46 94 ...
6 @9 C9 j' w; u: x, h## $ alk.phos: num 1718 7395 516 6122 944 ...
8 k/ ?9 o; u) j0 A! Z. k## $ ast : num 137.9 113.5 96.1 60.6 93 ...5 ?" ^5 J; V3 y. h. ~" u
## $ trig : int 172 88 55 92 63 189 88 143 79 95 ...( e6 _4 F% F* b# r
## $ platelet: int 190 221 151 183 NA 373 251 302 258 71 ...
4 H {" R9 s9 D" F" _+ |## $ protime : num 12.2 10.6 12 10.3 11 11 11 11.5 12 13.6 ...0 P O. G7 L7 Y! d
## $ stage : int 4 3 4 4 3 3 2 4 4 4 ...2 A. V4 t+ X2 m1 v: |8 I
. y4 w( t# _( Q+ z8 N' k; K1 u* C
1+ k: I3 }* \8 D6 M3 o
dim(dat) # 232 20( c* ]2 u7 ^: |. m, M u6 ^
11 w* c* l0 ?2 s
## [1] 232 20
[9 h8 p7 x- a n; _1" y- V% U* [, M3 {* M9 ` v
然后就是准备计算NRI所需要的各个参数。
/ U/ n/ g5 x6 ]# `
1 x2 ?2 h; G, H o# 定义结局事件,0是存活,1是死亡
6 g* v M& x' o( t- [7 ^event = ifelse(dat$time < 2000 & dat$status == 2, 1, 0)3 G" M2 {& V# @) C
0 o3 H! A+ Z( _: S# r0 V$ ~
# 两个只由预测变量组成的矩阵5 n) r9 R- v3 `' J8 S$ Z; k
z.std = as.matrix(subset(dat, select = c(age, bili, albumin)))9 |$ j7 V' P& e7 g( r+ L7 H3 D" C& N
z.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))8 b" C+ n2 a/ G3 s. m' L
' P0 d1 G! T4 w- G3 A# 建立2个模型) Q6 w0 ~7 _; J k& Q/ O
mstd = glm(event ~ age + bili + albumin, family = binomial(), data = dat, x=TRUE)( d2 I. R @4 B* @; v
mnew = glm(event ~ age + bili + albumin + protime, family = binomial(), data = dat, x=TRUE)
) s! U, ?- b: E3 P2 X+ k
/ N; V9 L' L ?0 u) q/ c! g# 取出模型预测概率' J! ]1 _+ D% S) h3 ?
p.std = mstd$fitted.values0 G7 U0 D5 G- |( K% U7 ~8 q
p.new = mnew$fitted.values: L# v0 _4 U4 b& L$ f8 `& ~6 \
/ r- j" d$ T4 k+ O" K1% h" G3 r1 M: y# w( z
然后就是计算NRI,对于二分类变量,使用nribin()函数,这个函数提供了3种参数使用组合,任选一种都可以计算出来(结果一样),以下3组参数任选1组即可。 mdl.std, mdl.new 或者 event, z.std, z.new 或者 event, p.std, p.new。
" ^) u' Q/ b N9 _* {# v, D h) u p, @3 ~( k7 p8 z$ a
# 这3种方法算出来都是一样的结果
6 i9 [: k+ u3 {2 w6 o! ]) W9 I
, o+ t8 j5 ]! p6 U5 J& W# 两个模型) X) r# E8 D1 H* y$ A$ D
nribin(mdl.std = mstd, mdl.new = mnew,
2 _, Y& F2 }* n* V+ |( t cut = c(0.3,0.7),
3 q$ h/ V9 D6 e% D8 A, R niter = 500,
/ [0 M) p7 @" a( h4 L" K0 j updown = 'category')" C) b$ u6 O, s6 Y: D! J$ M5 k% ?
3 I1 t4 {# n5 M3 a0 L/ [# 结果变量 + 两个只有预测变量的矩阵9 y3 I# x. M/ I, @3 h4 y
nribin(event = event, z.std = z.std, z.new = z.new,
4 l, l9 N g w) B: _ cut = c(0.3,0.7), ) S! s/ l7 k7 e. ~, x
niter = 500, 9 q9 l0 I' _5 c _2 G9 W! O( r
updown = 'category')9 o0 m3 T# q' M9 s Y
/ p5 i0 X6 _: h; E' u/ o' y## 结果变量 + 两个模型得到的预测概率
* g" k2 p& A. P' F( A- {1 Rnribin(event = event, p.std = p.std, p.new = p.new, 4 R8 d+ h. R* c
cut = c(0.3,0.7), 5 Y* m7 |$ `( {4 R
niter = 500, / o1 f/ f' [& n; E, _! W
updown = 'category')) H# @4 i) }: }+ T3 r* f8 w& D
W4 R3 ^# @2 \
1
+ r& ^: }, v$ b5 ]% ]0 u1 U" C% Z" }其中,cut是判断风险高低的阈值,我们使用了0.3,0.7,代表0-0.3是低风险,0.3-0.7是中风险,0.7-1是高风险,这个阈值是自己设置的,大家根据经验或者文献设置即可。6 J( }% s7 e% i8 w! [' }0 t. x
. U& B. ?! a4 S; jniter是使用bootstrap法进行重抽样的次数,默认是1000,大家可以自己设置。4 k6 N$ R& H: `* j
. r1 a0 b+ S# w+ W7 ~& n
updown参数,当设置为category时,表示低、中、高风险这种方式;当设置为diff时,此时cut的取值只能设置1个,比如设置0.2,即表示当新模型预测的风险和旧模型相差20%时,认为是重新分类。3 F( j+ G' d3 N6 Z |6 c' b
, L6 Y4 C- y0 U( O0 v* `
上面的代码运行后结果是这样的:/ j8 Q: \9 q* p
+ T- T/ W+ A* `
UP and DOWN calculation:
' _% R' _: \5 M" Q #of total, case, and control subjects at t0: 232 88 1442 W3 }0 u4 q+ |: k
m2 u& B# Y- n0 I/ g* I
Reclassification Table for all subjects:1 x# j P+ P! B9 c, f
New
g* \6 u5 K& PStandard < 0.3 < 0.7 >= 0.7) q; g. o8 L" K4 F. L
< 0.3 135 4 0
/ X# p; `5 W3 h < 0.7 1 31 4" i8 \: }, a, H% z2 v5 m
>= 0.7 0 2 551 D' m" w; Q" {; R
+ n7 ?7 h) R; W& A
Reclassification Table for case:" H6 M. p- H8 J4 s# f( }* b
New7 ^8 r% W1 A, z
Standard < 0.3 < 0.7 >= 0.7- o/ W5 s& i5 r, D5 s
< 0.3 14 0 0
+ u2 {, j# T+ n, S3 D < 0.7 0 18 3
# ^- i$ f5 s, r& ^9 P >= 0.7 0 1 52/ T. l2 K) u4 y. R* F! o @
; B2 L5 \% z7 P: {$ S8 U Reclassification Table for control:. A. x6 d- G# ]' e
New
6 e' r( F) H* OStandard < 0.3 < 0.7 >= 0.7( `( \3 k7 j! L5 r
< 0.3 121 4 0! @! `2 p% w. [( A3 Z
< 0.7 1 13 1& v& X( ?6 E8 M. s' ~$ P
>= 0.7 0 1 3# Y5 C( J$ Z, S: V# N
% M; w, N( t1 d8 n) | S' A7 rNRI estimation:
- ]- Z8 J& A3 f7 n, y @( ^Point estimates:
: T& X' o6 o1 }6 h6 a( p! Q Estimate9 o$ R |3 ^; I6 q! C
NRI 0.001893939
% }. e1 r* D5 zNRI+ 0.022727273' p- ?7 X, Z3 ?4 n) G$ R A
NRI- -0.020833333
$ i9 t$ p) y7 ~+ Y0 ePr(Up|Case) 0.034090909
# o8 t2 F" p$ `" APr(Down|Case) 0.0113636366 H' L8 f" H7 f: S: B
Pr(Down|Ctrl) 0.013888889
7 b O. @" {( E; J) s1 {" t2 BPr(Up|Ctrl) 0.034722222
, X: g5 A4 B% I D- D" T& Q
) l: h- h8 D2 t$ A L4 M3 sNow in bootstrap..
/ m1 z" b& L; y1 s; T: D
T1 Z+ E+ m4 JPoint & Interval estimates:
- r1 x' Y! ]' t, n n# i$ e; Q Estimate Std.Error Lower Upper
2 p8 d8 E+ R/ B( Y- p8 U+ P- R' P( ?NRI 0.001893939 0.027816095 -0.053995513 0.055354449
5 l. Z* e8 H7 V0 j, i+ g$ RNRI+ 0.022727273 0.021564394 -0.019801980 0.065789474$ Y8 b3 J0 X' O& E7 x2 W- O# Q1 m) F
NRI- -0.020833333 0.017312438 -0.058823529 0.007518797
$ L& h, d- ~9 E) j; F4 jPr(Up|Case) 0.034090909 0.019007629 0.000000000 0.072164948
3 V9 @. G. x6 k6 OPr(Down|Case) 0.011363636 0.010924271 0.000000000 0.039603960
6 e5 J, i9 g4 JPr(Down|Ctrl) 0.013888889 0.009334685 0.000000000 0.035211268* _* A, N9 ?/ c+ }
Pr(Up|Ctrl) 0.034722222 0.014716046 0.006993007 0.066176471
! ]# v0 M+ I4 i; s5 T9 R
q5 c$ o5 W! i+ K/ M. e: B8 w+ Q1
7 P( f" \2 D; ~4 v首先是3个混淆矩阵,第一个是全体的,第2个是case(结局为1)组的,第3个是control(结局为2)组的,有了这3个矩阵,我们可以自己计算净重分类指数。& |/ t, T8 u H; z; J, ]: {. e
7 `6 [) U7 E4 D% T( N/ s看case组:
5 _; H- w* U6 l9 s* S4 {( s
6 r2 s% B# w T净重分类指数 = ((0+3)-(0+1)) / 88 ≈ 0.0227272737 l( {; Y) C$ l6 m
' v. i ^$ F! [0 L6 D
再看control组:$ t) [) N7 u) O! Z8 P/ k$ |8 A
6 G, R! e. a4 R- K
净重分类指数 = ((1+1)-(4+1)) / 144 ≈ -0.020833333
, K! v$ I+ i6 R3 p( A4 i. j7 x8 M6 h% D! {8 K1 a
相加净重分类指数 = case组净重分类指数 + control组净重分类指数 = 2/88 - 3/144 ≈ 0.000315657
) [6 m4 M. r7 [+ d' Y0 ]' e. R2 j% N+ ]6 A* @! b" m2 W6 y
再往下是不做bootstrap时得到的估计值,其中NRI就是绝对净重分类指数,NRI+是case组的净重分类指数,NRI-是control组的净重分类指数(和我们计算的一样哦),最后是做了500次bootstrap后得到的估计值,并且有标准误和可信区间。+ ?0 \/ |( N% S" o" ]
; p" r* ], D" A* ~5 y
最后还会得到一张图:
( D5 b: L: Q$ L3 C/ f& f0 M M3 s* `0 R* ]! ]- A$ C6 R/ E
这张图中的虚线对应的坐标,就是我们在cut中设置的阈值,这张图对应的是上面结果中的第一个混淆矩阵,反应的是总体的情况,case是结果为1的组,也就是发生结局的组,control是结果为0的组,也就是未发生结局的组。
+ E9 z+ m/ t R% p. b) ?5 `% w# [' z9 ^
9 ^# X! F3 T8 R7 R1 u5 I3 y7 i: N' eP值没有直接给出,但是可以自己计算。
9 y% b r2 S4 Z$ O$ v9 X, T: G k w/ d8 R
# 计算P值+ @& ], u& @* ~7 [3 v
z <- abs(0.001893939/0.027816095)/ U/ D/ j% v2 q: A
p <- (1 - pnorm(z))*2
4 q, N8 G" L- P. h" J. O, qp
s1 a8 a! |- t6 f3 t% O1
0 a5 c. p- b& F3 M; n r% U## [1] 0.9457157
+ e) p' @1 X1 a* q1
8 v7 _1 P$ r6 j5 P/ TPredictABEL包
1 b4 r6 x# o9 ]8 Q#install.packages("PredictABEL") #安装R包
% s. d5 o5 |8 A# ]8 zlibrary(PredictABEL)
0 `3 y3 r/ i. i- a) K2 d
: n) x1 ?, m# N8 H) S. U4 I+ ^; d4 A# 取出模型预测概率,这个包只能用预测概率计算; ?6 \7 I' O- R0 L9 Z5 G: h
p.std = mstd$fitted.values+ t1 H D; ]1 V; @8 c/ t( Y
p.new = mnew$fitted.values
6 ]* z) P, ^+ A6 m- v6 V# c1! W! m. ~. c. X+ ^! L& U" g
然后就是计算NRI:0 b8 v. ~# K; n& ^# k1 y; V
* b# M* P. @! N% xdat$event <- event
9 O2 Z% o* I* W3 e0 p- f$ t/ i: w; u) G: b! g! r
reclassification(data = dat,
w) S" e) R3 {: c cOutcome = 21, # 结果变量在哪一列
+ O* J1 _5 k9 S" p) S) E" }( _ predrisk1 = p.std,
# n% }8 X4 w8 p predrisk2 = p.new,
3 I7 y2 X; f/ \4 y! V3 T cutoff = c(0,0.3,0.7,1)
1 V) j! j$ Z! j9 _4 ^8 X/ o+ \ )
& b2 ?7 T8 h- e) m8 _: t1 g& T9 Q7 e1
+ `/ `+ m+ G d## _________________________________________3 F9 L7 e+ ]9 X- K- J
##
6 f. a# ?# Q3 I3 R## Reclassification table
+ v4 D4 l9 v- @2 X* ^* L## _________________________________________; A) o+ n; P5 V
## & q q* x0 P+ ?; G7 U. H
## Outcome: absent 9 F% y( V" [" Q: ]1 X/ ~
## 0 N o. G2 [% H$ _
## Updated Model+ }* B; I. ~4 @
## Initial Model [0,0.3) [0.3,0.7) [0.7,1] % reclassified2 R2 v" C) W4 e' g) W" {
## [0,0.3) 121 4 0 3/ U. c; e! j# z) Z, _5 s* t
## [0.3,0.7) 1 13 1 13
/ T; F: R6 z( M0 k j## [0.7,1] 0 1 3 25; V X+ Q! U# l
## ' R+ O4 ~. G N0 V
##
) Z7 g; y6 {* u4 m. v## Outcome: present
4 D" u; r2 h: n2 N/ }##
4 @2 I% ~6 v9 G) d2 b# y$ g; X5 N## Updated Model- \, K7 b5 \2 t& v. o! `- P: [
## Initial Model [0,0.3) [0.3,0.7) [0.7,1] % reclassified
/ e d: P) e4 A; H, H## [0,0.3) 14 0 0 0- ?8 C. a( F+ h! B- C
## [0.3,0.7) 0 18 3 14$ W; ]; Y. h! N) t4 D! V" H* M2 B
## [0.7,1] 0 1 52 2
5 ]" ]! V X( ~& m$ u+ `## 4 V! p3 f/ D; G; U3 ]8 B
## 4 i, n# {3 J8 r0 s3 C
## Combined Data + ?# Y4 h( B; S4 j
## 0 M. Q( L/ |2 I) K' p
## Updated Model* O$ L# f; a" m4 {9 t7 M! Q
## Initial Model [0,0.3) [0.3,0.7) [0.7,1] % reclassified
" y& W. Y. T |! \5 |## [0,0.3) 135 4 0 31 g3 J; H& L; N8 t o: w4 O
## [0.3,0.7) 1 31 4 14
' V" N7 C' v, }6 Y( I) F9 o## [0.7,1] 0 2 55 4
9 N% _* u1 \& v# I" \) g; Z## _________________________________________# I4 e& m' {& g M' h* G" A3 ~
## - X+ K% U+ g" U2 G+ d- q
## NRI(Categorical) [95% CI]: 0.0019 [ -0.0551 - 0.0589 ] ; p-value: 0.94806
) o& n8 S$ C# [# ]; O; t) G7 b## NRI(Continuous) [95% CI]: 0.0391 [ -0.2238 - 0.3021 ] ; p-value: 0.77048 ) a# t5 a Q8 \. z% _' `, T
## IDI [95% CI]: 0.0044 [ -0.0037 - 0.0126 ] ; p-value: 0.28396& h/ u; [: J4 ]4 o. w
7 ~1 T; [/ F; @9 ?) j- S+ T1 P
1$ L; K4 M0 V) a3 q3 P9 y T
结果得到的是相加净重分类指数,还给出了IDI和P值。两个包算是各有优劣吧,大家可以自由选择。% q5 X/ e- c) k9 e$ C
" J: i% d3 y6 {& O. N% l+ d
生存分析的NRI
# S) R) S8 V4 b2 c; {0 w还是使用survival包中的pbc数据集用于演示,这次要构建cox回归模型,因此我们要使用time这一列了。
$ |0 a- `2 k4 W( f1 W; c1 s" H' e! }8 w4 k# v# x0 j8 t
nricens包
8 K; M7 ^" [: C) G* H( N8 ?3 Vlibrary(nricens)
5 s) [8 u8 S Z7 B2 {1 glibrary(survival)
7 k" c8 p: J# M: E: ?7 Z# i& q+ h3 S" s; x1 e, r/ _0 N2 P! I% m
dat <- pbc[1:312,]
/ U# r$ g, C' a- G' ~dat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡
; r7 ]7 ]. d- j# Y1 ~1
: c. ?9 d$ M3 h0 N5 W% ]然后准备所需参数:( F& o! p( G6 O$ y3 q+ Y
% V0 l9 w" N6 e1 J# 两个只由预测变量组成的矩阵- V% Q2 z8 s8 K u6 r F
z.std = as.matrix(subset(dat, select = c(age, bili, albumin)))
; V' W. g3 @, ?1 i! c4 `z.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))
7 y/ p9 ~6 ~( E- D [0 g( L; y+ S0 I
1 K5 Z, K/ ?" i7 `1 |# 建立2个cox模型
. l: J2 `# j/ M; smstd <- coxph(Surv(time,status) ~ age + bili + albumin, data = dat, x=TRUE)
& K% D! I# ~# d* x+ ymnew <- coxph(Surv(time,status) ~ age + bili + albumin + protime, data = dat, x=TRUE)
+ @# { B( {; g, S! }; T) \8 ]; Q; N# U
# 计算在2000天的模型预测概率,这一步不要也行,看你使用哪些参数# I0 C+ D, ^, p" }' L; `4 F" F
p.std <- get.risk.coxph(mstd, t0=2000)) t, z7 F" y9 P: W, U" V
p.new <- get.risk.coxph(mnew, t0=2000)
+ ]* G' ?* i% X* o& I0 H' M0 Q11 L" K9 G! V+ X; P7 a6 D/ X
计算NRI:
4 x/ f3 O' z$ t2 D; D) _# Q* n% n) a& j
nricens(mdl.std= mstd, mdl.new = mnew, 1 o; C3 D& x. X+ e; G
t0 = 2000,
, @/ j2 H; Y& ?$ D cut = c(0.3, 0.7),6 B/ ~- O! C2 D) Z9 v7 D
niter = 1000,
" O5 H7 G5 W, I; s- c h" D ]3 A updown = 'category')
9 x& m2 V8 h8 E( e# i
& U1 i& E+ x/ c; i3 MUP and DOWN calculation:* N7 o% W0 P# u6 l% U6 k+ l
#of total, case, and control subjects at t0: 312 88 144
8 y. ^' H! e0 n6 `- O% Z+ f( F
! P' @0 u' U* { Reclassification Table for all subjects:$ H, S; ]. m- [; ]4 Y/ A1 \' y8 \
New2 Y. }+ x* e! ]/ ^
Standard < 0.3 < 0.7 >= 0.71 N+ E* r6 V3 g# x4 n' b
< 0.3 202 7 0
! t( e! S4 w+ \0 H& r H0 s < 0.7 13 53 6
' q: [; o- U4 ^; k >= 0.7 0 0 31
) N. o; Y7 Y: w/ }5 }3 x
6 ], z( D( K9 Z Reclassification Table for case:
) w" J& c* u+ l! ]8 P New
n! n5 E' J$ m# K% ]4 ^; TStandard < 0.3 < 0.7 >= 0.7: U/ k: R& f1 O( }( y9 a
< 0.3 19 3 0
! c% u0 U4 v F+ p* g7 d < 0.7 3 32 4+ j8 o& Z' ^" x2 [+ ~ Q0 _1 y
>= 0.7 0 0 27
9 G q6 r; A- D5 D
' @" j# B( A. W) i& ~ Reclassification Table for control:
7 J, W5 [" l' p3 z, c8 G$ M New
) n+ d! i7 z; e- X7 d2 xStandard < 0.3 < 0.7 >= 0.76 [+ n! j, L" d C* f5 }
< 0.3 126 3 0; k1 C) j; S7 a# {5 [ @3 E5 Z* |
< 0.7 5 7 2
* X+ G2 \& E, M' `# X >= 0.7 0 0 1) D# V5 e- {. \( l6 y$ ?
% e& c. _5 Q i: L
NRI estimation by KM estimator:
" E) n. b7 m D- n8 u: F/ X3 q! D" S/ ^
Point estimates:
4 f. l) f7 G& f% ~. v Estimate# o. i& U5 F! [7 \3 y1 X2 }
NRI 0.05377635
" N. V, d' F! {/ uNRI+ 0.03748660
( H1 [0 C, L- R, ONRI- 0.016289748 u h) f. T1 X6 j- g8 V
Pr(Up|Case) 0.07708938
& N% {3 `4 S0 R7 Y6 k+ M+ bPr(Down|Case) 0.03960278
' b3 R: X5 ]) W! W9 r3 ]Pr(Down|Ctrl) 0.042563527 t# q* h" f) g8 ?; x1 Q: l5 z
Pr(Up|Ctrl) 0.02627378
( c. r! Z4 w: T$ @! e# ]* B# l) e& C$ {7 t3 O, I
Now in bootstrap..& W( B) _' q4 P( Y6 p3 T, E% L1 w
( |3 C& N" F" p, kPoint & Interval estimates:& A7 d+ @. d9 v8 C" G# g6 o
Estimate Lower Upper0 \$ k. [% A+ T/ [
NRI 0.05377635 -0.082230381 0.160581728 Z1 G( m9 n3 L
NRI+ 0.03748660 -0.084245197 0.132317763 d! G3 x# h! K& J2 A% p9 \2 Q" P9 z
NRI- 0.01628974 -0.030861213 0.06753616
7 C; l7 m" F# k1 w6 o) ZPr(Up|Case) 0.07708938 0.000000000 0.191022911 w( a" ~) i/ p* R2 V% s
Pr(Down|Case) 0.03960278 0.000000000 0.15236016& q+ ?5 @* l0 Q
Pr(Down|Ctrl) 0.04256352 0.004671535 0.09863170
' `# ~+ X/ p: R& K IPr(Up|Ctrl) 0.02627378 0.006400463 0.05998424
+ P% ^% o) D2 y2 Y% [' `' u8 F+ b2 h. v/ f6 [5 H, \
1
6 g8 y! h: z' l( }0 A
, t4 j6 w& W- b, s* ]8 VSnipaste_2022-05-20_21-49-38
. r4 _, r5 }0 E) o6 X5 P结果的解读和logistic的一模一样。
% Z q; U4 q& t! {+ H0 x
7 w4 Y) `$ S9 l9 V% hsurvNRI包) g- w# S( G: Q) y) k
# 安装R包
% S, ?2 D! C) Xdevtools::install_github("mdbrown/survNRI")
3 e/ }0 W5 Z! `+ }' x16 ^5 I" C! A6 N0 |$ S& O
加载R包并使用,还是用上面的pbc数据集。* T; d7 X4 Y7 _8 ^/ J
4 |/ c7 @+ ~; F8 [6 k1 Wlibrary(survNRI)
8 p$ w) C# |9 h4 ?% J1
# v$ e2 o! F; c' f" F# `8 x3 k## Loading required package: MASS/ C7 ] X' d8 n; K0 r' k8 A" Y6 }
1 ?) S/ X6 F7 m/ t; _2 g( [/ C. e
library(survival)6 r2 ], Q: k& `4 C+ V
% Y z6 \! S( C) _
# 使用部分数据
) W7 s! Z$ C r6 hdat <- pbc[1:312,]3 }' M8 L1 Z4 A# a# K% C( k
dat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡2 R( t8 Y# p& H. d! R$ a( A
1 }% i( j" ]: Q6 Lres <- survNRI(time = "time", event = "status",
: |# l3 r. X# b9 V6 i model1 = c("age", "bili", "albumin"), # 模型1的自变量, c" h* Q. e& j3 W q5 ]! K
model2 = c("age", "bili", "albumin", "protime"), # 模型2的自变量3 |% h7 [' h1 N& |
data = dat, . Y4 U: N, H" A/ {
predict.time = 2000, # 预测的时间点
; ^; S' Y* y, W5 y: n! ]) k) [5 o method = "all",
: i, h4 N4 h3 K# r7 \- h bootMethod = "normal",
9 m% U6 Q2 m1 c2 A1 p, V9 }( P bootstraps = 500, % ^, N+ Q& n) B. v, Y
alpha = .05)- j: n. _" z- {) o
7 ^0 o5 |4 K7 C0 N0 r% E
1+ y: V; ]. ]3 Y2 L' ^7 ^
查看结果,$estimates给出了不同组的NRI以及总的NRI,包括了使用不同方法(KM/IPW/SmoothIPW/SEM/Combined)得到的结果;$CI给出了可信区间。/ o I* e/ S) d, o M
$ `0 {" I) M: X& I$ Y8 Sres
0 \. g7 v4 X4 a" r' C# i1% |' e5 z* `- Y' O- V8 i
## $estimates4 T' m' v2 z5 Y( R/ A! N
## NRI.event NRI.nonevent NRI
& v/ x; L+ j* ]1 r## KM 0.20445422 0.3187408 0.5231951: R; R' a2 Q( f* h: Z' U& f
## IPW 0.22424434 0.3273544 0.55159876 X: g) \+ q0 ]0 l( y. D' e
## SmoothIPW 0.19645006 0.3144263 0.51087637 I( [/ ~- b4 U" r7 R- k, W
## SEM 0.07478611 0.2632127 0.33799882 K# C: B$ Z* A( h7 I0 V3 z
## Combined 0.19633867 0.3143794 0.51071813 c+ d- R0 V7 O( _" J
## ) @- E/ h2 @; E& K- m
## $CI
) j4 s: X5 t; a( K3 _ H4 W## $CI$NRI.event
3 K" i3 g$ a0 R## KM IPW SmoothIPW SEM Combined* F$ J( w1 b5 A# N5 a; {6 T4 }
## lowerbound -0.03915924 -0.02185068 -0.04724202 -0.1162587 -0.04737239 M$ k- ]1 P1 b* u
## upperbound 0.44806768 0.47033936 0.44014214 0.2658309 0.44004962 M, g* h/ z2 j. P( b6 M( F
## 2 C# |% ?& _3 P& q0 x
## $CI$NRI.nonevent( W# D7 G! W% u/ K& T) f
## KM IPW SmoothIPW SEM Combined/ W" y3 f) L+ o2 a+ x3 t4 B4 s
## lowerbound 0.1317108 0.1396315 0.1286685 0.08638933 0.1286426: _' W+ _. T+ z
## upperbound 0.7102251 0.7393216 0.6966341 0.51482212 0.69645496 i; G# P y. [4 M: {
##
" q2 @4 u3 u) v1 o2 e! @! d6 G## $CI$NRI
) |1 I) i" p. u' O, K2 H## KM IPW SmoothIPW SEM Combined
7 z+ B: o+ r+ |; X4 r+ O/ Q; x4 S4 N## lowerbound -0.05112533 -0.04569046 -0.05439863 -0.04132364 -0.05443409
; R3 a: Q4 F4 E+ R- S9 H8 q## upperbound 0.89306122 0.92464359 0.87970125 0.64253510 0.87953153% H5 T% s" e0 f: M9 L1 s
##
2 W& C4 @' j0 N##
5 a) m/ C5 U `4 M" R( o2 S( \% c; D## $bootMethod8 z5 ^: w4 N8 B- a; j& ~: s
## [1] "normal"
: {% P- Q2 H; u& o## ( \7 [, V ^* z( {3 S3 f
## $predict.time
# ]7 x2 t& X. T7 v6 M; ` X## [1] 2000
! ]' |* F0 W5 [: J( E- ^5 \" n## 6 C4 w7 F' X, A& F! e- q$ G
## $alpha9 }- p' G; S/ g
## [1] 0.05
4 c9 P9 l( Q; I0 r- @##
8 V, t- ~) y) {3 Z4 x V0 z## attr(,"class")
9 e0 I- L8 x+ [; B## [1] "survNRI"
3 n( m/ `& P9 M$ D d) i2 q8 Y1 |2 k- L% L W, |& l2 k
17 J! b! r+ M, H) C1 h+ V$ o
OK,这就是NRI的计算,除此之外,随机森林、决策树、lasso回归、SVM等,这些模型,都是可以计算的NRI的,后面会继续介绍。大家如果有问题欢迎在评论区留言。5 q E+ _( u, x# E' D
0 p$ r) k* `3 C% w# X0 V: v j/ e本文首发于公众号:医学和生信笔记" Z# t3 B& S* D G- z% {3 t" e B8 d
- t3 F8 \+ t/ z" K/ K5 a
“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。9 z1 a; r+ O5 u5 d$ I% @8 @
本文由 mdnice 多平台发布6 Y. `* d- {" h/ S
————————————————8 ]* D3 n4 N! `
版权声明:本文为CSDN博主「阿越就是我」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。8 Q. J) q; I9 j. F6 u* C
原文链接:https://blog.csdn.net/Ayue0616/article/details/126768006
M6 ]) i! |: I* G& d0 r& n3 M, {4 ~4 f; C8 {$ a2 L4 n
G3 Y5 A7 G& o
|
zan
|