Learn R Programming

⚠️There's a newer version (0.2.2) of this package.Take me there.

vlad

An R-package which contains functions to set up risk-adjusted quality control charts in health care.

Main features

  • Risk-adjusted CUSUM chart based on E-O by Wittenberg et al. (2018)
  • Risk-adjusted CUSUM chart based on log-likelihood ratio statistic by Steiner et al. (2000)
  • Algorithms are implemented using Rcpp and RcppArmadillo
  • High performance with parallel computation

Installation

You can install the released version of vlad from CRAN with:

install.packages("vlad")

And the development version from GitHub with:

# install.packages("devtools")
devtools::install_github("wittenberg/vlad")

Example

Load libraries:

library("vlad")
library("dplyr")
library("tidyr")
library("ggplot2")

Subset the dataset cardiacsurgery into Phase I (first two years) and Phase II (five years) and estimate a risk model based on phaseI.

data("cardiacsurgery", package = "spcadjust")
cardiacsurgery <- cardiacsurgery %>% rename(s = Parsonnet) %>%
  mutate(y = ifelse(status == 1 & time <= 30, 1, 0),
        phase = factor(ifelse(date < 2*365, "I", "II")))
head(cardiacsurgery)
#>   date time status  s surgeon y phase
#> 1    1   90      0 15       7 0     I
#> 2    1   90      0  9       3 0     I
#> 3    2   90      0  2       5 0     I
#> 4    3   90      0  8       7 0     I
#> 5    3   90      0  7       1 0     I
#> 6    3   90      0 40       1 0     I
phaseI <- filter(cardiacsurgery, phase == "I") %>% select(s, y)
coeff <- round(coef(glm(y ~ s, data = phaseI, family = "binomial")), 3)
print(coeff)
#> (Intercept)           s 
#>       -3.79        0.08

Create VLADs for seven surgeons

By using the estimated risk model coefficients coeff, for each pair of Parsonnet score s and operation outcome values y, the difference between expected and observed outcome is calculated with the function calceo(). Thereafter, differences are cummulated to create the VLAD. This is done for all seven surgeons of the cardiacsurgery dataset. Results are saved to the object vlads7.

vlads7 <- lapply(1:7, function(j){
  Si <- filter(cardiacsurgery, surgeon == j)
  EO <- sapply(seq_along(Si$s), function(i) calceo(df = Si[i, c("s", "y")], coeff = coeff))
  select(Si, surgeon, phase) %>%  mutate(n = 1:length(EO), cEO = cumsum(EO))
}) 

Create Variable life-adjusted Displays for each surgeon from the object vlads7.

vlads7 %>% 
  bind_rows() %>%  
  gather(key = "Surgeon", value = value, c(-n, -surgeon, -phase)) %>%
  ggplot(aes(x = n, y = value, colour = phase, group = Surgeon)) +
    geom_hline(yintercept = 0, colour = "darkgreen", linetype = "dashed") +
    geom_line(size = 1.1) + facet_wrap( ~ surgeon, ncol = 2, scales = "free") +
    labs(x="Patient number n", y="CUSUM E-O") + theme_classic() +
    scale_y_continuous(sec.axis = dup_axis(name = NULL, labels = NULL)) +
    scale_x_continuous(sec.axis = dup_axis(name = NULL, labels = NULL))

Create a VLAD for surgeon 2

S2 <- filter(cardiacsurgery, surgeon == 2) %>% select(phase, s, y)
S2I <- subset(S2, c(phase == "I"))
S2II <- subset(S2, c(phase == "II"))
coeff <- coef(glm(y ~ s, data = S2I, family = "binomial"))
EO <- sapply(1:nrow(S2), function(i) calceo(df = S2[i, c("s", "y")], coeff = coeff))

df1 <- select(S2, phase) %>% mutate(n = row_number(), cEO = cumsum(EO))
df2 <- gather(df1, variable, value, c(-n, -phase))

p1 <- ggplot(df2, aes(x = n, y = value, colour = phase)) +
  geom_hline(yintercept = 0, linetype = "dashed") + geom_line() + geom_point() + 
  labs(x = "Patient number", y = "CUSUM E-O") + theme_classic() +
  scale_y_continuous(sec.axis = dup_axis(name = NULL, labels = NULL)) +
  scale_x_continuous(sec.axis = dup_axis(name = NULL, labels = NULL))
p1

Compute thresholds of a risk-adjusted CUSUM chart for surgeon 2

Upper and lower control limits of the risk-adjusted CUSUM chart based on log-likelihood ratio statistic can be computed with the function racusum_arl_h_sim(). The implemention uses parallel simulation and a multi-stage search procedure.

