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