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