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