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