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