knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.dim = c(7, 5) ) library(cusum)
This vignette describes CUSUM charts based on a simulated false-signal-probability for hospital performance data in the R package cusum. This is a practical guide to constructing and evaluating non-risk-adjusted and risk-adjusted CUSUM charts following Steiner et al. (Biostatistics 1.4 (2000), pp. 441-52).
The cusum packages takes different factors into account that influence the signal rate of CUSUM charts. Some are given by the process to be monitored; these factors are:
The primary control input when constructing a CUSUM chart is the control limit. The control limit signals performance deterioration once crossed by the cumulated sum.
The control limit depends on a number of variables:
To illustrate how cusum can be used for monitoring, we employ a simple and artificial data set generated to closely follow the performance data of German hospitals for one non-risk-adjusted performance indicator and one risk-adjusted performance indicator in 2016 and 2017.
risk-adj. | Indicator Description | Further explanation (in German) --------- | -------------------- | --------------------------------- NO | Ratio of observed to expected cases of severe stroke or death under open carotid stenosis surgery | pdf (p4) YES | Preoperative stay more than 24 hours for patients with proximal femur fracture | pdf (p23)
Non-risk-adjusted performance indicator
data("cusum_example_data", package = "cusum") head(cusum_example_data)
Risk-adjusted performance indicator
data("racusum_example_data", package = "cusum") head(racusum_example_data)
First, CUSUM charts are constructed on performance data from 2016 (Phase I), and then applied and evaluated on performance data from 2017 (Phase II).
cusum_example_p1 <- cusum_example_data[cusum_example_data$year == 2016, ] cusum_example_p2 <- cusum_example_data[cusum_example_data$year == 2017, ] racusum_example_p1 <- racusum_example_data[racusum_example_data$year == 2016, ] racusum_example_p2 <- racusum_example_data[racusum_example_data$year == 2017, ]
We get the control limit of our CUSUM chart by simulating for a false signal probability depending on sample size and accepted failure probability.
We can estimate the accepted failure probability by taking the average of Phase I. Alternatively, we could also define an accepted failure probability politically
failure_probability <- mean(cusum_example_p1$y) n_patients <- nrow(cusum_example_p1)
Then, control limits can be simulated using cusum_limit_sim.
cusum_limit <- cusum_limit_sim(failure_probability, n_patients, odds_multiplier = 2, n_simulation = 1000, alpha = 0.05, seed = 2046) print(cusum_limit)
Monitoring via CUSUM charts is applied on performance data from 2017 (Phase II) and the control limit cusum_limit. It can be calculated using cusum.
patient_outcomes <- cusum_example_p2$y cusum_cs <- cusum(failure_probability, patient_outcomes, limit = cusum_limit, odds_multiplier = 2, reset = FALSE) head(cusum_cs) plot(cusum_cs)
Performance is as expected during the first half of monitoring, and then deteriorates. We get a signal at t=r sig <- cusum_cs$t[cusum_cs$signal==1]; sig[1]
. If reset==TRUE, the CUSUM resets after each signal.
cusum_cs <- cusum(failure_probability, patient_outcomes, limit = cusum_limit, odds_multiplier = 2, reset = TRUE) plot(cusum_cs)
The false signal probability of a CUSUM chart can be simulated using cusum_alpha_sim given a predefined control limit.
n_patients <- nrow(cusum_example_p2) cusum_alpha <- cusum_alpha_sim(failure_probability, n_patients, odds_multiplier = 2, n_simulation = 1000, limit = cusum_limit, seed = 2046) print(cusum_alpha)
We see that cusum_alpha equals our previously defined false signal probability of 0.05.
Control limits of RA-CUSUM charts are simulated for a false signal probability depending on sample size and risk distribution.
RA-CUSUM Control limits can be simulated using racusum_limit_alpha.
patient_risks <- racusum_example_p1$score racusum_limit <- racusum_limit_sim(patient_risks, odds_multiplier = 2, n_simulation = 1000, alpha = 0.05, seed = 2046) print(racusum_limit)
Monitoring via RA-CUSUM chart is applied on performance data from 2017 (Phase II) and the control limit racusum_limit. It can be calculated using racusum.
patient_risks <- racusum_example_p2$score patient_outcomes <- racusum_example_p2$y racusum_cs <- racusum(patient_risks, patient_outcomes, limit = racusum_limit, odds_multiplier = 2, reset = FALSE) plot(racusum_cs)
Performance is as expected during the first half of monitoring, and then deteriorates. We get a signal at t=r sig <- racusum_cs$t[racusum_cs$signal==1]; sig[1]
. If reset==TRUE, the CUSUM resets after each signal.
racusum_cs <- racusum(patient_risks, patient_outcomes, limit = racusum_limit, odds_multiplier = 2, reset = TRUE) plot(racusum_cs)
The false signal probability of a CUSUM chart can be simulated using cusum_alpha_sim.
racusum_alpha <- racusum_alpha_sim(patient_risks, odds_multiplier = 2, n_simulation = 1000, limit = racusum_limit, seed = 2046) print(racusum_alpha)
We see that racusum_alpha is similar to our previously defined false signal probability of 0.05. Deviation is possible due to a slight change in risk population.
CUSUM charts for detecting process improvements can be constructed similarly, but the CUSUM statistic is restricted to non-positive values.
cusum_limit_improve <- cusum_limit_sim(failure_probability, n_patients, odds_multiplier = .5, n_simulation = 1000, alpha = 0.5,seed = 2046) cusum_cs_improve <- cusum(failure_probability, patient_outcomes = cusum_example_p2$y, limit = cusum_limit_improve, odds_multiplier = .5) plot(cusum_cs_improve) cusum_alpha_sim(failure_probability, n_patients, odds_multiplier = 0.5, n_simulation = 1000, limit = cusum_limit_improve, seed = 2046)
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.