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