- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 81
- 收听数
- 1
- 能力
- 120 分
- 体力
- 541988 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 167975
- 相册
- 1
- 日志
- 0
- 记录
- 0
- 帖子
- 5324
- 主题
- 5250
- 精华
- 18
- 分享
- 0
- 好友
- 163
TA的每日心情 | 开心 2021-8-11 17:59 |
---|
签到天数: 17 天 [LV.4]偶尔看看III 网络挑战赛参赛者 网络挑战赛参赛者 - 自我介绍
- 本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。
群组: 2018美赛大象算法课程 群组: 2018美赛护航培训课程 群组: 2019年 数学中国站长建 群组: 2019年数据分析师课程 群组: 2018年大象老师国赛优 |
% P2 m$ }. }8 j. }
净重新分类指数NRI的计算: C1 a5 P: u" L- o X
“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。
3 M+ ~, L$ ^* ?# |* o8 qNRI,net reclassification index,净重新分类指数,是用来比较模型准确度的,这个概念有点难理解,但是非常重要,在临床研究中非常常见,是评价模型的一大利器!1 l# h9 c$ e; ]( J e! Z9 u6 K+ u
% B F" D4 X+ _$ D# C在R语言中有很多包可以计算NRI,但是能同时计算logistic回归和cox回归的只有nricens包,PredictABEL可以计算logistic模型的净重分类指数,survNRI可以计算cox模型的净重分类指数。
& K+ e9 w6 i5 v1 Q b
& B0 s3 B& k0 H( w" f) _; C$ L0 w% ologistic的NRI4 C- [( S- b" J5 m$ Q0 k* {
nricens包$ U3 J0 g _. |1 L7 S4 u6 |
PredictABEL包
! q- j9 c# w( W4 @; I生存分析的NRI% {9 }& A, }' n2 _; ^& q# O7 j7 S
nricens包3 h4 l+ |% |2 D$ D! D" Y+ z: n
survNRI包
' Y4 }' X# q* ?+ w% ^% `logistic的NRI0 ?8 P" L. M' s1 { a& ~
nricens包
' }$ Z& j+ j! P7 Y#install.packages("nricens") # 安装R包
, f5 G) k, i2 `3 o) jlibrary(nricens)
: \, x- n+ X5 r) s, H- R1* F$ ?* y2 M# O# g* y$ v% l0 r
## Loading required package: survival ]/ P4 _. L9 k" o0 i
1- O6 ~' N' F3 G4 x. r* ]; a
使用survival包中的pbc数据集用于演示,这是一份关于原发性硬化性胆管炎的数据,其实是一份用于生存分析的数据,是有时间变量的,但是这里我们用于演示logistic回归,只要不使用time这一列就可以了。
& g: y9 O& s6 A! H# Z9 ]
* Y) B- T3 G! t: ilibrary(survival)* r2 m6 w9 |& q, h
5 J3 ^6 N- N) e; [: C5 s
# 只使用部分数据, R9 \# G( C+ j. D4 g; i
dat = pbc[1:312,] 7 k- n5 i! @0 a, |9 m
dat = dat[ dat$time > 2000 | (dat$time < 2000 & dat$status == 2), ]! k1 c9 R8 F, V. r' L, B0 Q
% |& X5 B4 b5 Ystr(dat) # 数据长这样+ c( g( I# e1 c! v* i
1- z9 x" v1 K: h
## 'data.frame': 232 obs. of 20 variables:4 X% r4 O, g7 a; n0 Q: o* k0 `
## $ id : int 1 2 3 4 6 8 9 10 11 12 ...
; ^% E5 o! J8 L## $ time : int 400 4500 1012 1925 2503 2466 2400 51 3762 304 ...
* J+ i* N' g% m; L; f## $ status : int 2 0 2 2 2 2 2 2 2 2 ...
" V. q# t3 q5 l( p( z8 @1 {## $ trt : int 1 1 1 1 2 2 1 2 2 2 ...2 y2 U9 I4 Y: Z7 Q5 x- j2 F
## $ age : num 58.8 56.4 70.1 54.7 66.3 ...& b* | p Q0 o; R |% p
## $ sex : Factor w/ 2 levels "m","f": 2 2 1 2 2 2 2 2 2 2 ...6 K& O# i/ N& F9 S0 M
## $ ascites : int 1 0 0 0 0 0 0 1 0 0 ...( s3 o( \& u) [* l) ~, m8 l& Q5 j$ [
## $ hepato : int 1 1 0 1 1 0 0 0 1 0 ...+ E3 n* E% p# K u: Z5 K' K& ]% G6 [% x
## $ spiders : int 1 1 0 1 0 0 1 1 1 1 ...* e5 [- n" T( [/ g, O
## $ edema : num 1 0 0.5 0.5 0 0 0 1 0 0 ...
* \ I5 L4 T" i) Q## $ bili : num 14.5 1.1 1.4 1.8 0.8 0.3 3.2 12.6 1.4 3.6 ...$ r7 ^- H% ~8 R$ Z6 H! K& L a1 L
## $ chol : int 261 302 176 244 248 280 562 200 259 236 ...
~- ?$ j# _3 }% o1 L## $ albumin : num 2.6 4.14 3.48 2.54 3.98 4 3.08 2.74 4.16 3.52 ..." d1 V+ E8 ?# V, H" G# Y
## $ copper : int 156 54 210 64 50 52 79 140 46 94 ...
6 q% h, Z0 p# N, l0 R0 x0 T## $ alk.phos: num 1718 7395 516 6122 944 ...! T0 m" L2 n. m
## $ ast : num 137.9 113.5 96.1 60.6 93 ...
1 V& h4 i- |. m# n+ f! Y% w## $ trig : int 172 88 55 92 63 189 88 143 79 95 ...2 q8 c- O/ ]0 c, r
## $ platelet: int 190 221 151 183 NA 373 251 302 258 71 ...0 O7 w$ \7 T7 d @7 w9 k. s8 J
## $ protime : num 12.2 10.6 12 10.3 11 11 11 11.5 12 13.6 ..." C& D" f8 g7 b
## $ stage : int 4 3 4 4 3 3 2 4 4 4 ...: J7 l+ @! |& y5 c% \
+ g* k1 G# h7 u& l8 L+ i
14 s6 i. @9 t; n* _' T/ v- L
dim(dat) # 232 208 D# ^- ?& f: `$ K9 k1 m0 G
15 A1 n+ E" g: E7 `! Y( `* O& o" S8 x* _
## [1] 232 20! t: R( l1 D0 @" J) x3 ]
1
0 ?0 _) [& g8 i9 _ g然后就是准备计算NRI所需要的各个参数。/ [8 P# X( ]6 r$ y6 E8 G$ P" s
4 t9 L$ z% |" q |3 z# 定义结局事件,0是存活,1是死亡; W. g, A z7 \% m3 O
event = ifelse(dat$time < 2000 & dat$status == 2, 1, 0)
! {0 }+ B$ R) i9 U* P3 l# ?
* W$ b, I/ b4 b1 ]! r. f# 两个只由预测变量组成的矩阵. @/ M' \) C/ u1 K
z.std = as.matrix(subset(dat, select = c(age, bili, albumin)))
; h w: k9 ~4 q5 Q5 N. t+ Uz.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))
$ K$ V+ z6 M% r. b: n% C: F# ]2 u8 ]( ?' i
# 建立2个模型
' c$ u( C) q6 |" c0 P/ pmstd = glm(event ~ age + bili + albumin, family = binomial(), data = dat, x=TRUE)
6 w% n) X) V4 h" M- l% Gmnew = glm(event ~ age + bili + albumin + protime, family = binomial(), data = dat, x=TRUE)
7 S& I9 X& h6 Y( ^
" n* r2 R: C4 |9 x! `% v# 取出模型预测概率: j8 b7 k" Y# y* t1 M9 G+ \
p.std = mstd$fitted.values
; \: u& @0 B6 ~; op.new = mnew$fitted.values0 Z( \% P/ R) t# X. j' J
+ i# |6 j7 w% V' T1 K1 |
1. z: ?5 ?- W# G ]& a0 f9 t
然后就是计算NRI,对于二分类变量,使用nribin()函数,这个函数提供了3种参数使用组合,任选一种都可以计算出来(结果一样),以下3组参数任选1组即可。 mdl.std, mdl.new 或者 event, z.std, z.new 或者 event, p.std, p.new。8 |. D! b# h; V: u
( F% k0 A; s+ L
# 这3种方法算出来都是一样的结果
5 q: e+ Z! x+ d1 A3 l$ T3 }3 G2 t0 r y7 z' G
# 两个模型
2 @" a. A) L9 ]nribin(mdl.std = mstd, mdl.new = mnew,
" R C8 L2 ?6 Q9 E8 u cut = c(0.3,0.7),
7 Y% d& |$ u; t' Y6 _$ \0 ~ niter = 500, " ?$ z" D7 ^% `- y1 m7 u0 k6 N; y
updown = 'category')/ [- D W6 D. B" b
' n: J" u6 k0 ?$ n: U# 结果变量 + 两个只有预测变量的矩阵6 ~4 d# e! j$ ~$ Q7 n9 h( w/ U
nribin(event = event, z.std = z.std, z.new = z.new,
: H& K1 U& ?- u& g% ] cut = c(0.3,0.7),
! q/ j( [7 j2 ]! ?( H) g- C niter = 500, % M: _# C5 t* h6 I& n, Y7 L" l
updown = 'category')
# a P$ n2 d. U" s/ m9 C- K9 M( I8 H: V+ k
## 结果变量 + 两个模型得到的预测概率
# [ |$ u0 B! ~5 D4 t* P" Vnribin(event = event, p.std = p.std, p.new = p.new, " r& F3 [8 _# L" D# h( m
cut = c(0.3,0.7),
$ n4 `5 e0 b, K* \0 \ niter = 500,
. _5 [( t" U2 a updown = 'category')
# O% a: c' i. b k4 z, D
7 T; x' c# S ~8 b- I2 a1
+ u+ x- i) _( u9 d# ?+ C* N" @其中,cut是判断风险高低的阈值,我们使用了0.3,0.7,代表0-0.3是低风险,0.3-0.7是中风险,0.7-1是高风险,这个阈值是自己设置的,大家根据经验或者文献设置即可。
' U' f C! P$ Y: _7 n/ \* ~
. n, S8 R( y0 }- initer是使用bootstrap法进行重抽样的次数,默认是1000,大家可以自己设置。
1 g. H U/ m0 k* |
9 t2 {% I) m# O) A' oupdown参数,当设置为category时,表示低、中、高风险这种方式;当设置为diff时,此时cut的取值只能设置1个,比如设置0.2,即表示当新模型预测的风险和旧模型相差20%时,认为是重新分类。( ?6 ~4 A3 D, t/ {- H, J
8 c7 @1 b; h1 ?2 Y上面的代码运行后结果是这样的:
( l7 ^. f& r s1 c
5 i$ r. X. H( v7 YUP and DOWN calculation:# w# a6 Q$ s F! D! I: k
#of total, case, and control subjects at t0: 232 88 144' k+ g5 U) e1 C8 {8 g
" ?$ {% \0 W2 A/ M/ I0 Z
Reclassification Table for all subjects:
; ~) e- ^1 E! g7 C( z New
2 h* O; b( l# |& Z0 H- l) vStandard < 0.3 < 0.7 >= 0.7
" b* o3 A8 d' ^# K: [ < 0.3 135 4 0
4 U0 R& M$ C! n$ t0 A" k < 0.7 1 31 49 _6 H+ O: L( M5 |* c/ ?
>= 0.7 0 2 55
4 J; I& b- B" u3 ?4 ^! y$ e
0 Q4 N6 ~+ {6 ?& ~, S* L Reclassification Table for case:
4 N6 b" N5 ~ F9 R0 ^ I$ `8 ` New
B: g' C; ?: j6 A7 EStandard < 0.3 < 0.7 >= 0.76 k' }; {9 F, s
< 0.3 14 0 0, |6 N% g1 J' Q5 |: `
< 0.7 0 18 3
; _; G6 C1 s' W/ G' J* _ >= 0.7 0 1 520 x! [0 P) V x
* ]$ V, S2 k4 \: {
Reclassification Table for control:- J8 @2 z; }0 g8 o& J9 D
New
' p- q, c( X# X( n# }9 P6 {* cStandard < 0.3 < 0.7 >= 0.7* L+ T% m. w& |3 R2 B& Y! Z
< 0.3 121 4 0
" {- E+ U) t- Z& z" \ < 0.7 1 13 1, v2 E2 t3 c# k6 p2 W1 {* D
>= 0.7 0 1 3
9 @; Z: Z( c6 |1 L, u" M: |; c5 v, m- K
NRI estimation:
5 [4 Y; a( \- i$ b- p- d4 r5 jPoint estimates:
0 G: Z& `# M; V2 d Estimate
5 i) I( g9 K& b( O# oNRI 0.001893939
?1 n5 K0 |+ s- q. d/ INRI+ 0.022727273" b4 ?/ x |* r( u
NRI- -0.020833333
2 K* u- p% `7 p# [: APr(Up|Case) 0.034090909# y' V6 o; f5 A5 l) w
Pr(Down|Case) 0.0113636361 a) @9 o8 A2 y k% u8 P
Pr(Down|Ctrl) 0.013888889
4 h8 B: Q% R, v3 h3 XPr(Up|Ctrl) 0.034722222+ s& z' r. b% q" j0 ^# ?
2 b3 A) k0 A* K5 }4 k( R' a
Now in bootstrap.. f4 N2 ?9 g- y
1 r( W0 E3 ?5 U p% \5 q" I
Point & Interval estimates:
" u7 d" W% I5 u# o7 B Estimate Std.Error Lower Upper
. X1 e8 j- u' h+ I( f h' SNRI 0.001893939 0.027816095 -0.053995513 0.055354449
/ H3 U0 j) P: h: l3 @3 s W/ ]" `NRI+ 0.022727273 0.021564394 -0.019801980 0.065789474
# j/ u$ B f4 \0 S" P( @0 PNRI- -0.020833333 0.017312438 -0.058823529 0.007518797
7 x: |- x: V" j: |Pr(Up|Case) 0.034090909 0.019007629 0.000000000 0.072164948. T2 p% I0 y2 q5 n, U" v+ R
Pr(Down|Case) 0.011363636 0.010924271 0.000000000 0.039603960
' R6 B" {5 }& R% B5 O9 ~Pr(Down|Ctrl) 0.013888889 0.009334685 0.000000000 0.0352112684 ?# {# Z' G/ e! ]# P! z! ^
Pr(Up|Ctrl) 0.034722222 0.014716046 0.006993007 0.066176471
: o9 u: r3 g# i: a& |. Y9 U# c- K1 Z2 Y6 ^ j9 [
1+ Z0 @# x, w7 c H: \4 a
首先是3个混淆矩阵,第一个是全体的,第2个是case(结局为1)组的,第3个是control(结局为2)组的,有了这3个矩阵,我们可以自己计算净重分类指数。1 r" V w+ C/ I2 z) K5 T* u3 ]
+ t- \# y% @& \
看case组:( O7 g- w& Q7 N5 M8 g1 x
* ~9 ~& Y8 x2 O! o净重分类指数 = ((0+3)-(0+1)) / 88 ≈ 0.0227272732 ^* I; D8 \3 w* U/ ?7 Q$ \( J9 L u
% L& A- S' k' b
再看control组:
9 B( V, y- `8 g8 J
# y. d& C. O& t. V; y8 p9 `净重分类指数 = ((1+1)-(4+1)) / 144 ≈ -0.020833333
) ^3 Z) G' Y2 ` K$ I: @# [' b4 K9 W8 ]& n! T- {9 C" E( F
相加净重分类指数 = case组净重分类指数 + control组净重分类指数 = 2/88 - 3/144 ≈ 0.000315657! Y! d0 X; C# {8 ]) x8 L$ c
8 I, C; L7 \* n6 k( v, w; G, A再往下是不做bootstrap时得到的估计值,其中NRI就是绝对净重分类指数,NRI+是case组的净重分类指数,NRI-是control组的净重分类指数(和我们计算的一样哦),最后是做了500次bootstrap后得到的估计值,并且有标准误和可信区间。/ r$ p# }- h6 o6 `3 P; _! B# D
7 l' w- P6 E3 ~% @最后还会得到一张图:
2 L7 g* A G5 f' K; }2 A/ ?
1 l* C N6 [9 l, z这张图中的虚线对应的坐标,就是我们在cut中设置的阈值,这张图对应的是上面结果中的第一个混淆矩阵,反应的是总体的情况,case是结果为1的组,也就是发生结局的组,control是结果为0的组,也就是未发生结局的组。
6 G7 d1 \* D/ w+ o( k* c/ X2 W- Z. a- G
P值没有直接给出,但是可以自己计算。
9 F' \# l E& y
! E. f. G- q, C( P- [3 Y# 计算P值1 ?1 {+ f4 K$ s8 h+ C
z <- abs(0.001893939/0.027816095)
) P2 c/ A/ }* i2 N1 p7 {. lp <- (1 - pnorm(z))*2
) f4 U2 I$ Q; @# T1 Vp
9 j+ X5 ], }7 K! A& U: v1
& l( l- ?9 T' S$ B' Y6 g, c. Q## [1] 0.9457157 F" d$ u" `& S
1, `" ]5 [3 a6 h3 L
PredictABEL包
/ F1 b$ Q) y) v& m#install.packages("PredictABEL") #安装R包
5 p/ N" @, S J9 f# I/ l% _library(PredictABEL) 0 a& `1 w" M$ m s; g6 \8 e: }
& m9 a d0 W4 P7 t
# 取出模型预测概率,这个包只能用预测概率计算( I. M! W8 S9 S: p+ R0 `
p.std = mstd$fitted.values
8 N6 \# T6 H0 tp.new = mnew$fitted.values . W, g4 ?& {+ }
1
7 t/ }* e0 l2 b8 r; }2 d, x- L然后就是计算NRI:' |2 {9 o) \ M3 D1 R; h ^
3 o/ `! K/ Z* q, n
dat$event <- event& R9 t- X+ W- Z* w
" L: t' @* ?4 |2 ?' u
reclassification(data = dat,
3 m' Q6 v3 b3 c j$ A1 z, o cOutcome = 21, # 结果变量在哪一列
) U# o3 ~; V& N7 Q: f2 x& N4 w predrisk1 = p.std,
% N3 d; b. Z2 Y6 C- _8 ~ predrisk2 = p.new,
4 O& N& d6 ~0 l6 G) p E: G4 S cutoff = c(0,0.3,0.7,1)
* v& c2 `8 v% F" l ~' z )6 w3 ~/ I4 Q0 B: V+ j
16 h m0 T* F( V6 k4 D' j- W0 _0 T
## _________________________________________
2 A( Z& k+ n# v' `! T5 o. Q [##
) L; `# h2 x: n## Reclassification table * V6 _, z) Z. \1 U( Y, B
## _________________________________________8 ?0 _6 x! b$ C3 S
##
$ x. Z) C$ e0 }## Outcome: absent
5 c+ p( ]0 g. z% `# T##
; l! p& A- X8 j( `) Y## Updated Model
/ v/ _ s8 \4 s3 c+ J6 J; C; ~8 T2 M## Initial Model [0,0.3) [0.3,0.7) [0.7,1] % reclassified; p" S0 F% m8 R: i+ A' v
## [0,0.3) 121 4 0 3 }/ X5 B' Z, ]0 p4 w } B ~" h
## [0.3,0.7) 1 13 1 13
6 r( F& R/ A" d## [0.7,1] 0 1 3 25
9 D' |2 ?; h9 [% ]: M, I- e##
" c$ j1 ?: N2 {! e0 L/ @##
, M O% I7 @4 ?' U3 O0 L## Outcome: present 4 w; y9 t( `/ J9 p
##
8 v- Z$ X% n7 E' Z: ?4 x* r## Updated Model
& k6 q3 c y1 u+ m% v: U& p, f## Initial Model [0,0.3) [0.3,0.7) [0.7,1] % reclassified
) t7 b' q J( u- x; y## [0,0.3) 14 0 0 0
$ |' g% i! ~) n5 L1 b( c- i1 a## [0.3,0.7) 0 18 3 145 K/ a# D+ C) q
## [0.7,1] 0 1 52 2$ Q' I0 b9 ]9 X
## + P5 U, ^/ Y( |' E+ _
## 4 }+ R. u- A* O& c/ F
## Combined Data u7 ]. `0 n! K" l8 R5 h( t
## 8 n4 K ~* P1 g' g8 x5 u
## Updated Model
$ l0 T1 i) t$ F3 P: ~3 i) {## Initial Model [0,0.3) [0.3,0.7) [0.7,1] % reclassified$ Y$ J7 N2 J3 a: K; ]* p
## [0,0.3) 135 4 0 3* H: V; r4 j) |- B" P L4 F9 P" V# r
## [0.3,0.7) 1 31 4 14
' L) V+ ]% {( |) t## [0.7,1] 0 2 55 42 Q! P5 Z g( J4 A$ U
## _________________________________________
$ D0 I; d* C3 i& v e$ }## 2 @& x. p z4 ~ y: C. V. \
## NRI(Categorical) [95% CI]: 0.0019 [ -0.0551 - 0.0589 ] ; p-value: 0.94806 t9 X9 T5 r7 ]" W, s f
## NRI(Continuous) [95% CI]: 0.0391 [ -0.2238 - 0.3021 ] ; p-value: 0.77048
~" e* I4 [7 S" W/ S# i) Z## IDI [95% CI]: 0.0044 [ -0.0037 - 0.0126 ] ; p-value: 0.283968 l; E U3 Q8 E B+ j7 s ^
: N0 X# N) m' E
1
' D( U' Z. v0 B: C$ b* h结果得到的是相加净重分类指数,还给出了IDI和P值。两个包算是各有优劣吧,大家可以自由选择。
' M) B8 _* Q6 A
3 T/ y% X8 J& w; f% d' m生存分析的NRI
+ |- k; j9 a; V2 H8 i5 i- d" z还是使用survival包中的pbc数据集用于演示,这次要构建cox回归模型,因此我们要使用time这一列了。
R8 b' v% R7 h! d/ n0 I) v; m
; Z, ]; Z5 K e; Y; ^nricens包
% l, L! N+ V* y6 U) Xlibrary(nricens)
8 G) [8 J/ L9 nlibrary(survival)
: p3 f2 C- Y9 ^5 J/ }: o
( _, B1 _2 W% d) H, t' zdat <- pbc[1:312,]
+ [# Y+ f y# \- h( {) ?: Y" v8 odat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡& O& j0 z8 I) @8 t
16 f- K6 F3 |# [, y, M, d+ p! C
然后准备所需参数:/ i6 I) ~1 t" \1 Q) t
0 ^3 P3 i# h- U, Q7 ?
# 两个只由预测变量组成的矩阵
: J. V: T* N3 j+ p) ]z.std = as.matrix(subset(dat, select = c(age, bili, albumin)))% v2 K. J$ V( ~, B- ~
z.new = as.matrix(subset(dat, select = c(age, bili, albumin, protime)))6 T2 a8 ]$ p0 m! o) G7 n
# g9 d. v/ @/ {9 d# 建立2个cox模型
9 g) m1 X2 F" i; t v2 nmstd <- coxph(Surv(time,status) ~ age + bili + albumin, data = dat, x=TRUE)
3 k V" V4 ?. v/ G7 X1 W0 cmnew <- coxph(Surv(time,status) ~ age + bili + albumin + protime, data = dat, x=TRUE)/ n( i. a8 F4 Z8 O F
& {$ ?; G$ @ s3 j& K! g
# 计算在2000天的模型预测概率,这一步不要也行,看你使用哪些参数' D* \$ K/ }: g8 q" z
p.std <- get.risk.coxph(mstd, t0=2000)
8 d% U! k% j# s* Q/ rp.new <- get.risk.coxph(mnew, t0=2000)5 G0 e9 I0 _2 {' p
1
% X( x5 z: b% ^5 O: T6 U3 O计算NRI:9 W5 L. i& J( R6 Q/ H
5 k% g1 s( K% e$ G# J& x; znricens(mdl.std= mstd, mdl.new = mnew, - k( R+ g: D1 P" z8 @
t0 = 2000,
" n f5 P2 c% X cut = c(0.3, 0.7),
" X0 g+ N1 I, _; c; [ niter = 1000, $ Y: O4 S |8 A/ g
updown = 'category')
* }* P/ M! z) W }4 {2 V! W
# w4 e0 h; L' u) u1 q% TUP and DOWN calculation:
+ R8 i+ x# r8 m. G" h #of total, case, and control subjects at t0: 312 88 144
8 p* L! x, `9 {: g
K" H+ F V' i t" ^ Reclassification Table for all subjects:2 N" h0 n% S h$ ~: ?: c
New% M4 d" D. {. r: k. q0 m/ Y
Standard < 0.3 < 0.7 >= 0.7 [7 ^& o/ \$ n" u) _* N
< 0.3 202 7 0' X0 s. T6 ^) Z7 T% g7 m; W# K
< 0.7 13 53 6: u* B7 i9 b" L% l. i c" ^
>= 0.7 0 0 31$ k K; j$ p* v. w7 Q4 z8 D
4 h: V7 A. U2 N
Reclassification Table for case:
* i i3 I+ T F+ h: x New4 f3 G' ~0 N- r/ v+ U# U
Standard < 0.3 < 0.7 >= 0.75 `) V, ^) u: }* o6 {5 k
< 0.3 19 3 0
/ n, [: X l* H6 H: b& Q: Q < 0.7 3 32 4
# v& `: S$ P p/ Z) p: v% O+ ] >= 0.7 0 0 27" U0 f/ S# I8 J G
- N8 d4 L) t* t, ? Reclassification Table for control:) I* W5 N$ O% S f+ v/ K1 z
New
& n* Z4 \. t# X* [$ r( v- i# ?- YStandard < 0.3 < 0.7 >= 0.7
5 s6 }& j- l' S < 0.3 126 3 05 }7 y) Y( \$ K# {* g# P
< 0.7 5 7 2( c+ P, ]1 `* |% l! u6 u: D- L1 A: h
>= 0.7 0 0 1
# W; q) H3 t/ i; _# f! L
* a, W) P( m5 `NRI estimation by KM estimator:1 l' C# D' @. g7 N! B4 f
' X" R4 J7 i2 U
Point estimates:* N% {/ H& K% P7 g4 N
Estimate
7 L _2 Q1 ]- ]. x5 x/ Q4 n# vNRI 0.053776358 S$ a( q2 c+ r9 _4 j6 x! E
NRI+ 0.03748660
5 S% q- _" c2 J; }4 K, ]NRI- 0.01628974% i: e, T8 w" X. q
Pr(Up|Case) 0.07708938
( S# |+ @# N K" MPr(Down|Case) 0.039602786 q0 M. j5 p% p; ^! h) d; M' p+ I* p
Pr(Down|Ctrl) 0.04256352+ w+ |- u% ~. g, l' `
Pr(Up|Ctrl) 0.026273787 g- X0 {* B: @; G8 O }
3 A1 ` |, I3 `# M( y K& f4 q
Now in bootstrap.., ^; w. Q3 {4 ]& }
% p% G5 p; I" r. e# }
Point & Interval estimates:8 `0 m+ Z3 y0 P1 ~
Estimate Lower Upper1 ~. o' T' e; u& g q" B
NRI 0.05377635 -0.082230381 0.16058172. n3 M; x% D3 f5 s0 z: G
NRI+ 0.03748660 -0.084245197 0.13231776
* \0 z( j. T9 N! s+ y- b3 pNRI- 0.01628974 -0.030861213 0.06753616" E0 v5 g. \5 @
Pr(Up|Case) 0.07708938 0.000000000 0.19102291
2 x2 a. S+ p1 o* m& Z6 b: RPr(Down|Case) 0.03960278 0.000000000 0.15236016- W6 R3 i, o q6 B! X
Pr(Down|Ctrl) 0.04256352 0.004671535 0.09863170% y+ f$ z0 n( j, s
Pr(Up|Ctrl) 0.02627378 0.006400463 0.05998424
$ O' Y" Y4 w3 R9 U) b0 R J7 m4 N" _/ e+ e
13 S% w6 Y' Y4 h6 j4 U2 C4 z7 j) n" E
, W, _/ r6 e& o- f; [) T
Snipaste_2022-05-20_21-49-381 |: C& Z7 N/ a
结果的解读和logistic的一模一样。
. V5 a) R+ X) U7 _
( q5 P i$ {4 T6 Z9 |/ i3 gsurvNRI包. z/ a2 }" F( f$ y- v
# 安装R包
) J8 k6 K# z: p: q4 ]0 u/ mdevtools::install_github("mdbrown/survNRI")0 [4 f3 u; ?: q: ~' @# p
1
7 c: E- P5 M7 r. H) ~# m- [4 [$ h加载R包并使用,还是用上面的pbc数据集。
6 I5 h4 _6 N1 O6 Z" j/ D! h8 @$ `/ f! |) e8 e' E
library(survNRI)/ B1 x/ T+ a$ M; K* K* `
1
9 h' o# S6 _3 Z4 z, d! k## Loading required package: MASS
H( A: Q. L( w: ~1- ] ?0 v$ U- K2 ^
library(survival)
2 m0 n" j8 b7 K# m
! F- s5 M9 {0 [# z# 使用部分数据- R# N+ Y0 P, B/ H% k1 n g
dat <- pbc[1:312,]
. x2 G0 }- N8 e" h0 a' f: Ydat$status <- ifelse(dat$status==2, 1, 0) # 0表示活着,1表示死亡
! \3 x! K7 H, ~+ d9 v( v- x3 E k; y0 q5 B1 {" i
res <- survNRI(time = "time", event = "status",
3 ]* h+ V+ E, F3 c' A& V: ^3 u+ f/ M2 J model1 = c("age", "bili", "albumin"), # 模型1的自变量" m' }% r( O2 D- F7 P8 t
model2 = c("age", "bili", "albumin", "protime"), # 模型2的自变量
. S [- B4 p, L9 t- X data = dat,
4 m' W. V) L8 [( d0 b" `# } predict.time = 2000, # 预测的时间点. d: }5 X# ? ~8 k8 {& z+ w' O
method = "all",
; _3 |- T9 k7 Q% ^5 P) c bootMethod = "normal",
5 } y0 g+ p5 u! @. r" ^/ J* u* P bootstraps = 500,
, F. Y6 B) i$ Y: S: @/ t alpha = .05)1 Y- x% j! \( n# |
0 z y0 P9 W) O9 W! R& e: j1
' L5 N# C6 e+ d- ?6 x- x查看结果,$estimates给出了不同组的NRI以及总的NRI,包括了使用不同方法(KM/IPW/SmoothIPW/SEM/Combined)得到的结果;$CI给出了可信区间。
5 w I- q, k1 [! A+ n4 h! F" a$ u. h+ h ~ ]/ h( R) R
res6 L* A; F; e8 I- Q; t; s
1( o" P }" N. T+ W
## $estimates( K' |; [( t+ D0 N- K
## NRI.event NRI.nonevent NRI# p$ w O# ?! ^$ x
## KM 0.20445422 0.3187408 0.5231951% ]+ Z; C O) v: p
## IPW 0.22424434 0.3273544 0.55159873 v; @; H/ R' v+ ~+ n
## SmoothIPW 0.19645006 0.3144263 0.5108763
1 c2 e% `0 R. j## SEM 0.07478611 0.2632127 0.3379988
! e0 t" N1 s( t, Q( E## Combined 0.19633867 0.3143794 0.51071812 p/ O- N* f6 k% s |
## 6 K8 N, G5 y# S5 F t5 ~* K
## $CI
/ W1 z+ _2 r" D, W$ d0 H## $CI$NRI.event
; _2 }. c9 }7 h( S## KM IPW SmoothIPW SEM Combined
0 P8 d8 Q1 a" i; ~. a1 ^. f## lowerbound -0.03915924 -0.02185068 -0.04724202 -0.1162587 -0.0473723
0 j) X' m* o: T n/ t7 D## upperbound 0.44806768 0.47033936 0.44014214 0.2658309 0.4400496
/ n2 z3 q3 j2 k- ?+ B0 t+ W5 S$ a## 2 W! z, u) }) d% k& ]. C4 u) V# }/ n
## $CI$NRI.nonevent
4 ~% E, U1 D+ ~* _( b4 ]## KM IPW SmoothIPW SEM Combined6 v1 g0 L9 m0 I" M7 G
## lowerbound 0.1317108 0.1396315 0.1286685 0.08638933 0.1286426' k: O8 k; h+ K; O
## upperbound 0.7102251 0.7393216 0.6966341 0.51482212 0.6964549
+ S5 O3 Y; l9 ^##
; T2 S/ y( h r% b. G+ E1 u## $CI$NRI
" Q0 n2 y S9 m q' @/ \## KM IPW SmoothIPW SEM Combined
5 E7 n5 H1 N5 s% G- Y## lowerbound -0.05112533 -0.04569046 -0.05439863 -0.04132364 -0.054434094 I; z- J3 P9 s: Z* e+ Q
## upperbound 0.89306122 0.92464359 0.87970125 0.64253510 0.87953153! m+ Q5 T5 O0 h8 \+ ~
##
; V: ?9 w8 J' b# K+ H# H0 p## 2 q% |2 Z# q# B( F0 T
## $bootMethod
+ I' m# H: Q/ v; o" }## [1] "normal"
% [9 e- V4 \$ b3 T. A1 t: N- |## 3 G0 P6 Y( R( O
## $predict.time
7 O) i! N1 m1 T6 z/ P, r W## [1] 2000
, y2 [- ~4 ]: h S/ y) a! y4 M##
) I) u5 c% P) c. m3 i## $alpha
/ d+ d$ L! R' \7 Q U- H+ z, H## [1] 0.056 G: f0 e$ Y# s: i. T
##
k# h% u5 c2 Q& m r* _- [* L## attr(,"class")* o# ~! G) i; f; R$ \
## [1] "survNRI"
6 z4 }" t. } x( s
6 B4 H' i; {. U( z1# I8 Z: G4 p, p% ~* H
OK,这就是NRI的计算,除此之外,随机森林、决策树、lasso回归、SVM等,这些模型,都是可以计算的NRI的,后面会继续介绍。大家如果有问题欢迎在评论区留言。- v+ t/ u/ e+ j( _" d: ^
+ f) F$ m$ {# N( D( y
本文首发于公众号:医学和生信笔记
% x0 o3 \ m2 u9 |2 L k' J4 b/ e, |7 r1 H# I7 M# ?. ]* S
“ 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。
& A% z# c& l1 L E6 M6 ^本文由 mdnice 多平台发布. S! _8 R! |; f, \
————————————————) U) H# E' [! y1 Y5 @/ S: _. `
版权声明:本文为CSDN博主「阿越就是我」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
/ C5 A( j: Z& u7 Q原文链接:https://blog.csdn.net/Ayue0616/article/details/126768006- f( i# M, C5 y( c
( C1 `5 Z) t+ Q j/ i b
1 e) Z2 z0 \$ n* q- @4 W% F( |" K
|
zan
|