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