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