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