# set a random number generator for parallel computations
RNGkind("L'Ecuyer-CMRG")
# number of simulation runs
m <- 10^4
# assign cores
nc <- parallel::detectCores()
# verbose calculation 
UCL_sim <- racusum_crit_sim(L0 = 740, df = S2I[, c("s", "y")], coeff = coeff, m = m, RA = 2, nc = nc, verbose = TRUE)
#> h = 1    ARL = 75.006 
#> h = 2    ARL = 383.3554 
#> h = 3    ARL = 1312.8564 
#> h = 2.9  ARL = 1181.3768 
#> h = 2.8  ARL = 1052.3355 
#> h = 2.7  ARL = 928.6587 
#> h = 2.6  ARL = 822.3063 
#> h = 2.5  ARL = 730.0184 
#> h = 2.51     ARL = 739.8392 
#> h = 2.52     ARL = 747.3412 
#> h = 2.519    ARL = 746.4942 
#> h = 2.518    ARL = 745.9933 
#> h = 2.517    ARL = 745.6282 
#> h = 2.516    ARL = 744.6935 
#> h = 2.515    ARL = 744.0614 
#> h = 2.514    ARL = 743.2221 
#> h = 2.513    ARL = 742.2656 
#> h = 2.512    ARL = 741.7172 
#> h = 2.511    ARL = 741.3188 
#> h = 2.51     ARL = 739.8392 
#> h = 2.5101   ARL = 739.862 
#> h = 2.5102   ARL = 739.862 
#> h = 2.5103   ARL = 740.0315
# quite calculation
LCL_sim <- racusum_crit_sim(L0 = 740, df = S2I[, c("s", "y")], coeff = coeff, m = m, RA = 1/2, nc = nc, verbose = FALSE)
round(cbind(UCL_sim, LCL_sim), 3)
#>      UCL_sim LCL_sim
#> [1,]    2.51   2.281

References

Wittenberg et al. (2018). A simple signaling rule for variable life-adjusted display derived from an equivalent risk-adjusted CUSUM chart

Steiner et al. (2000). Monitoring surgical performance using risk-adjusted cumulative sum charts

Authors

Philipp Wittenberg and Sven Knoth

License

GPL (>= 2)

Copy Link

Version

Install

install.packages('vlad')

Monthly Downloads

47

Version

0.2.0

License

GPL (>= 2)

Maintainer

Philipp Wittenberg

Last Published

December 6th, 2018

Functions in vlad (0.2.0)

ell

Estimated log-likelihood.
eocusum_arl_sim

Compute ARLs of EO-CUSUM control charts using simulation
eocusum_arloc_h_sim

Compute alarm threshold of Out of Control EO-CUSUM control charts using simulation
racusum_arloc_h_sim

Compute alarm threshold (Out of Control ARL) of RA-CUSUM control charts using simulation
racusum_arloc_sim

Compute Out of Control ARLs of RA-CUSUM control charts using simulation
cusum_arl_h_sim

Compute alarm threshold of Bernoulli CUSUM control charts using simulation
cusum_arl_sim

Compute ARLs of Bernoulli CUSUM control charts using simulation
eocusum_arloc_sim

Compute Out of Control ARLs of EO-CUSUM control charts using simulation
eocusum_adoc_sim

Compute steady-state ARLs of EO-CUSUM control charts using simulation
eocusum_arl_h_sim

Compute alarm threshold of EO-CUSUM control charts using simulation
eocusum_scores

Compute CUSUM scores based on E-O
eocusum_crit_sim

Compute alarm threshold of EO-CUSUM control charts using simulation
bcusum_crit_sim

Compute alarm threshold of Bernoulli CUSUM control charts using simulation
gettherisk

Compute Risk of death
racusum_crit_mc

Compute alarm threshold of RA-CUSUM control chart using Markov chain approximation
calceo

Compute Expected minus Observed value
racusum_adoc_sim

Compute steady-state ARLs of RA-CUSUM control charts using simulation
racusum_crit_sim

Compute alarm threshold of RA-CUSUM control charts using simulation
trafo

Box-Cox transformation of data.
vlad-package

Variable Life Adjusted Display and Other Risk-Adjusted Quality Control Charts
racusum_arl_h_sim

Compute alarm threshold of RA-CUSUM control charts using simulation
racusum_arl_sim

Compute ARLs of RA-CUSUM control charts using simulation
racusum_arl_mc

Compute ARLs of RA-CUSUM control charts using Markov chain approximation
QQ

Pearson measure
bcusum_arl_sim

Compute ARLs of the Bernoulli CUSUM control charts using simulation
llr_score

Compute the log-likelihood ratio score
optimal_k

Compute optimal k
racusum_scores

Compute CUSUM scores based on the log-likelihood ratio statistic
search_delta

Search Box-Cox transformation parameter
eocusum_ad_sim

Compute steady-state ARLs of EO-CUSUM control charts using simulation