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