knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.width=6, fig.height=4, fig.align = "center", df_print = "tibble" ) options(dplyr.summarise.inform = FALSE)
Antimicrobial resistance jeopardizes many achievements of modern medicine, such as the ability to effectively treat infectious diseases or complete surgical procedures safely. Hospitals, alongside other inpatient facilities, make frequent use of categories of antibiotics which are most imminently eroding in effectiveness, the loss of which would have the most severe impact on health care systems [@Sharland2018]. They are thus at the forefront of the global effort to optimise the use of such antibiotics and sustain their effectiveness.
Ramses
is an R package designed to support the stewardship of antimicrobials in hospitals by facilitating the analysis of routinely-collected electronic health records for:
Ramses
is currently in development. The latest stable version can be installed using the devtools
package.
devtools::install_github("ramses-antibiotics/ramses-package")
Ramses
comes with synthetic data for testing and training purposes.
You can use it to create a demonstration DuckDB database fully loaded with
synthetic electronic health records on a local drive. No need for a database server.
library(Ramses) library(ggplot2) library(dplyr) ramses_db <- create_mock_database("ramses-db.duckdb")
You are now able to query the database and visualise admissions and episodes of antimicrobial therapy timeline below.
When hovered for a few seconds, timeline symbols display a tooltip containing detailed information.
therapy_timeline(Patient(conn = ramses_db, id = "99999999999"), date1 = as.Date("2017-02-01"), date2 = as.Date("2017-03-01"))
DBI::dbListTables(ramses_db)
Three main metrics are used to describe antimicrobial consumption in hospitals: Defined Daily Doses, Days on Therapy, and Length of Therapy. Definitions given by @StanicBenic2018 are reproduced below:
Formulae are available from @Ibrahim2014 along with a discussion of rates which can be derived from these metrics (eg per 1,000 admissions, per 1,000 bed-days). Statistical adjustment of these metrics is discussed by @VanSanten2018 and @Yu2018.
The approach to create tables of antimicrobial consumption follows three steps:
Consumption can be attributed to specialty based on the specialty of the episode during which the antibiotic is administered. In this case, the appropriate bridge table is bridge_episode_prescription_overlap
.
study_pop <- tbl(ramses_db, "inpatient_episodes") %>% filter(main_specialty_code %in% c("100", "101", "300") & discharge_date >= "2016-01-01") %>% mutate(calendar_year = year(discharge_date), calendar_month = month(discharge_date)) consumption_num <- study_pop %>% left_join(tbl(ramses_db, "bridge_episode_prescription_overlap")) %>% group_by(calendar_year, calendar_month, main_specialty_code) %>% summarise(DOT_prescribed = sum(coalesce(DOT, 0.0)), DDD_prescribed = sum(coalesce(DDD_prescribed, 0.0))) consumption_denom <- study_pop %>% group_by(calendar_year, calendar_month, main_specialty_code) %>% summarise(bed_days = sum(ramses_bed_days)) consumption_rates <- full_join(consumption_denom, consumption_num) %>% collect() %>% mutate(month_starting = as.Date(paste0(calendar_year, "/", calendar_month, "/01"))) head(consumption_rates)
ggplot(consumption_rates, aes(x = month_starting, y = DOT_prescribed/bed_days*1000, group = main_specialty_code, color = main_specialty_code)) + geom_line() + scale_x_date(date_labels = "%b %Y") + xlab("Month") + ylab("Days of Therapy (DOTs)\nper 1,000 bed-days")
Alternatively, consumption can be attributed to the episode when prescriptions are issued (authoring_date
field in drug_prescriptions
). In this case, the appropriate bridge table is bridge_episode_prescription_initiation
. This amounts to attributing antibiotic consumption to the initial prescriber.
consumption_num_init <- study_pop %>% left_join(tbl(ramses_db, "bridge_episode_prescription_initiation")) %>% group_by(calendar_year, calendar_month, main_specialty_code) %>% summarise(DOT_prescribed = sum(coalesce(DOT, 0.0)), DDD_prescribed = sum(coalesce(DDD_prescribed, 0.0))) consumption_denom_init <- study_pop %>% group_by(calendar_year, calendar_month, main_specialty_code) %>% summarise( bed_days = sum(ramses_bed_days), total_admissions = n_distinct(paste0(patient_id, encounter_id)) ) consumption_rates_init <- full_join(consumption_denom_init, consumption_num_init) %>% collect() %>% mutate(month_starting = as.Date(paste0(calendar_year, "/", calendar_month, "/01")))
ggplot(consumption_rates_init, aes(x = month_starting, y = DOT_prescribed/total_admissions*1000, group = main_specialty_code, color = main_specialty_code)) + geom_line() + scale_x_date(date_labels = "%b %Y") + xlab("Month") + ylab("Days of Therapy (DOTs)\nper 1,000 admissions")
Length of Therapy is the time elapsed during a prescribing episodes (sequence of antimicrobial prescriptions separated by at the most 36 hours by default). To measure it, the bridge table bridge_encounter_therapy_overlap
is available. It calculate the total LOT during between admission and discharge (excluding to-take-home medications).
length_therapy_by_encounter <- study_pop %>% distinct(patient_id, encounter_id, admission_method) %>% left_join(tbl(ramses_db, "bridge_encounter_therapy_overlap")) %>% group_by(patient_id, encounter_id, admission_method) %>% summarise(LOT = sum(LOT, na.rm = T)) %>% collect() length_therapy_by_encounter %>% group_by(admission_method) %>% summarise( `Total admissions` = n(), `Total admissions with therapy` = sum(!is.na(LOT)), `Mean LOT` = mean(LOT, na.rm = T), `Median LOT` = median(LOT, na.rm = T), percentile25 = quantile(x = LOT, probs = .25, na.rm = T), percentile75 = quantile(x = LOT, probs = .75, na.rm = T) ) %>% transmute( `Admission method` = case_when( admission_method == 1 ~ "Elective", admission_method == 2 ~ "Emergency"), `Total admissions`, `Mean LOT`, `Median LOT`, `Inter-quartile range` = paste0( formatC(percentile25, format = "f", digits = 1), "-", formatC(percentile75, format = "f", digits = 1) ) ) %>% knitr::kable(digits = 1)
To measure rates of prescribing by antibiotic class or AWaRe category, the query design is different because different dimensions are sought for the numerator and denominator.
Unlike before, this task takes three steps:
consumption_aware_episodes_num <- tbl(ramses_db, "drug_prescriptions") %>% select(patient_id, prescription_id, ATC_code, ATC_route) %>% left_join(tbl(ramses_db, "reference_aware"), by = c("ATC_code", "ATC_route")) %>% select(patient_id, prescription_id, aware_category) %>% left_join(tbl(ramses_db, "bridge_episode_prescription_overlap")) %>% inner_join(study_pop) %>% group_by(calendar_year, calendar_month, aware_category) %>% summarise(DOT_prescribed = sum(coalesce(DOT, 0.0))) consumption_aware_episodes_denom <- study_pop %>% group_by(calendar_year, calendar_month) %>% summarise(bed_days = sum(coalesce(ramses_bed_days, 0.0))) consumption_aware_episodes <- left_join( consumption_aware_episodes_denom, consumption_aware_episodes_num ) %>% collect() %>% mutate(month_starting = as.Date(paste0(calendar_year, "/", calendar_month, "/01")), aware_category = factor(aware_category, levels = c("Access", "Watch", "Reserve")))
aware_colours <- c( "Access" = "#1cb1d1", "Watch" = "#008ab1", "Reserve" = "#ff9667" ) ggplot(consumption_aware_episodes, aes(x = month_starting, y = DOT_prescribed/bed_days*1000, group = aware_category, color = aware_category)) + geom_line() + scale_x_date(date_labels = "%b %Y") + scale_color_manual(name = "AWaRe category", values = aware_colours) + xlab("Month") + ylab("Days of Therapy (DOTs)\nper 1,000 bed-days")
Always remember close database connections when you are finished.
DBI::dbDisconnect(ramses_db, shutdown = TRUE)
file.remove("ramses-db.duckdb")
# Do by Aware Rating next # rx_atc_codes <- tbl(ramses_db, "drug_prescriptions") %>% # select(prescription_id, ATC_code, ATC_route) # left_join(rx_atc_codes, by = "prescription_id") %>% # left_join(tbl(ramses_db, "reference_aware"), by = c("ATC_code", "ATC_route")) %>%
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.