- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 564444 点
- 威望
- 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 U' M; `5 F& |. W; X/ b净重新分类指数NRI的计算; e4 W3 W+ X5 u2 {1 \
“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。
9 k- s& C1 q9 _1 UNRI,net reclassification index,净重新分类指数,是用来比较模型准确度的,这个概念有点难理解,但是非常重要,在临床研究中非常常见,是评价模型的一大利器!
B' V5 l [, Y& U, x% { @+ F7 S' [4 B& v; s, r: M$ C. _
在R语言中有很多包可以计算NRI,但是能同时计算logistic回归和cox回归的只有nricens包,PredictABEL可以计算logistic模型的净重分类指数,survNRI可以计算cox模型的净重分类指数。4 ~9 ]7 [- G5 @) R/ v
8 f* i5 M6 i D
logistic的NRI
) [( Q: v' ? h6 x- S: x2 dnricens包$ l. P( ^$ w8 f+ V) ]3 @
PredictABEL包4 l K/ x: D( C: v* t# C" x0 L
生存分析的NRI d; |6 Z3 Q: \+ {. z& |4 R4 ?
nricens包
$ k! j! P! |' J" hsurvNRI包
E' e% f7 B& ologistic的NRI
. }1 j/ M5 }) Qnricens包
5 \: a" W6 F L% a7 w$ N- [5 ?" m#install.packages("nricens") # 安装R包1 a! H* V8 l. I. a* j9 _
library(nricens)
4 {5 f, `" }& t$ J8 L1* e" R) G1 u5 u; v
## Loading required package: survival
8 A' S+ O- b2 S# w( o/ R: n( o8 Y1
f7 c! P5 N/ I& k) X1 W使用survival包中的pbc数据集用于演示,这是一份关于原发性硬化性胆管炎的数据,其实是一份用于生存分析的数据,是有时间变量的,但是这里我们用于演示logistic回归,只要不使用time这一列就可以了。
- Z- S7 n, D$ @/ o& W: \2 R# X0 [! m% @; a. P
library(survival)+ @+ ^5 T8 D, X/ L
% f% N. b0 B* W3 K3 p# 只使用部分数据
: }# Z- |% k. a: E7 T- @# j( Adat = pbc[1:312,]
: ?! v, p+ @ k4 xdat = dat[ dat$time > 2000 | (dat$time < 2000 & dat$status == 2), ]; R# ^" d& C# D. @" h" z
' ?9 _" O3 | xstr(dat) # 数据长这样
) ]: s( J& S3 a1 C1
2 b3 l/ R3 ~9 U" Q% u## 'data.frame': 232 obs. of 20 variables:- P! ]' i# o+ P @
## $ id : int 1 2 3 4 6 8 9 10 11 12 ...* U3 p- ^( z" a; j, K
## $ time : int 400 4500 1012 1925 2503 2466 2400 51 3762 304 ...2 Q4 g/ r, U, Y' x4 f. E
## $ status : int 2 0 2 2 2 2 2 2 2 2 ...
1 b% _. T5 U- D0 @4 [; M) }6 M. i## $ trt : int 1 1 1 1 2 2 1 2 2 2 ...) W: P" o# x# \- w
## $ age : num 58.8 56.4 70.1 54.7 66.3 .../ J' V! S' E: y# V4 G q- H
## $ sex : Factor w/ 2 levels "m","f": 2 2 1 2 2 2 2 2 2 2 ...
( @+ s1 m# ]# D7 ~ R9 q' U% K# e4 N## $ ascites : int 1 0 0 0 0 0 0 1 0 0 ...
5 h; `5 Z8 P! f% ~6 P0 W## $ hepato : int 1 1 0 1 1 0 0 0 1 0 ...
9 M9 w- ?0 Z4 r- p' N! I## $ spiders : int 1 1 0 1 0 0 1 1 1 1 ...
b3 u; g- e2 h. d## $ edema : num 1 0 0.5 0.5 0 0 0 1 0 0 ...
2 I. k* v) u0 J$ Q## $ bili : num 14.5 1.1 1.4 1.8 0.8 0.3 3.2 12.6 1.4 3.6 ...( z9 l4 T9 @8 i% b. Z% X
## $ chol : int 261 302 176 244 248 280 562 200 259 236 ...9 u( l/ C* K9 o% [
## $ albumin : num 2.6 4.14 3.48 2.54 3.98 4 3.08 2.74 4.16 3.52 ...3 R$ {$ }1 X" Q# V# ?6 f
## $ copper : int 156 54 210 64 50 52 79 140 46 94 .../ ]8 Y1 k; A8 Z' R$ e
## $ alk.phos: num 1718 7395 516 6122 944 ...
! M# V. F; _% I. t% p5 v! s## $ ast : num 137.9 113.5 96.1 60.6 93 ...3 a( Q5 T* R1 w
## $ trig : int 172 88 55 92 63 189 88 143 79 95 ...2 d2 X/ i; z/ Q0 L7 [5 e
## $ platelet: int 190 221 151 183 NA 373 251 302 258 71 ...
1 {1 E/ L9 o1 N: {, u T## $ protime : num 12.2 10.6 12 10.3 11 11 11 11.5 12 13.6 ...
3 u; Y; \9 ^+ p5 I( i6 @( b## $ stage : int 4 3 4 4 3 3 2 4 4 4 ..., m5 E+ b8 F! S+ [! I7 a- S; h
, A( O3 V4 V6 W+ f' ?5 S5 Q$ W2 `
18 X( _' D3 X* @9 }4 H
dim(dat) # 232 20; H+ M% \& ?! \: l
1+ @/ E5 }9 x7 j& O% E, @8 e
## [1] 232 20
7 A/ y8 W; g6 T2 a2 Q1
& L9 z1 W9 @ L( O# A然后就是准备计算NRI所需要的各个参数。
( L1 s/ ?4 ~4 j( r7 x# V" K
% U) `2 A2 q) _$ G8 e# W9 w# 定义结局事件,0是存活,1是死亡" V/ H7 f* N) ~( ?2 |
event = ifelse(dat$time < 2000 & dat$status == 2, 1, 0)
. v' b. o* y% Q& [2 @
+ G5 H( d( b4 u. d% y& V& O0 q# 两个只由预测变量组成的矩阵
' @% g7 Y& V! ^, K* M9 G4 Yz.std = as.matrix(subset(dat, select = c(age, bili, albumin))). C- f; i+ a% v/ c# ~
z.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime))); x( ^+ ?9 S! H: B
# g U3 d, Q$ T6 H( ~3 G7 B
# 建立2个模型/ U; ^! f+ |- B( ?+ \) g, W8 S
mstd = glm(event ~ age + bili + albumin, family = binomial(), data = dat, x=TRUE)5 X; q# {' i: X; J# {5 v) o% m
mnew = glm(event ~ age + bili + albumin + protime, family = binomial(), data = dat, x=TRUE)( a0 U; e& f) t% R7 m1 P( Z+ ~
" D. c1 b- a6 E! }4 R
# 取出模型预测概率
3 P3 d7 F9 x( D: p8 {p.std = mstd$fitted.values
+ o/ w5 w. a+ yp.new = mnew$fitted.values6 @9 @: b$ ~9 M' i5 l
8 Y, U, t/ j2 P, D& _, f `1
2 Z1 F; C+ E+ Q' t. U5 x然后就是计算NRI,对于二分类变量,使用nribin()函数,这个函数提供了3种参数使用组合,任选一种都可以计算出来(结果一样),以下3组参数任选1组即可。 mdl.std, mdl.new 或者 event, z.std, z.new 或者 event, p.std, p.new。
0 ~3 P- K+ N' {, q( |+ s, h1 h7 \) G
# 这3种方法算出来都是一样的结果
' A- q1 }+ S! M9 c& W \5 @$ i
e& ~3 `( L- J1 [$ z4 g# 两个模型
3 i! F3 f6 r* j1 F9 q% @. ]nribin(mdl.std = mstd, mdl.new = mnew, + e+ C- H i' e
cut = c(0.3,0.7),
4 e8 ]' @/ h# T1 ` ]2 v niter = 500,
5 I" }, F. J+ a+ g updown = 'category')# h, ?# x8 j/ k. W! p" d8 M9 o
+ L! ^9 R0 `, V: w
# 结果变量 + 两个只有预测变量的矩阵
5 V7 y3 G6 |$ |* N$ X. B: Lnribin(event = event, z.std = z.std, z.new = z.new, 9 _0 @: ?2 S* E
cut = c(0.3,0.7),
- @$ Z7 k" s( ?6 {5 K' h& ^ niter = 500,
) w; @4 d0 u5 _. [1 o updown = 'category')
+ P# Z! m. o9 D9 h
' H6 i( p4 E9 S1 e4 j7 X: D6 e## 结果变量 + 两个模型得到的预测概率
9 d) U u9 f; L: pnribin(event = event, p.std = p.std, p.new = p.new,
6 u2 Q' |6 n- \' T+ p4 _7 x cut = c(0.3,0.7), 3 m1 o+ O9 n. N2 t7 a0 w& `
niter = 500, . ^/ Q/ c/ |" h S
updown = 'category'); c8 }* Z# U' f& w1 W5 T
# B# j/ f. C- {# b2 |) S2 m1
7 E) V" @; T* Y: s其中,cut是判断风险高低的阈值,我们使用了0.3,0.7,代表0-0.3是低风险,0.3-0.7是中风险,0.7-1是高风险,这个阈值是自己设置的,大家根据经验或者文献设置即可。6 _' L$ i& g9 n, ?2 E
6 ~1 t8 g/ V- v2 I$ t
niter是使用bootstrap法进行重抽样的次数,默认是1000,大家可以自己设置。4 T1 n: N, W' X: H1 ~" ?- P: N5 P
2 `$ t! c1 B; w \# n8 \4 |/ s
updown参数,当设置为category时,表示低、中、高风险这种方式;当设置为diff时,此时cut的取值只能设置1个,比如设置0.2,即表示当新模型预测的风险和旧模型相差20%时,认为是重新分类。
9 F0 a: L a! u) d: J" n
, N- G! u- l8 I) J9 k: x5 Z上面的代码运行后结果是这样的:
5 K4 x" d" S& m s* t# [
$ F' p! }( P: x" ^: f& qUP and DOWN calculation: s/ ]3 c3 c! O3 S
#of total, case, and control subjects at t0: 232 88 144
7 A/ V% k0 Y- W9 Y' d2 i& W6 ~9 e( j
Reclassification Table for all subjects:7 Z5 V9 f8 T3 n7 ]8 q
New
9 @6 K( n4 S6 j+ gStandard < 0.3 < 0.7 >= 0.7
9 y# _) X2 S' M) ^8 Y < 0.3 135 4 0
+ q$ |9 k/ J" t1 w2 G9 o, m < 0.7 1 31 4% U4 ~( [- T) r6 m9 U2 V
>= 0.7 0 2 55
+ q; g% n& {4 \3 m ?
. \& y9 o+ [9 {* c0 Q Reclassification Table for case:
7 I; G P' k: q. U6 | New; f6 S$ Y3 N$ J. r* f6 ?4 o
Standard < 0.3 < 0.7 >= 0.7& z" B& R2 g* N( V4 D
< 0.3 14 0 0
T6 x% C/ W/ B, W! G+ U! ? < 0.7 0 18 3$ c, `5 L) j* _8 t3 t) l
>= 0.7 0 1 527 @4 Z( O- u3 U d* q0 k
* g, c. k3 u1 u( E5 S
Reclassification Table for control:# N( p0 \& c+ E
New
! h/ S5 X+ T% w1 c$ |2 \3 C# gStandard < 0.3 < 0.7 >= 0.7+ W3 ?: H1 k4 E5 R4 g$ |
< 0.3 121 4 0
& m5 n9 v) _8 } < 0.7 1 13 1 v+ g# ] c( E% R* p
>= 0.7 0 1 3
, I H& X- H- E" K K. U- r* `6 B0 y% a# p- O
NRI estimation:7 ]% }- p, M4 y; t/ x
Point estimates:
( c) G! B" G- b Estimate5 k- b- Y) X8 W: ]# S+ I1 _$ _- {
NRI 0.001893939
! i W+ r2 C2 L" g! T$ fNRI+ 0.022727273/ R0 l: F; }0 F( X3 J0 Z. J. @* w
NRI- -0.020833333: I f$ w/ s M7 C3 L
Pr(Up|Case) 0.0340909092 a% L8 d \9 r' t/ {1 C7 J
Pr(Down|Case) 0.011363636: ~: Q7 F. M7 ]! _' ~0 R% K
Pr(Down|Ctrl) 0.013888889
. o: U ~. ^/ C i! H2 O! N& xPr(Up|Ctrl) 0.034722222# v* t1 o- }3 @2 [9 N g
/ L4 W) z1 h* N5 U* R! x( A
Now in bootstrap..; @! K4 K) h; P2 [! ]& o2 T; J
" s6 V+ `' q- P9 w4 Z
Point & Interval estimates:0 h8 U. A! ~' L l; ^3 d6 f& J
Estimate Std.Error Lower Upper( n1 q* j4 e8 L/ b+ R1 P
NRI 0.001893939 0.027816095 -0.053995513 0.055354449
3 |0 L5 G1 Q* w. g+ aNRI+ 0.022727273 0.021564394 -0.019801980 0.065789474+ K7 O: z x$ E7 l: y F2 E# [
NRI- -0.020833333 0.017312438 -0.058823529 0.007518797
|2 U& P2 t7 t' o* z8 y$ \Pr(Up|Case) 0.034090909 0.019007629 0.000000000 0.072164948
! I n5 ]3 b! r# Y: _Pr(Down|Case) 0.011363636 0.010924271 0.000000000 0.039603960
6 ~& \* |: [8 ?* O* ^8 ^9 `/ V' CPr(Down|Ctrl) 0.013888889 0.009334685 0.000000000 0.035211268
& K3 k' M8 H3 E7 cPr(Up|Ctrl) 0.034722222 0.014716046 0.006993007 0.066176471 k8 k+ s1 f4 M' t2 s( q
" m7 z, |2 z. E/ L0 X0 p1 m% n1
2 U: m* _0 @( U" I5 Z首先是3个混淆矩阵,第一个是全体的,第2个是case(结局为1)组的,第3个是control(结局为2)组的,有了这3个矩阵,我们可以自己计算净重分类指数。6 A( b2 S7 b6 K) Y% _8 y2 F
9 O/ ~' `, b5 |; j4 x" S看case组:
% O/ `$ Q& i! \. G* _4 Y# } X5 _. E) D: u! E* |! E
净重分类指数 = ((0+3)-(0+1)) / 88 ≈ 0.0227272733 h# B4 d2 k8 g2 v2 T; ?
# ?1 [ h5 ^0 s9 u6 k再看control组:
$ G9 S! L- L# X2 t" D* {) Z' h& Y# \, T0 m% `* s% M6 C; o
净重分类指数 = ((1+1)-(4+1)) / 144 ≈ -0.020833333
6 e5 _0 n1 }* j% S0 x5 ~" B
+ y) P8 q1 T1 S$ E0 w相加净重分类指数 = case组净重分类指数 + control组净重分类指数 = 2/88 - 3/144 ≈ 0.000315657
' Z" ?3 J4 h2 I) `" s* m- o9 Y- @
' p) a+ e% D6 c1 ~4 {! ]3 [9 g. o$ N7 s再往下是不做bootstrap时得到的估计值,其中NRI就是绝对净重分类指数,NRI+是case组的净重分类指数,NRI-是control组的净重分类指数(和我们计算的一样哦),最后是做了500次bootstrap后得到的估计值,并且有标准误和可信区间。0 d2 [$ S# i& {9 o+ |
! B# |+ @+ I% m) X$ r. q3 q( K
最后还会得到一张图:
2 ?9 K# Q3 w% X0 g. x9 d5 u# ?' V. r9 J
这张图中的虚线对应的坐标,就是我们在cut中设置的阈值,这张图对应的是上面结果中的第一个混淆矩阵,反应的是总体的情况,case是结果为1的组,也就是发生结局的组,control是结果为0的组,也就是未发生结局的组。$ B# m, Q& X) D' n- n1 \ n
! T0 @3 ?$ A6 _% F$ d; P- \
P值没有直接给出,但是可以自己计算。3 K7 @9 f: a" ]# W3 d' m3 Q4 ]
7 R1 N1 j2 z0 Q3 y7 L. P) t/ H3 Q
# 计算P值
! U# k! o9 v2 ]' \ Mz <- abs(0.001893939/0.027816095)4 [: j& h# O3 P% G( |/ E) ^1 O6 t
p <- (1 - pnorm(z))*26 q0 }# R: N9 L# }+ h$ G/ _
p
2 L0 q/ y, t7 j/ x0 j8 H10 Y2 }( p/ N) ^% M
## [1] 0.9457157
# `# x! ]) V" [. `- X0 `9 g1* q" e/ w+ f, ] e0 c: ~: o
PredictABEL包
: m }$ _2 M' w! ^. V0 s; h# C' W5 r#install.packages("PredictABEL") #安装R包
( u3 ~2 ~7 q. _! P3 j |. E) Olibrary(PredictABEL)
% ]8 Y) `, T. ?( E& A2 M
; z8 v( _" E* z% L/ ]5 l# 取出模型预测概率,这个包只能用预测概率计算
( y W5 w, }3 N& r0 v: rp.std = mstd$fitted.values$ {* y- D! k% E4 ^9 f U
p.new = mnew$fitted.values
; @1 x' K0 Y# v+ ]7 j) }14 O( }0 s( r( V% @4 |* N) u; r0 [
然后就是计算NRI:
: S6 I% c; u0 _ d0 G9 v
" d* {) }3 G1 a8 t" X# z$ y6 tdat$event <- event
' U$ i" M5 g0 p9 Q" p3 h
, V4 R' j* h* Z, v( w. ]# k/ [: ~; Sreclassification(data = dat,
8 S% e. Q0 Z7 X' |% k+ ?! L# [; V cOutcome = 21, # 结果变量在哪一列
8 O1 c v5 b& `- R E! i( H% P H predrisk1 = p.std,& T. T( P" o2 b0 Y
predrisk2 = p.new,& Q+ V% |3 k% F% _9 E
cutoff = c(0,0.3,0.7,1)
0 w" d- y3 R. y6 M1 l )" ?, v1 L0 |0 j( {5 X# Q2 e" ]
1
6 [9 D9 j) H$ ?# ~0 ^$ w9 ?4 p## _________________________________________ K5 j. F, ^0 v6 V
##
3 v3 x e# v) g% y9 {& N8 D* r1 Z## Reclassification table
( B/ ?- g& C, ~! c; n8 _$ M## _________________________________________
3 k% `; l$ Q% l. [2 E/ C##
. |, p, o3 l3 ?* m## Outcome: absent
+ ]$ \; Q7 M ^# [##
$ H% y3 T& _9 ^& ?# [## Updated Model
9 ?9 _' b( K: y- w: j## Initial Model [0,0.3) [0.3,0.7) [0.7,1] % reclassified
) Z5 D4 X2 v6 d4 u# T6 O! |2 A6 e## [0,0.3) 121 4 0 3
. j/ @+ m' x! g" M- s" G% T7 I## [0.3,0.7) 1 13 1 13# _3 Z1 A$ h- k# C, p
## [0.7,1] 0 1 3 259 j) u/ t- }( |- G
##
W6 G7 w1 _) v* O##
' ]8 b) e3 v6 P0 x3 l$ t" v## Outcome: present 6 Q! Q- x2 o, P+ h* [8 f
##
; j5 C' G0 b- I5 p" I- R## Updated Model
7 A5 A! u& U% {) ~6 y! o## Initial Model [0,0.3) [0.3,0.7) [0.7,1] % reclassified
% R$ H! q. Q+ v4 g## [0,0.3) 14 0 0 0- w7 ^) d4 \& _% @% g. U6 [5 T
## [0.3,0.7) 0 18 3 14
( x, b3 i7 j& N+ }9 Z## [0.7,1] 0 1 52 20 t: o6 \4 Q0 N( r/ s
## ( D4 i! e6 \9 i/ D; @% D
## + {5 J. U# b! v* U
## Combined Data
% a5 o E3 k' o4 Q' I##
& Z+ o9 p0 ]6 E" o/ _, s4 z## Updated Model) {- P! G, k$ P0 V$ K4 w) f; b# F
## Initial Model [0,0.3) [0.3,0.7) [0.7,1] % reclassified
. F4 J. F1 ~- i( d1 w3 [## [0,0.3) 135 4 0 3( x3 z0 | g& X
## [0.3,0.7) 1 31 4 14" n; z+ S0 L& j8 |7 ~* @" S
## [0.7,1] 0 2 55 49 ~( D( A2 \, q' `
## _________________________________________
+ x, |7 ?4 B. p" n## - |% L2 w% f3 M9 _' w9 q' }
## NRI(Categorical) [95% CI]: 0.0019 [ -0.0551 - 0.0589 ] ; p-value: 0.94806 # g7 |, y4 I9 V* R' o- I6 T
## NRI(Continuous) [95% CI]: 0.0391 [ -0.2238 - 0.3021 ] ; p-value: 0.77048
) |( |; K `% O) j1 n## IDI [95% CI]: 0.0044 [ -0.0037 - 0.0126 ] ; p-value: 0.28396
4 n3 Y! z0 q% ?4 r& z) W' |* [; Z" m3 J; D, P
1
0 _" `, T% |9 z* P9 c结果得到的是相加净重分类指数,还给出了IDI和P值。两个包算是各有优劣吧,大家可以自由选择。0 {5 i$ x) j d) |2 G( ^* r& e- V6 w' O
, _& {+ n+ d8 r; l4 B: o生存分析的NRI
( e3 Y+ |- C6 H. F还是使用survival包中的pbc数据集用于演示,这次要构建cox回归模型,因此我们要使用time这一列了。$ l* w& L* w F2 S9 N9 ]* T
* p: _, v7 ~' {( B4 b
nricens包( t4 ?; b/ i7 a6 v" R4 J2 h2 ?
library(nricens)
, }9 L( A0 K! u( D5 qlibrary(survival)1 j0 n, l# N" R0 s9 `- ]
5 C6 F3 w) |# j7 {6 f- l
dat <- pbc[1:312,]5 D9 m8 R5 D, ^3 v
dat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡 r2 ?: h7 H; `
1
3 W9 w `; S* w; {+ e然后准备所需参数:( z3 T& P5 N3 w$ j3 i3 F( m
# H8 o& F8 G) B9 k, P" a# 两个只由预测变量组成的矩阵
d! }7 j: V, X" rz.std = as.matrix(subset(dat, select = c(age, bili, albumin)))0 T2 v8 a# u2 p, w
z.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))
' k& r$ s/ G5 E; ~
0 f# z2 e" h: s; k% q/ H! t$ \# 建立2个cox模型9 |1 H" l, n, D# F3 B- N4 T
mstd <- coxph(Surv(time,status) ~ age + bili + albumin, data = dat, x=TRUE)4 ^* o0 K$ ~) t0 c3 s0 k( v* M: w
mnew <- coxph(Surv(time,status) ~ age + bili + albumin + protime, data = dat, x=TRUE)+ u9 X1 Y7 e$ d# T3 l2 p# |1 C7 s
- M# ^7 p' I+ g
# 计算在2000天的模型预测概率,这一步不要也行,看你使用哪些参数! \% z/ }8 B7 @5 ?
p.std <- get.risk.coxph(mstd, t0=2000)
6 I+ V* n; Z O, p) s- x- n2 z3 v: lp.new <- get.risk.coxph(mnew, t0=2000)! T3 l3 j+ r" n; G
1% i8 _1 J) Z5 `: b/ K) C
计算NRI:
5 J) E; w8 U1 Y: W4 S5 |
$ G; m7 q4 g6 X) j2 qnricens(mdl.std= mstd, mdl.new = mnew,
1 r& T$ [- W* B6 L- t t0 = 2000,
A. z$ ?/ a4 [! r" w cut = c(0.3, 0.7),
, q3 n7 Q, a, b% a1 | niter = 1000, + p/ }$ E4 U, ^( C, U i
updown = 'category'): F: l+ F" p ^
" [- d" q* T4 D- t" o3 t" X& ~
UP and DOWN calculation:
) A( B0 ^3 |( K+ `5 u4 K) X" S# e- o #of total, case, and control subjects at t0: 312 88 144
+ h6 j) r# {' b# b( Z7 V5 {; p% u2 Q8 G- B/ S1 w7 ?
Reclassification Table for all subjects:
7 L5 I0 c( {. I4 W: J+ ? New
0 j" a$ o+ \9 N y: NStandard < 0.3 < 0.7 >= 0.7. I1 K' j, W, k
< 0.3 202 7 0: h3 ~3 t9 Q/ w& ~' ]6 A9 E4 h% w
< 0.7 13 53 68 R3 W/ Y$ S9 U O( K. j9 Y3 @3 E
>= 0.7 0 0 31
/ }: U/ ]) b. @9 p; n$ M$ c( J. _8 ]. O
Reclassification Table for case:4 y _6 a1 J( ]3 _
New; i* F9 T R. }; R- J( C, Q+ F$ z
Standard < 0.3 < 0.7 >= 0.7
$ ?( h) A4 [6 U9 D7 f9 \ < 0.3 19 3 0
* }3 A* J2 ]4 g' F- Q4 @/ ? < 0.7 3 32 4( }' `1 D1 l* u( X# }5 r& F+ G
>= 0.7 0 0 277 A1 A% z1 |# x! o* C
# e2 S" S1 V2 \4 I& Z9 y! y2 Y+ J" r Reclassification Table for control:
% ~/ K4 ~3 K. {1 ]6 M/ W5 o New
5 [+ n$ z: e3 h$ YStandard < 0.3 < 0.7 >= 0.7
( H7 X- X% w! ^3 C; R < 0.3 126 3 09 p0 F! ` B V0 [! @# }
< 0.7 5 7 2
" @4 a/ u; Y$ w; i* u8 b >= 0.7 0 0 1
* p3 ]" R: C( D/ H" ?2 p0 B s8 w' }+ r( \6 K$ _3 `
NRI estimation by KM estimator:6 y6 F& D' z* Y' s4 r0 c) M
6 `" m/ `* B0 x# z! V( h) K; LPoint estimates:0 Y- H6 Y7 J7 z$ p9 F
Estimate) b& g, z6 F1 A: I& P
NRI 0.05377635+ c9 n6 o2 |2 d+ D. ?% c
NRI+ 0.03748660
+ ?! ^. [9 L; n& ?% i' w( ~NRI- 0.016289745 o8 c7 K3 T: h3 o
Pr(Up|Case) 0.07708938
3 A, n4 A7 S# I, [. f7 L" bPr(Down|Case) 0.039602781 K$ [$ h, F% }9 F0 g* {
Pr(Down|Ctrl) 0.04256352
, ]) v7 F6 L b3 F2 e; LPr(Up|Ctrl) 0.02627378
/ c' K1 h: h { E: b5 t: z" q
( q2 N6 \( F, c* U/ k2 j# UNow in bootstrap..
$ `. Z2 I$ ?6 X& p* ]8 @
; S3 n9 a3 ^# J$ ], K4 MPoint & Interval estimates:
# t0 }6 ^7 D& }$ j7 v5 v Estimate Lower Upper! J" I2 [3 z I, ^* U
NRI 0.05377635 -0.082230381 0.16058172
, P0 T5 x/ ^2 U0 {! J- G1 CNRI+ 0.03748660 -0.084245197 0.132317768 R3 _. c: h6 Q/ w% C v6 y$ h
NRI- 0.01628974 -0.030861213 0.06753616
5 {& t- l! @) R6 pPr(Up|Case) 0.07708938 0.000000000 0.19102291
; U H0 ~! k3 T4 {; a! O) PPr(Down|Case) 0.03960278 0.000000000 0.152360166 l" y/ u/ O9 u) n( o1 x
Pr(Down|Ctrl) 0.04256352 0.004671535 0.098631705 Q$ X) \7 s) t. F/ Q" {9 [; t$ S- `
Pr(Up|Ctrl) 0.02627378 0.006400463 0.05998424
+ M0 ]% P6 ]( a v" k, x. F" o9 h7 L9 {# l: V/ y0 P. K
1" e0 K7 v4 ]% j, q" I3 s
& `, Q4 e, a; {8 @3 Q" m, K
Snipaste_2022-05-20_21-49-386 d! V" D( a, o9 t* O
结果的解读和logistic的一模一样。
$ V( E1 @4 z% C- V( B4 X' l L m# u- L2 \( K9 f. W P
survNRI包
1 e( k; {5 x2 M4 d- C( ~, t1 f# 安装R包& |+ \ `- T! E% }
devtools::install_github("mdbrown/survNRI")9 s0 {2 `$ k+ i9 i+ u# p0 ~* z
1
- ~$ L5 D" r. t3 u5 f B& b加载R包并使用,还是用上面的pbc数据集。5 e- g) O9 N, E
: C3 D: P( U5 j. E. e
library(survNRI)( a; P! Y2 H2 {
15 I0 e6 v3 R" F% K9 Z
## Loading required package: MASS
0 l6 R0 u4 _* G1# V; x& r7 u) }; v. B
library(survival)$ @$ C4 G) A& Y$ y
+ \( r; d2 o* D8 s
# 使用部分数据- Q0 {: K0 h" A" l7 n
dat <- pbc[1:312,]
" I% L. q1 a8 g. t7 Qdat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡
* g, B0 b4 k7 }: q0 g$ j4 j l7 b% }1 a; Q
res <- survNRI(time = "time", event = "status", - ~2 S) t% l! ?" i- \" m
model1 = c("age", "bili", "albumin"), # 模型1的自变量5 M7 u: L& b5 r# K7 l
model2 = c("age", "bili", "albumin", "protime"), # 模型2的自变量5 ~3 l$ c- a0 l3 J k$ k# }
data = dat,
8 p# u0 f3 w, ?& W0 s- V' I+ @5 ` predict.time = 2000, # 预测的时间点
$ ]7 N! s% ]7 ~* a1 p$ y; w# Z. s1 p method = "all",
8 u5 V/ |: ~% G' T% @# B bootMethod = "normal", * Y, w/ q7 L& n0 n) ]- z2 k4 S
bootstraps = 500, : X. _+ G7 `9 s" z
alpha = .05)
1 ?2 ~* K2 l: W; }
5 w! Y& Y E& @: {8 _! F+ g1- D$ a9 g) X: K2 O, U! ~3 |: R
查看结果,$estimates给出了不同组的NRI以及总的NRI,包括了使用不同方法(KM/IPW/SmoothIPW/SEM/Combined)得到的结果;$CI给出了可信区间。; c& I. {6 ~9 R
! |1 Z3 M, g; T f( w- `res
% S. a& n' V' t% n. R2 @- F1
: X9 i) W% p/ c. U5 w## $estimates/ v' k. C5 _0 w. M- M
## NRI.event NRI.nonevent NRI
/ J/ K4 R+ a7 X9 O. g( G## KM 0.20445422 0.3187408 0.5231951% Y) x/ R2 w' i! t7 a# b+ U
## IPW 0.22424434 0.3273544 0.5515987$ b3 G& M0 _; n9 X6 f
## SmoothIPW 0.19645006 0.3144263 0.5108763
' R: x- Y ]" y& ?: a## SEM 0.07478611 0.2632127 0.3379988/ E+ a" C1 T) n9 L, i
## Combined 0.19633867 0.3143794 0.5107181# u; X2 C2 V( u: Z
##
) j! \: n C3 Z% b## $CI
/ N* H+ X: i' b8 x% J## $CI$NRI.event
' L5 ?2 d/ Y' w2 a& w5 M+ [& l## KM IPW SmoothIPW SEM Combined
4 G( [5 s' o# q1 r% r## lowerbound -0.03915924 -0.02185068 -0.04724202 -0.1162587 -0.0473723
. X8 @9 N t3 q2 U& C## upperbound 0.44806768 0.47033936 0.44014214 0.2658309 0.4400496
' j/ N D. h. \$ S## $ q4 L- w' b- m
## $CI$NRI.nonevent
, e8 s' E4 w7 h( X( v U& D0 X" f## KM IPW SmoothIPW SEM Combined' G7 f0 Z1 p6 C2 ~" O# U
## lowerbound 0.1317108 0.1396315 0.1286685 0.08638933 0.1286426
! r+ N7 M+ n+ k! \% L, e## upperbound 0.7102251 0.7393216 0.6966341 0.51482212 0.6964549
' v% ~2 K& @% b6 I1 ?8 [## 1 W8 S3 U) B; r# X; b+ p* [
## $CI$NRI+ Q2 r4 n2 \1 g9 U& f$ q0 b# d& I
## KM IPW SmoothIPW SEM Combined
4 L# I& A* B1 |% R. H0 u* g6 u( r# N## lowerbound -0.05112533 -0.04569046 -0.05439863 -0.04132364 -0.05443409! F, p& H6 I% M# s
## upperbound 0.89306122 0.92464359 0.87970125 0.64253510 0.879531534 i8 i6 W! M9 Q& ~
##
" E$ Y; {; `/ I% O# S3 g4 d## # O" n9 w: w+ C2 @2 z7 G
## $bootMethod
2 ^; x8 v6 B; t8 o2 |# v; l# G## [1] "normal"
9 e0 q% A' S J" f# e& Q##
/ L! o2 J) J5 J% i7 [ A) G/ X## $predict.time& K+ M4 u1 A$ Z1 s* V
## [1] 2000# U- L( b* B% \& }% k1 I
##
, M1 \/ ~* a p. W: _. \, o9 u- G, R## $alpha
) a( y6 S& m" K! u% _; ?$ S5 p## [1] 0.05( }3 D4 l, c' R) o# j4 v. A
## % f$ ]4 S& a' ]* J: L' W
## attr(,"class")( W/ j1 U6 d/ i& a' k8 M) L
## [1] "survNRI"
8 Y3 x( _# t$ w2 \" O1 D' H1 S$ w3 p& \" B. L7 m$ X. Y
19 G+ S. v& L, h( B) @0 x9 e, g7 }
OK,这就是NRI的计算,除此之外,随机森林、决策树、lasso回归、SVM等,这些模型,都是可以计算的NRI的,后面会继续介绍。大家如果有问题欢迎在评论区留言。+ R0 z4 C: B2 X8 G$ |! B) j' f
' ^. K) I. e& [" K* r9 R; J! b
本文首发于公众号:医学和生信笔记
6 `8 r1 v4 {& y; s
4 T5 l6 N) Y# p: X; e0 J" b“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。
/ i! `9 w, E/ v; C1 R本文由 mdnice 多平台发布
! z0 ^& y# K7 _ Y————————————————
0 L5 g* K9 {/ ]) V* S# Q版权声明:本文为CSDN博主「阿越就是我」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
. \# T0 U0 ?) a原文链接:https://blog.csdn.net/Ayue0616/article/details/1267680064 q* U! z C3 v, l# A
# ?$ B. I6 w7 U( M+ H& h2 e; U- x
0 Y. R0 v7 a* o: i! O
|
zan
|