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