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