- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 563314 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 174217
- 相册
- 1
- 日志
- 0
- 记录
- 0
- 帖子
- 5313
- 主题
- 5273
- 精华
- 3
- 分享
- 0
- 好友
- 163
TA的每日心情 | 开心 2021-8-11 17:59 |
|---|
签到天数: 17 天 [LV.4]偶尔看看III 网络挑战赛参赛者 网络挑战赛参赛者 - 自我介绍
- 本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。
 群组: 2018美赛大象算法课程 群组: 2018美赛护航培训课程 群组: 2019年 数学中国站长建 群组: 2019年数据分析师课程 群组: 2018年大象老师国赛优 |
" W- W# b& G% X7 t1 w! f% W
净重新分类指数NRI的计算
$ T" F& q3 O+ ^3 U% b. O/ v“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。
- x/ }% o4 R; e( d+ K8 cNRI,net reclassification index,净重新分类指数,是用来比较模型准确度的,这个概念有点难理解,但是非常重要,在临床研究中非常常见,是评价模型的一大利器!
9 m; F$ Q& d! _
) p& t% r% P& m n; r1 @' E/ E1 X在R语言中有很多包可以计算NRI,但是能同时计算logistic回归和cox回归的只有nricens包,PredictABEL可以计算logistic模型的净重分类指数,survNRI可以计算cox模型的净重分类指数。
' E) M' A1 w2 u/ L/ d) N$ l" g
+ s2 W3 c: u* x* C m$ slogistic的NRI
! n. j# K& ^( C( Anricens包" v6 w& H: W# O3 q9 A% b4 B* t
PredictABEL包9 b3 Z: A; G4 o8 ?& K7 T6 n% X, C
生存分析的NRI
- S9 A/ M1 ?9 }1 L( ]nricens包, F7 ], ?, |5 ?- ]+ ^& e+ c' x& ]
survNRI包/ w6 S! G( K B$ c: |9 M
logistic的NRI/ I" R$ w1 w" `5 i* @! S) p: }
nricens包& v9 A& O+ Z3 o4 U
#install.packages("nricens") # 安装R包
: Q1 [, P" Y0 l! }$ z' R7 I# mlibrary(nricens)0 |& S7 d E/ W+ f# Q% P: q
16 o( M8 k- R C% M: R; ]2 r
## Loading required package: survival
u; [. U7 _- n/ r1
h. @, I8 s1 y使用survival包中的pbc数据集用于演示,这是一份关于原发性硬化性胆管炎的数据,其实是一份用于生存分析的数据,是有时间变量的,但是这里我们用于演示logistic回归,只要不使用time这一列就可以了。
`8 O/ J& U( c/ {" [
5 {/ ]$ ^3 x9 q+ J! _library(survival)$ P( n% [# O0 O6 ~' s& x% W& z* P
8 ]3 E/ @- d1 N/ ]' H6 @
# 只使用部分数据& W2 o& G) k; z4 `. i. L
dat = pbc[1:312,] + ^$ k( P& P0 Z2 Z% N1 e
dat = dat[ dat$time > 2000 | (dat$time < 2000 & dat$status == 2), ]+ k1 I9 o1 x) i7 i% Q
! D0 x. H" @( _# S$ q3 Qstr(dat) # 数据长这样- n7 i" C: w6 l; p8 T
1" R1 ~; `: @6 F9 ?; {
## 'data.frame': 232 obs. of 20 variables:& c- T4 m* b- K( ^
## $ id : int 1 2 3 4 6 8 9 10 11 12 .../ T$ S3 r+ ^2 w
## $ time : int 400 4500 1012 1925 2503 2466 2400 51 3762 304 ...6 _ A7 f/ s; r7 b: R1 u4 K
## $ status : int 2 0 2 2 2 2 2 2 2 2 ...
+ H" E* j' C6 t1 P9 m## $ trt : int 1 1 1 1 2 2 1 2 2 2 ...
4 |. m& ~, I2 v4 U# H$ i9 G## $ age : num 58.8 56.4 70.1 54.7 66.3 ...+ F1 U8 r3 o/ C9 V' e+ R
## $ sex : Factor w/ 2 levels "m","f": 2 2 1 2 2 2 2 2 2 2 ...6 q: l, ^2 |4 V& G& q/ d
## $ ascites : int 1 0 0 0 0 0 0 1 0 0 ...$ N6 \) a6 v6 c; U
## $ hepato : int 1 1 0 1 1 0 0 0 1 0 ...2 x5 J0 x ]# g, r
## $ spiders : int 1 1 0 1 0 0 1 1 1 1 ...# I2 v' P7 W0 ?
## $ edema : num 1 0 0.5 0.5 0 0 0 1 0 0 ..., m" ]8 n- Q+ w* d, l
## $ bili : num 14.5 1.1 1.4 1.8 0.8 0.3 3.2 12.6 1.4 3.6 ...
8 Q% C0 |7 y" W% Z. L) }## $ chol : int 261 302 176 244 248 280 562 200 259 236 ...2 V% i, Q# j0 H3 B8 X% d
## $ albumin : num 2.6 4.14 3.48 2.54 3.98 4 3.08 2.74 4.16 3.52 ...
8 r* Z, K7 ?% I' a## $ copper : int 156 54 210 64 50 52 79 140 46 94 ...
9 Y1 l5 N7 H7 E) C. S1 t## $ alk.phos: num 1718 7395 516 6122 944 ...1 X }: ]8 R) F4 o
## $ ast : num 137.9 113.5 96.1 60.6 93 ...7 A" s2 p2 q0 Q( |) n
## $ trig : int 172 88 55 92 63 189 88 143 79 95 ...
/ U: q X- Z8 a0 G6 F, P' z- i## $ platelet: int 190 221 151 183 NA 373 251 302 258 71 ...5 ^/ s- e+ B5 D9 x; \ w
## $ protime : num 12.2 10.6 12 10.3 11 11 11 11.5 12 13.6 ...- R( }9 q( `0 W2 ?$ Y7 e
## $ stage : int 4 3 4 4 3 3 2 4 4 4 ..." k- |: \6 l; {' ^& l$ y
$ C, W! ]. V* _$ o1 {% _6 V17 F! Q. m7 h' E# ~; l3 i* R
dim(dat) # 232 20
7 h; f7 ?. R4 ^9 G3 A2 X7 \1) Q, d2 m( _; X' D8 R
## [1] 232 20# k: b$ v5 X2 y# i5 ^+ ~
1. ~2 h' H5 Z! q
然后就是准备计算NRI所需要的各个参数。' T7 G3 B. s% H3 B8 x
7 k# Q& g/ ?0 y& U z
# 定义结局事件,0是存活,1是死亡
% T+ j# b& p* H P. D6 \4 v. s; tevent = ifelse(dat$time < 2000 & dat$status == 2, 1, 0)
' Y. `2 K0 X+ j4 j
0 C1 {$ r8 P7 T# 两个只由预测变量组成的矩阵
# y+ `/ A: q" @ O! z1 k5 oz.std = as.matrix(subset(dat, select = c(age, bili, albumin)))
) W2 _! N! ~' U* Bz.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime))). N0 C' l5 X& J' ?
+ z& }) x! C% Z5 s/ s1 C# 建立2个模型
$ ], g m& J" mmstd = glm(event ~ age + bili + albumin, family = binomial(), data = dat, x=TRUE)
; _+ E( b% R F, Z' v# A; ~) }' cmnew = glm(event ~ age + bili + albumin + protime, family = binomial(), data = dat, x=TRUE). Z) {. U5 r3 w$ f( i/ i. t! L7 n
2 w5 v! j+ }8 d
# 取出模型预测概率/ P- a: n( @8 \# A
p.std = mstd$fitted.values/ Y: T" ^! C( s! ]) v+ q9 ^1 }* i' r
p.new = mnew$fitted.values
4 E& {1 t/ L: t# X
+ @; b# K4 i, N, F' J( K7 F3 _1
4 O' a$ }8 ]5 R! O$ |* r& s# Z7 }1 p然后就是计算NRI,对于二分类变量,使用nribin()函数,这个函数提供了3种参数使用组合,任选一种都可以计算出来(结果一样),以下3组参数任选1组即可。 mdl.std, mdl.new 或者 event, z.std, z.new 或者 event, p.std, p.new。9 R; S* W+ o! y2 \
4 H+ T5 m/ J+ E! f7 h1 i% B8 U7 V; Q/ h
# 这3种方法算出来都是一样的结果5 d4 a2 k U2 h' D: T [( s
( w7 P: k) @2 X }; o R0 K
# 两个模型* }4 d# J, r) Q1 o/ x* D
nribin(mdl.std = mstd, mdl.new = mnew,
; s0 S! s$ K0 a, O cut = c(0.3,0.7),
3 K* m% u( M2 E1 A! f; { niter = 500,
5 o6 J8 H3 @6 H6 C$ X updown = 'category')9 w6 J9 c/ B* j7 P! Z5 n
6 |4 n/ ^/ i, o( G- W6 F% ~# 结果变量 + 两个只有预测变量的矩阵
# @- R4 C8 `0 O# `nribin(event = event, z.std = z.std, z.new = z.new,
# I k& J. A- b; g( x. Q cut = c(0.3,0.7), & y) l. S8 H7 p9 K1 t
niter = 500, 1 r, e/ X' J2 e0 V
updown = 'category')
0 i# v6 T6 k% X- m# K# Q
" ?2 q: L2 r" ]- V/ ^8 u8 j## 结果变量 + 两个模型得到的预测概率
! E. a9 z7 A+ V9 w- gnribin(event = event, p.std = p.std, p.new = p.new, f& X' p! v( C! v
cut = c(0.3,0.7),
2 }# z/ P7 O4 m( w3 E, w* F niter = 500, # ~+ l, n; k7 ~# u% n
updown = 'category')
+ N3 o1 s' J: a. B6 F7 L6 X, M- O
4 ~1 M# n0 ~ G- B& e1+ I+ `! x+ D$ B, K- F0 A q% g4 S
其中,cut是判断风险高低的阈值,我们使用了0.3,0.7,代表0-0.3是低风险,0.3-0.7是中风险,0.7-1是高风险,这个阈值是自己设置的,大家根据经验或者文献设置即可。+ {# e) ]" V+ V# |! E1 z
. u. ?4 g5 B9 X9 O: J/ ~/ m% u, Jniter是使用bootstrap法进行重抽样的次数,默认是1000,大家可以自己设置。* k: e; V( u% V( x/ K# o
. {/ R4 D3 ?& s4 xupdown参数,当设置为category时,表示低、中、高风险这种方式;当设置为diff时,此时cut的取值只能设置1个,比如设置0.2,即表示当新模型预测的风险和旧模型相差20%时,认为是重新分类。
) p6 v# V. q. t8 q) A1 K% G8 i' U
$ M, N/ o, f/ {7 d! u上面的代码运行后结果是这样的:
! B2 y( m( C. |5 X( O
* F7 k6 ? _4 U7 j1 GUP and DOWN calculation:
, B" h7 A+ K( J; i #of total, case, and control subjects at t0: 232 88 1442 q& M7 m4 s2 F( z
5 c8 ?& q! n+ x Reclassification Table for all subjects:
& V. l# O0 h+ ]: V& Z New
: A5 z! @9 U! J* V4 }Standard < 0.3 < 0.7 >= 0.72 {4 t9 ]7 Q2 J+ D, R" @
< 0.3 135 4 0
H7 h' _! E4 C& d) b, t' E8 U3 J < 0.7 1 31 4
- P4 h( e( k' q0 X >= 0.7 0 2 558 g' l) C. u z+ c. ^
; T& h3 K, t/ @ Reclassification Table for case:9 v) X z y# h1 C% f4 u, X
New
0 |5 h# n- E; O- AStandard < 0.3 < 0.7 >= 0.7
* d, O0 E( R$ q0 t C% Y < 0.3 14 0 07 p2 @4 M% c% h( ?- q% Z
< 0.7 0 18 3
1 J% j: N B9 b8 W, _ >= 0.7 0 1 52
: c3 y; q0 d/ }# g+ E& X& ^8 H* o8 f4 Q* S" V5 D
Reclassification Table for control:' N! ~0 N5 m7 c; z4 }7 }. t/ o% M
New
" E; ]- { P# Q3 fStandard < 0.3 < 0.7 >= 0.7
8 g& Z/ q; O$ j5 L) s < 0.3 121 4 01 x( r1 E, q* a. R
< 0.7 1 13 10 e. _" N! n( t, F5 {- L9 k9 ^; H
>= 0.7 0 1 35 B* T u( d, M2 @
7 C c0 d4 Y9 r# n% t6 ^& \: ^3 [1 _NRI estimation:
5 x, \9 q3 B" X6 v6 |0 a! {Point estimates:
, U! [$ z& Q; b- L8 s Estimate
5 f/ L3 c1 u% s6 @! v0 x4 Y) ?NRI 0.001893939$ h% |: {* {$ a
NRI+ 0.022727273
' e7 U7 w" q; t1 M/ \NRI- -0.020833333! F$ o' s, s* h$ B6 ~/ H$ \
Pr(Up|Case) 0.0340909098 `( T% F$ \/ J% _* S% V3 a
Pr(Down|Case) 0.011363636
2 j) T' R/ C1 z- Z! b9 iPr(Down|Ctrl) 0.013888889
! H! ]$ Q, U! k7 H! ]8 o5 \7 vPr(Up|Ctrl) 0.0347222221 r5 _, A1 q6 [9 J
) K- p0 T- ~' M/ l- H SNow in bootstrap..
% j- b; O ^3 E/ X" [. M, i1 m& A {; l* @ P. v, b3 x
Point & Interval estimates:- r, H G' n% W& I9 W4 b( ^
Estimate Std.Error Lower Upper
0 F' c$ o6 K* tNRI 0.001893939 0.027816095 -0.053995513 0.055354449
) U6 f6 W m1 C2 hNRI+ 0.022727273 0.021564394 -0.019801980 0.065789474
0 Y* N1 W4 R) x/ cNRI- -0.020833333 0.017312438 -0.058823529 0.007518797
* C; T3 }) h1 F' p; Y, cPr(Up|Case) 0.034090909 0.019007629 0.000000000 0.072164948, x. W+ U& F: |( Q2 N
Pr(Down|Case) 0.011363636 0.010924271 0.000000000 0.039603960, U* s" B% L1 y4 K( C+ J5 K& i3 g
Pr(Down|Ctrl) 0.013888889 0.009334685 0.000000000 0.035211268
; V$ y' ^5 `+ FPr(Up|Ctrl) 0.034722222 0.014716046 0.006993007 0.066176471
" p# {/ A5 x& Q, q" e6 z- N" X$ v
) ^% x! R6 g( L' I" m, v1
8 O2 ?8 J& z) P" m首先是3个混淆矩阵,第一个是全体的,第2个是case(结局为1)组的,第3个是control(结局为2)组的,有了这3个矩阵,我们可以自己计算净重分类指数。8 Q7 s9 Y: ?, z! E, b
0 R! M5 Y4 C, v, Y: t% p看case组:
- H6 Z8 |8 u9 u, w/ g
! o: z0 {5 w( O! P m! k. V9 v净重分类指数 = ((0+3)-(0+1)) / 88 ≈ 0.022727273
% e3 ]7 X% Q( s" j, {
- a( L. ]% ^, i8 C: ^再看control组:
, P6 u* b' i$ E$ n9 z' E2 O3 @
净重分类指数 = ((1+1)-(4+1)) / 144 ≈ -0.020833333' i. V- D. |2 K6 \% a
) D+ ~2 w0 R' c( o _$ Z2 B相加净重分类指数 = case组净重分类指数 + control组净重分类指数 = 2/88 - 3/144 ≈ 0.000315657# A- @0 N5 H6 X5 c6 S4 J
) y8 g5 X4 C/ D' w8 l% R# g% d再往下是不做bootstrap时得到的估计值,其中NRI就是绝对净重分类指数,NRI+是case组的净重分类指数,NRI-是control组的净重分类指数(和我们计算的一样哦),最后是做了500次bootstrap后得到的估计值,并且有标准误和可信区间。! ~# c5 Q( q+ U
2 m+ U- a: p# R$ o, P/ Q( r最后还会得到一张图:4 @4 U1 p! ^4 q' s! {
! T s) @) X, ]! O1 G& @# [
这张图中的虚线对应的坐标,就是我们在cut中设置的阈值,这张图对应的是上面结果中的第一个混淆矩阵,反应的是总体的情况,case是结果为1的组,也就是发生结局的组,control是结果为0的组,也就是未发生结局的组。% J3 O* P: F4 j" F3 j# j
$ x% d$ v a4 b3 V; {4 \/ l
P值没有直接给出,但是可以自己计算。
0 w5 p' v& ^5 c9 i0 |: X, Q. @$ @
$ A8 I0 f: Z q' \# 计算P值
! u$ ^+ ]0 V. M0 m x2 qz <- abs(0.001893939/0.027816095)
1 P* d f# x* n* h. ?# j5 bp <- (1 - pnorm(z))*2
& b. l. f+ @# E7 Gp2 I' E. h6 }, F9 j
1. s8 f7 A/ U. X
## [1] 0.9457157
; Q7 B! X5 M7 `) ?) J1
6 b+ }% l; \+ a4 a/ N3 hPredictABEL包
2 Y) ~; B: n v8 x. a! c#install.packages("PredictABEL") #安装R包
# F" n4 n8 q2 E- rlibrary(PredictABEL) / Q, `0 h4 c5 W0 ]) }, D8 t
% n3 j! v" _7 U. ?5 c( c% J5 M
# 取出模型预测概率,这个包只能用预测概率计算3 \( X2 b3 t. _; s& \8 z/ Q
p.std = mstd$fitted.values$ P2 o! j3 L8 F: x( _
p.new = mnew$fitted.values . Y# a% {5 C- h( i/ ^! u: m
1" O; u3 \2 a, w: w5 T
然后就是计算NRI:4 D2 i0 i2 t; C3 R
$ b" r. ?7 m& ?; ]8 M
dat$event <- event# Q% P9 s ^9 @! x7 E
, q X! W- c4 T2 [6 [
reclassification(data = dat,
) Q' _" |2 B# K cOutcome = 21, # 结果变量在哪一列3 v! N, i3 N: j. E1 c, {: J. _3 H
predrisk1 = p.std,, h* o& E5 V1 g$ ~, \6 f
predrisk2 = p.new,- V1 J. ^3 k5 G- `8 j$ x* P* R' F
cutoff = c(0,0.3,0.7,1)
; |8 [) W' F# k& ?( N6 r )+ m5 h$ G& T o3 j9 z! s
1
9 N. M" B: U* ^4 N$ _: A) a## _________________________________________
t/ B% _2 G# W( W) A$ M##
: b8 j S) u9 D6 _ | ^* R## Reclassification table
: F4 o! L- _0 `) ?( j: P## _________________________________________+ ?& W9 D2 j6 S8 {7 h1 t( z
##
1 \, V4 y8 s3 k' j## Outcome: absent 6 l* T: Z% x3 Y, y$ w+ k. ~
## - e) a. O g6 t1 t: W
## Updated Model
, ?, v. T3 P: E+ v## Initial Model [0,0.3) [0.3,0.7) [0.7,1] % reclassified& s; l9 m: u. N
## [0,0.3) 121 4 0 3
" p1 q0 e1 c( i4 R## [0.3,0.7) 1 13 1 13' r, h" n) F, Z
## [0.7,1] 0 1 3 253 l; t) Z$ D& _! ?9 i! ]
##
2 Q7 ~/ Y" [$ T## ! B2 j' ^) a c& D$ ?6 f
## Outcome: present
4 K) V: u- x' p, h3 y' x9 c## 3 I# b C- }2 q" k) M
## Updated Model, i) u; x& x9 U% J( q
## Initial Model [0,0.3) [0.3,0.7) [0.7,1] % reclassified
6 q1 z" F) h u## [0,0.3) 14 0 0 0
8 M& k( d, B* j3 R. q## [0.3,0.7) 0 18 3 14! B$ u! M, @, {# x
## [0.7,1] 0 1 52 2* r' x4 P; A; B/ p, p. ^
## # C3 e ~: p3 d O) T. S6 y
##
% z5 ^: t4 ~: Y. T/ i* a* ?# d## Combined Data
; Z/ O$ P u6 W, W5 O. Z7 [- ~## 7 O$ o0 W! B" l
## Updated Model
7 P1 F3 j9 v8 W0 T4 { H## Initial Model [0,0.3) [0.3,0.7) [0.7,1] % reclassified) a& W) @3 Q# A$ C" s+ \* f) i
## [0,0.3) 135 4 0 3& c! F% C9 i1 x
## [0.3,0.7) 1 31 4 14$ |4 B2 E: w( e# s
## [0.7,1] 0 2 55 49 Y! {- Z0 W# V; N. ]0 b# y- _
## _________________________________________2 V- L# R# H! _: _3 M0 q
## ( V6 u; `* a$ m) ?( s) |5 l" G
## NRI(Categorical) [95% CI]: 0.0019 [ -0.0551 - 0.0589 ] ; p-value: 0.94806
" N# n2 Q" f# f) G( g0 U" n( I## NRI(Continuous) [95% CI]: 0.0391 [ -0.2238 - 0.3021 ] ; p-value: 0.77048 ' z5 ~) Z/ i. J' O' a1 S5 g' R2 s
## IDI [95% CI]: 0.0044 [ -0.0037 - 0.0126 ] ; p-value: 0.28396
, A1 k7 E6 W/ ^6 k% I5 b, t
* f, h8 Z f: p* @1
3 f9 ~+ `2 n% q" S/ T6 A& Z0 ]% @结果得到的是相加净重分类指数,还给出了IDI和P值。两个包算是各有优劣吧,大家可以自由选择。
' M8 a, X9 u7 _
, G7 @0 e$ p! z; w8 L生存分析的NRI
9 n( b% g0 `" R2 I$ U还是使用survival包中的pbc数据集用于演示,这次要构建cox回归模型,因此我们要使用time这一列了。
8 f5 f* d: L7 `( ]8 J+ R/ B& C0 I' V D* `5 Z/ {' O6 w) E
nricens包* P# i- x; K, z( J
library(nricens)7 I; a+ P$ N! y/ t n
library(survival)
+ I8 s3 O; `: X/ E- n" j8 F9 R- _& h/ X z6 Y' M8 p; |
dat <- pbc[1:312,]$ o$ E* c4 F/ w; n6 [5 [- o
dat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡( O+ Z* r8 m0 ^% d* x
1' t$ s3 p& Z: N K j
然后准备所需参数:
, i9 J/ {; M( t6 _- F
2 ?& d3 i0 P$ v2 X% n' N9 E& h# 两个只由预测变量组成的矩阵
% I* ~4 }6 y0 B( J7 qz.std = as.matrix(subset(dat, select = c(age, bili, albumin)))
+ o5 d6 P( E) H Oz.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))
0 S- A0 f3 S% A4 {5 F3 s5 `6 A) A) ?1 ^2 X% T
# 建立2个cox模型 D7 h% m; l. R. m! b2 P: n
mstd <- coxph(Surv(time,status) ~ age + bili + albumin, data = dat, x=TRUE)
5 Q2 L; J2 }- e+ R+ t0 {( imnew <- coxph(Surv(time,status) ~ age + bili + albumin + protime, data = dat, x=TRUE)
& T9 E* F/ A1 P! |$ B J. [" ?, F9 ^* y. M1 u& ~
# 计算在2000天的模型预测概率,这一步不要也行,看你使用哪些参数4 L4 W2 v! Z3 d
p.std <- get.risk.coxph(mstd, t0=2000), [% D4 a. K3 L- p
p.new <- get.risk.coxph(mnew, t0=2000)
# v. z1 u: I1 u4 Z# J1
/ P0 \4 A% Q2 s计算NRI:
% R y* K. z9 c' M/ Z1 c5 X' _* a0 R* i( ^ G) t0 b
nricens(mdl.std= mstd, mdl.new = mnew,
. X: r5 w) V( k; a7 k t0 = 2000,
" A+ p& r2 Q. x# l9 g cut = c(0.3, 0.7),% ~! ?) {9 [) l5 N# B G! G* W
niter = 1000,
8 [/ L4 c4 }* D3 j4 F updown = 'category')3 g8 }$ `+ z0 m
5 F. O- M% G; h+ _% E+ NUP and DOWN calculation:6 d- Q4 a/ D5 X, a
#of total, case, and control subjects at t0: 312 88 1441 `, i+ J: Z3 I, k
) |& j6 z# i" f, H# [ Reclassification Table for all subjects:
& @& X0 j5 s) m. w8 D- i! n$ b' F New
, y& B3 j7 @% t' j" RStandard < 0.3 < 0.7 >= 0.7, U7 f% |# @- b4 q, b% U, N0 D
< 0.3 202 7 0
, w' V& K: y& c* j < 0.7 13 53 6! c5 b, }2 _) I
>= 0.7 0 0 313 b) a0 d% J6 D0 ~. m$ U0 D! f
8 h1 t1 n S# r# m( f0 ?/ X
Reclassification Table for case:
) I1 Q) w8 F, m/ I( |) u New
3 r. b$ p/ S# F) Z, k* L/ ?! I0 v7 aStandard < 0.3 < 0.7 >= 0.7* j* \4 { i' k$ k9 J
< 0.3 19 3 06 \, y% T2 W/ L% ` U
< 0.7 3 32 4
* |0 R; _% G# H/ Z: p R >= 0.7 0 0 27( D3 Z, V9 f! [. d- L: Y
9 i6 a! j3 g4 U: @ Reclassification Table for control:
- Q, \# I5 _+ ~1 T; \/ e, r New
: G8 y4 c3 m1 \% C8 z3 p& i% hStandard < 0.3 < 0.7 >= 0.7+ f+ h: P5 \4 U
< 0.3 126 3 0: Z& C, S, n! b) ~, C) x$ _: o
< 0.7 5 7 2
/ c. Y. Y8 u* W ]" y' V, ^9 D >= 0.7 0 0 19 {+ m) ?- p1 W( e
& a1 \6 \+ |; p! ~, E
NRI estimation by KM estimator:
: n) i" ]+ [& C4 A% ~! f b
3 a5 C7 i; T0 _) X* t* Q' t6 a: GPoint estimates:# ?- |1 H5 h6 e4 U V' u
Estimate+ ~, H/ L2 b& y/ p3 F" X! T
NRI 0.05377635
2 ?0 M2 o- y) I1 ^# FNRI+ 0.03748660/ F6 m% O x3 f. L* O/ d
NRI- 0.01628974
0 i# v7 b* l3 z" A# S! RPr(Up|Case) 0.07708938% w' s/ h( D* [
Pr(Down|Case) 0.03960278) J% t- M' P2 y" Y
Pr(Down|Ctrl) 0.04256352; q0 L2 N/ q1 C1 r0 e& U$ _- E {
Pr(Up|Ctrl) 0.02627378) B9 }+ E0 C) A- @+ a5 I2 _$ T
# \) A7 w7 P+ h( u; v n0 F3 Y8 Y
Now in bootstrap..
" ~: r$ Q; K; N/ M {! `0 f; q5 b4 _# f
Point & Interval estimates:
1 n* U8 h* \- s% o- x8 t Estimate Lower Upper5 \$ l& d' J* z
NRI 0.05377635 -0.082230381 0.16058172; Z) H7 W2 d( O1 ?' v) T! B4 H: j
NRI+ 0.03748660 -0.084245197 0.13231776) [3 [3 T' F/ k% k. n: T2 M" j
NRI- 0.01628974 -0.030861213 0.06753616- d0 v. j. ]2 s$ |
Pr(Up|Case) 0.07708938 0.000000000 0.19102291
+ `* G. c t6 \& v8 F/ QPr(Down|Case) 0.03960278 0.000000000 0.15236016" G y1 f) D( {8 V
Pr(Down|Ctrl) 0.04256352 0.004671535 0.09863170
4 ]9 I2 X+ A) C3 OPr(Up|Ctrl) 0.02627378 0.006400463 0.05998424
& C& J/ U& g2 t5 J3 N H0 f% k+ m1 d' Z9 e8 M" y$ v
1- T; O* }* o/ a% C% j% `) E# H
( y0 x% N4 F2 E; @Snipaste_2022-05-20_21-49-38' j3 @1 U( |8 I1 H! q" q* t
结果的解读和logistic的一模一样。! a9 j4 O+ Q/ `: g3 w
2 X) v7 n& w2 Y5 GsurvNRI包. }- u( M) Y3 ]/ W, i- `) Q O) e! o4 H3 B
# 安装R包
) m5 ]- v7 ?# u# Udevtools::install_github("mdbrown/survNRI")
" X7 L- |' x* M( m% Z17 m U$ n/ f `; Z: [& k# F
加载R包并使用,还是用上面的pbc数据集。
6 _8 a5 p9 B- H9 n; |9 f: Z7 _9 D2 X/ ]. F( ~3 b
library(survNRI)& y* l& t8 {" J1 g0 W1 b: r
1
8 k# q4 b: c6 W! Y& Q. t o## Loading required package: MASS
3 r0 W4 M& i4 N! c. \1* _4 A/ t# k2 F) H, o& Q
library(survival)4 _7 ]& d: ?6 l- z( X' v0 e. n
. R2 F: d( b: z @' h9 p: f
# 使用部分数据( o! k V' h3 H4 Q* `4 Z7 D6 A
dat <- pbc[1:312,]
! T; h. ^" T# V: g$ odat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡
# q) Z7 [1 Y+ [7 ^8 k* F5 s" g1 Y2 ]. N; E: ?
res <- survNRI(time = "time", event = "status",
6 D3 M; n* |0 p0 ^0 u( B+ } model1 = c("age", "bili", "albumin"), # 模型1的自变量( y1 S/ J# v. v
model2 = c("age", "bili", "albumin", "protime"), # 模型2的自变量 }3 e% F3 Y$ }. i
data = dat,
( m1 |( y( [. n predict.time = 2000, # 预测的时间点
0 G9 F' e" W9 o+ D8 I R1 r. p method = "all", ( A% X0 N. [ U6 E1 W8 N
bootMethod = "normal",
" Z. ^# h! |( d+ Y- j9 O2 F8 i bootstraps = 500, / ^7 t9 y3 i' s2 \
alpha = .05)
1 ?% e1 A8 R! T3 }1 m. L0 }: n
/ C& r6 F" n' ~- l/ l9 C! e1
- `$ {8 n6 K- ~2 H" K3 o3 y* e查看结果,$estimates给出了不同组的NRI以及总的NRI,包括了使用不同方法(KM/IPW/SmoothIPW/SEM/Combined)得到的结果;$CI给出了可信区间。
! \, s1 o& M6 ^. |7 \
9 I! W- [' M4 e* Q$ yres0 m( d) v* p) D; H" i& M
1
( G7 V+ I9 M2 W6 R7 L## $estimates" G7 K" }1 O- J; G, `( j* |
## NRI.event NRI.nonevent NRI
* b3 t9 J: V/ s R8 E, a5 ~/ `## KM 0.20445422 0.3187408 0.5231951
- n! c. d: w" ~ `+ ]## IPW 0.22424434 0.3273544 0.5515987
# e. J; q, D# Q## SmoothIPW 0.19645006 0.3144263 0.5108763
5 `$ [, g* b6 Z( J) c## SEM 0.07478611 0.2632127 0.3379988. a2 f& ?9 A7 I1 b# r2 j, w
## Combined 0.19633867 0.3143794 0.5107181# z2 }) M: g" i+ Y! L4 e8 a
##
/ m5 x7 f& b1 d3 }## $CI) Y7 D. i: u0 H* S1 a1 @/ D% l
## $CI$NRI.event8 x' j' h+ L, \4 w4 }% D8 Q
## KM IPW SmoothIPW SEM Combined" k, b% j1 z+ D" f9 |7 `
## lowerbound -0.03915924 -0.02185068 -0.04724202 -0.1162587 -0.0473723. z; ?5 ]3 Z4 F# Z* ] } p
## upperbound 0.44806768 0.47033936 0.44014214 0.2658309 0.4400496
8 o8 K$ ~5 ?% p0 h" y##
3 A$ x* \0 [# Z$ Q, Z+ A## $CI$NRI.nonevent
& Y4 E+ Q6 C7 r0 ?% s6 y8 e0 g+ u4 \## KM IPW SmoothIPW SEM Combined6 T9 `& |: ~8 ^
## lowerbound 0.1317108 0.1396315 0.1286685 0.08638933 0.12864268 j% u0 i; y4 }7 _1 v5 d* M4 S7 t
## upperbound 0.7102251 0.7393216 0.6966341 0.51482212 0.6964549- w. B: i i3 A9 w$ [
## ; S6 j, J- `% R, J @) c( _ c
## $CI$NRI
4 w. o. l2 ]5 \1 [1 Q; m. @## KM IPW SmoothIPW SEM Combined
0 R! X8 U& z8 N# e( |4 r# `" D## lowerbound -0.05112533 -0.04569046 -0.05439863 -0.04132364 -0.05443409
$ | N2 c/ k7 j4 O4 q- B## upperbound 0.89306122 0.92464359 0.87970125 0.64253510 0.87953153
2 J3 G$ f: t \##
) ? b1 m) a9 \( e H! u##
& p& T1 j! L/ k2 P- S, O## $bootMethod/ G, s4 [: D9 J2 K) W
## [1] "normal"
! t2 X, m0 _+ m) f% [- a( A$ y## / P, }" S! h0 M" |. O1 U/ i) P
## $predict.time
, X$ k2 I" {3 A, F7 e$ C3 E$ q7 |## [1] 20003 @) h+ L% h+ V$ i
## 0 T+ R# e* s" Q! Y8 P6 v
## $alpha& A% T; A' R9 g3 |( r
## [1] 0.05( m* N. u, \$ T* S, ?; g
## # U. M4 w9 J# f
## attr(,"class")5 G0 R, R/ s( r2 X- w
## [1] "survNRI"* C( M- M% W* y# i5 h
, Q1 f' K" Z7 q* ?& {. v0 U, K$ I1 Z% _: N0 `. {' R
OK,这就是NRI的计算,除此之外,随机森林、决策树、lasso回归、SVM等,这些模型,都是可以计算的NRI的,后面会继续介绍。大家如果有问题欢迎在评论区留言。
N' Y/ d# H, T+ N" b
0 \; [! X0 d$ d2 H- s7 h本文首发于公众号:医学和生信笔记
. T: }! P6 w! ~' J) q
: b6 C# \3 j! t5 H! p4 |“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。8 V" Z- K7 @1 I3 h
本文由 mdnice 多平台发布9 n; F: C: i$ g6 t L4 O" y6 T
————————————————
) [1 _. R& `& m6 s; D+ h版权声明:本文为CSDN博主「阿越就是我」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。. x. a( L; Z- p, I$ n3 f, M
原文链接:https://blog.csdn.net/Ayue0616/article/details/126768006& k7 z& M1 ?$ v6 f( R3 q
" u& m5 S B9 v$ \
N0 r6 g# O" E7 M/ ^( E0 M |
zan
|