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