diff --git a/DESCRIPTION b/DESCRIPTION index d959183a..7b2ccead 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,5 +1,5 @@ Package: AMR -Version: 1.2.0.9007 +Version: 1.2.0.9008 Date: 2020-06-17 Title: Antimicrobial Resistance Analysis Authors@R: c( diff --git a/NAMESPACE b/NAMESPACE index cd554d43..f67f79f0 100755 --- a/NAMESPACE +++ b/NAMESPACE @@ -64,6 +64,7 @@ export(ab_atc) export(ab_atc_group1) export(ab_atc_group2) export(ab_cid) +export(ab_class) export(ab_ddd) export(ab_group) export(ab_info) diff --git a/NEWS.md b/NEWS.md index 23bd33fb..a146eda0 100755 --- a/NEWS.md +++ b/NEWS.md @@ -1,4 +1,4 @@ -# AMR 1.2.0.9007 +# AMR 1.2.0.9008 ## Last updated: 17-Jun-2020 ### New @@ -13,17 +13,23 @@ tibble(J01CA01 = "S") %>% select(penicillins()) #> Selecting beta-lactams/penicillins: `J01CA01` (ampicillin) + + # select an antibiotic class manually with `ab_class()` + example_isolates %>% + select(ab_class("mycobact")) + #> Selecting antimycobacterials: `RIF` (rifampicin) ``` ### Changed * Fixed a bug where `eucast_rules()` would not work on a tibble when the `tibble` or `dplyr` package was loaded -* All `*_join_microorganisms()` functions now return the original data class (e.g. tibbles and data.tables) +* All `*_join_microorganisms()` functions and `bug_drug_combinations()` now return the original data class (e.g. `tibble`s and `data.table`s) * Fixed a bug where `as.ab()` would return an error on invalid input values * Fixed a bug for using grouped versions of `rsi_df()`, `proportion_df()` and `count_df()`, and fixed a bug where not all different antimicrobial results were added as rows * Added function `filter_penicillins()` to filter isolates on a specific result in any column with a name in the antimicrobial 'penicillins' class (more specific: ATC subgroup *Beta-lactam antibacterials, penicillins*) * Added official antimicrobial names to all `filter_ab_class()` functions, such as `filter_aminoglycosides()` * Added antibiotics code "FOX1" for cefoxitin screening (abbreviation "cfsc") to the `antibiotics` data set * Improved auto-determination for columns of types `` and `` +* Fixed a bug in `bug_drug_combinations()` for when only one antibiotic was in the input data # AMR 1.2.0 diff --git a/R/aa_helper_functions.R b/R/aa_helper_functions.R index b947fd77..64cf2817 100755 --- a/R/aa_helper_functions.R +++ b/R/aa_helper_functions.R @@ -63,14 +63,12 @@ filter_join_worker <- function(x, y, by = NULL, type = c("anti", "semi")) { # No export, no Rd addin_insert_in <- function() { - stopifnot_installed_package("rstudioapi") - get("insertText", envir = asNamespace("rstudioapi"))(" %in% ") + import_fn("insertText", "rstudioapi")(" %in% ") } # No export, no Rd addin_insert_like <- function() { - stopifnot_installed_package("rstudioapi") - get("insertText", envir = asNamespace("rstudioapi"))(" %like% ") + import_fn("insertText", "rstudioapi")(" %like% ") } check_dataset_integrity <- function() { @@ -186,12 +184,23 @@ stopifnot_installed_package <- function(package) { # https://developer.r-project.org/Blog/public/2019/02/14/staged-install/index.html sapply(package, function(x) tryCatch(get(".packageName", envir = asNamespace(x)), - error = function(e) stop("package '", x, "' required but not installed.", - "\nTry to install it with: install.packages(\"", x, "\")", - call. = FALSE))) + error = function(e) { + if (package == "rstudioapi") { + stop("This function only works in RStudio.", call. = FALSE) + } else { + stop("package '", x, "' required but not installed.", + "\nTry to install it with: install.packages(\"", x, "\")", + call. = FALSE) + } + })) return(invisible()) } +import_fn <- function(name, pkg) { + stopifnot_installed_package(pkg) + get(name, envir = asNamespace(pkg)) +} + stopifnot_msg <- function(expr, msg) { if (!isTRUE(expr)) { stop(msg, call. = FALSE) @@ -245,7 +254,7 @@ dataset_UTF8_to_ASCII <- function(df) { df } -has_colour <- function () { +has_colour <- function() { # this is a base R version of crayon::has_color enabled <- getOption("crayon.enabled") if (!is.null(enabled)) { @@ -276,7 +285,7 @@ has_colour <- function () { } return(FALSE) } - emacs_version <- function () { + emacs_version <- function() { ver <- Sys.getenv("INSIDE_EMACS") if (ver == "") { return(NA_integer_) diff --git a/R/ab_class_selectors.R b/R/ab_class_selectors.R index e1c65f0e..b60f66c6 100644 --- a/R/ab_class_selectors.R +++ b/R/ab_class_selectors.R @@ -22,6 +22,7 @@ #' Antibiotic class selectors #' #' Use these selection helpers inside any function that allows [Tidyverse selections](https://tidyselect.r-lib.org/reference/language.html), like `dplyr::select()` or `tidyr::pivot_longer()`. They help to select the columns of antibiotics that are of a specific antibiotic class, without the need to define the columns or antibiotic abbreviations. +#' @inheritParams filter_ab_class #' @details All columns will be searched for known antibiotic names, abbreviations, brand names and codes (ATC, EARS-Net, WHO, etc.). This means that a selector like e.g. [aminoglycosides()] will pick up column names like 'gen', 'genta', 'J01GB03', 'tobra', 'Tobracin', etc. #' #' These functions only work if the `tidyselect` package is installed, that comes with the `dplyr` package. An error will be thrown if `tidyselect` package is not installed, or if the functions are used outside a function that allows Tidyverse selections like `select()` or `pivot_longer()`. @@ -36,119 +37,138 @@ #' example_isolates %>% #' select(carbapenems()) #' -#' #' # this will select columns 'mo', 'AMK', 'GEN', 'KAN' and 'TOB': #' example_isolates %>% #' select(mo, aminoglycosides()) #' +#' # this will select columns 'mo' and all antimycobacterial drugs ('RIF'): +#' example_isolates %>% +#' select(mo, ab_class("mycobact")) +#' +#' +#' # get bug/drug combinations for only macrolides in Gram-positives: +#' example_isolates %>% +#' filter(mo_gramstain(mo) %like% "pos") %>% +#' select(mo, macrolides()) %>% +#' bug_drug_combinations() %>% +#' format() +#' #' #' data.frame(irrelevant = "value", #' J01CA01 = "S") %>% # ATC code of ampicillin #' select(penicillins()) # so the 'J01CA01' column is selected -#' +#' #' } +ab_class <- function(ab_class) { + ab_selector(ab_class, function_name = "ab_class") +} + +#' @rdname antibiotic_class_selectors +#' @export aminoglycosides <- function() { - ab_selector("aminoglycoside") + ab_selector("aminoglycoside", function_name = "aminoglycosides") } #' @rdname antibiotic_class_selectors #' @export carbapenems <- function() { - ab_selector("carbapenem") + ab_selector("carbapenem", function_name = "carbapenems") } #' @rdname antibiotic_class_selectors #' @export cephalosporins <- function() { - ab_selector("cephalosporin") + ab_selector("cephalosporin", function_name = "cephalosporins") } #' @rdname antibiotic_class_selectors #' @export cephalosporins_1st <- function() { - ab_selector("cephalosporins.*1") + ab_selector("cephalosporins.*1", function_name = "cephalosporins_1st") } #' @rdname antibiotic_class_selectors #' @export cephalosporins_2nd <- function() { - ab_selector("cephalosporins.*2") + ab_selector("cephalosporins.*2", function_name = "cephalosporins_2nd") } #' @rdname antibiotic_class_selectors #' @export cephalosporins_3rd <- function() { - ab_selector("cephalosporins.*3") + ab_selector("cephalosporins.*3", function_name = "cephalosporins_3rd") } #' @rdname antibiotic_class_selectors #' @export cephalosporins_4th <- function() { - ab_selector("cephalosporins.*4") + ab_selector("cephalosporins.*4", function_name = "cephalosporins_4th") } #' @rdname antibiotic_class_selectors #' @export cephalosporins_5th <- function() { - ab_selector("cephalosporins.*5") + ab_selector("cephalosporins.*5", function_name = "cephalosporins_5th") } #' @rdname antibiotic_class_selectors #' @export fluoroquinolones <- function() { - ab_selector("fluoroquinolone") + ab_selector("fluoroquinolone", function_name = "fluoroquinolones") } #' @rdname antibiotic_class_selectors #' @export glycopeptides <- function() { - ab_selector("glycopeptide") + ab_selector("glycopeptide", function_name = "glycopeptides") } #' @rdname antibiotic_class_selectors #' @export macrolides <- function() { - ab_selector("macrolide") + ab_selector("macrolide", function_name = "macrolides") } #' @rdname antibiotic_class_selectors #' @export penicillins <- function() { - ab_selector("penicillin") + ab_selector("penicillin", function_name = "penicillins") } #' @rdname antibiotic_class_selectors #' @export tetracyclines <- function() { - ab_selector("tetracycline") + ab_selector("tetracycline", function_name = "tetracyclines") } -ab_selector <- function(ab_class, vars = NULL) { - - stopifnot_installed_package("tidyselect") - peek_vars_tidyselect <- get("peek_vars", envir = asNamespace("tidyselect")) - - vars_vct <- peek_vars_tidyselect(fn = ab_class) +ab_selector <- function(ab_class, function_name) { + peek_vars_tidyselect <- import_fn("peek_vars", "tidyselect") + vars_vct <- peek_vars_tidyselect(fn = function_name) vars_df <- data.frame(as.list(vars_vct))[0, , drop = FALSE] colnames(vars_df) <- vars_vct ab_in_data <- suppressMessages(get_column_abx(vars_df)) - + if (length(ab_in_data) == 0) { message(font_blue("NOTE: no antimicrobial agents found.")) return(NULL) } - + ab_reference <- subset(antibiotics, group %like% ab_class | atc_group1 %like% ab_class | atc_group2 %like% ab_class) ab_group <- find_ab_group(ab_class) + if (ab_group == "") { + ab_group <- paste0("'", ab_class, "'") + examples <- "" + } else { + examples <- paste0(" (such as ", find_ab_names(ab_class, 2), ")") + } # get the columns with a group names in the chosen ab class agents <- ab_in_data[names(ab_in_data) %in% ab_reference$ab] if (length(agents) == 0) { - message(font_blue(paste0("NOTE: no antimicrobial agents of class ", ab_group, - " found (such as ", find_ab_names(ab_class, 2), - ")."))) + message(font_blue(paste0("NOTE: No antimicrobial agents of class ", ab_group, + " found", examples, "."))) } else { message(font_blue(paste0("Selecting ", ab_group, ": ", paste(paste0("`", font_bold(agents, collapse = NULL), diff --git a/R/atc_online.R b/R/atc_online.R index dac70119..a534104b 100644 --- a/R/atc_online.R +++ b/R/atc_online.R @@ -76,15 +76,14 @@ atc_online_property <- function(atc_code, administration = "O", url = "https://www.whocc.no/atc_ddd_index/?code=%s&showdescription=no") { - stopifnot_installed_package(c("curl", "rvest", "xml2")) - has_internet <- get("has_internet", envir = asNamespace("curl")) - html_attr <- get("html_attr", envir = asNamespace("rvest")) - html_children <- get("html_children", envir = asNamespace("rvest")) - html_node <- get("html_node", envir = asNamespace("rvest")) - html_nodes <- get("html_nodes", envir = asNamespace("rvest")) - html_table <- get("html_table", envir = asNamespace("rvest")) - html_text <- get("html_text", envir = asNamespace("rvest")) - read_html <- get("read_html", envir = asNamespace("xml2")) + has_internet <- import_fn("has_internet", "curl") + html_attr <- import_fn("html_attr", "rvest") + html_children <- import_fn("html_children", "rvest") + html_node <- import_fn("html_node", "rvest") + html_nodes <- import_fn("html_nodes", "rvest") + html_table <- import_fn("html_table", "rvest") + html_text <- import_fn("html_text", "rvest") + read_html <- import_fn("read_html", "xml2") check_dataset_integrity() diff --git a/R/bug_drug_combinations.R b/R/bug_drug_combinations.R index da731829..0ca22df9 100644 --- a/R/bug_drug_combinations.R +++ b/R/bug_drug_combinations.R @@ -62,6 +62,9 @@ bug_drug_combinations <- function(x, if (!is.data.frame(x)) { stop("`x` must be a data frame.", call. = FALSE) } + if (!any(sapply(x, is.rsi), na.rm = TRUE)) { + stop("No columns with class found. See ?as.rsi.", call. = FALSE) + } # try to find columns based on type # -- mo @@ -72,12 +75,13 @@ bug_drug_combinations <- function(x, stop("`col_mo` must be set.", call. = FALSE) } + x_class <- class(x) x <- as.data.frame(x, stringsAsFactors = FALSE) x[, col_mo] <- FUN(x[, col_mo, drop = TRUE]) - x <- x[, c(col_mo, names(which(sapply(x, is.rsi))))] + x <- x[, c(col_mo, names(which(sapply(x, is.rsi)))), drop = FALSE] unique_mo <- sort(unique(x[, col_mo, drop = TRUE])) - + out <- data.frame( mo = character(0), ab = character(0), @@ -85,10 +89,10 @@ bug_drug_combinations <- function(x, I = integer(0), R = integer(0), total = integer(0)) - + for (i in seq_len(length(unique_mo))) { # filter on MO group and only select R/SI columns - x_mo_filter <- x[which(x[, col_mo, drop = TRUE] == unique_mo[i]), names(which(sapply(x, is.rsi)))] + x_mo_filter <- x[which(x[, col_mo, drop = TRUE] == unique_mo[i]), names(which(sapply(x, is.rsi))), drop = FALSE] # turn and merge everything pivot <- lapply(x_mo_filter, function(x) { m <- as.matrix(table(x)) @@ -103,8 +107,8 @@ bug_drug_combinations <- function(x, total = merged$S + merged$I + merged$R) out <- rbind(out, out_group) } - - structure(.Data = out, class = c("bug_drug_combinations", class(x))) + + structure(.Data = out, class = c("bug_drug_combinations", x_class)) } #' @method format bug_drug_combinations @@ -121,6 +125,7 @@ format.bug_drug_combinations <- function(x, decimal.mark = getOption("OutDec"), big.mark = ifelse(decimal.mark == ",", ".", ","), ...) { + x <- as.data.frame(x, stringsAsFactors = FALSE) x <- subset(x, total >= minimum) if (remove_intrinsic_resistant == TRUE) { @@ -221,6 +226,8 @@ format.bug_drug_combinations <- function(x, #' @method print bug_drug_combinations #' @export print.bug_drug_combinations <- function(x, ...) { - print(as.data.frame(x, stringsAsFactors = FALSE)) - message(font_blue("NOTE: Use 'format()' on this result to get a publicable/printable format.")) + x_class <- class(x) + print(structure(x, class = x_class[x_class != "bug_drug_combinations"]), + ...) + message(font_blue("NOTE: Use 'format()' on this result to get a publishable/printable format.")) } diff --git a/R/eucast_rules.R b/R/eucast_rules.R index 713e87a3..2cff1179 100755 --- a/R/eucast_rules.R +++ b/R/eucast_rules.R @@ -206,7 +206,7 @@ eucast_rules <- function(x, "\n\nThis may overwrite your existing data if you use e.g.:", "\ndata <- eucast_rules(data, verbose = TRUE)\n\nDo you want to continue?") if ("rstudioapi" %in% rownames(utils::installed.packages())) { - showQuestion <- get("showQuestion", envir = asNamespace("rstudioapi")) + showQuestion <- import_fn("showQuestion", "rstudioapi") q_continue <- showQuestion("Using verbose = TRUE with eucast_rules()", txt) } else { q_continue <- utils::menu(choices = c("OK", "Cancel"), graphics = FALSE, title = txt) diff --git a/R/lifecycle.R b/R/lifecycle.R index bf887b78..b0767b07 100644 --- a/R/lifecycle.R +++ b/R/lifecycle.R @@ -26,10 +26,10 @@ #' Lifecycles of functions in the `AMR` package #' @name lifecycle #' @rdname lifecycle -#' @description Functions in this `AMR` package are categorised using [the lifecycle circle of the `tidyverse` as found on www.tidyverse.org/lifecycle](https://www.tidyverse.org/lifecycle). +#' @description Functions in this `AMR` package are categorised using [the lifecycle circle of the Tidyverse as found on www.tidyverse.org/lifecycle](https://www.Tidyverse.org/lifecycle). #' -#' \if{html}{\figure{lifecycle_tidyverse.svg}{options: height=200px style=margin-bottom:5px} \cr} -#' This page contains a section for every lifecycle (with text borrowed from the aforementioned `tidyverse` website), so they can be used in the manual pages of the functions. +#' \if{html}{\figure{lifecycle_Tidyverse.svg}{options: height=200px style=margin-bottom:5px} \cr} +#' This page contains a section for every lifecycle (with text borrowed from the aforementioned Tidyverse website), so they can be used in the manual pages of the functions. #' @section Experimental lifecycle: #' \if{html}{\figure{lifecycle_experimental.svg}{options: style=margin-bottom:5px} \cr} #' The [lifecycle][AMR::lifecycle] of this function is **experimental**. An experimental function is in early stages of development. The unlying code might be changing frequently. Experimental functions might be removed without deprecation, so you are generally best off waiting until a function is more mature before you use it in production code. Experimental functions are only available in development versions of this `AMR` package and will thus not be included in releases that are submitted to CRAN, since such functions have not yet matured enough. diff --git a/R/mdro.R b/R/mdro.R index b515687e..70be8608 100755 --- a/R/mdro.R +++ b/R/mdro.R @@ -95,7 +95,7 @@ mdro <- function(x, "\n\nThis may overwrite your existing data if you use e.g.:", "\ndata <- mdro(data, verbose = TRUE)\n\nDo you want to continue?") if ("rstudioapi" %in% rownames(utils::installed.packages())) { - showQuestion <- get("showQuestion", envir = asNamespace("rstudioapi")) + showQuestion <- import_fn("showQuestion", "rstudioapi") q_continue <- showQuestion("Using verbose = TRUE with mdro()", txt) } else { q_continue <- utils::menu(choices = c("OK", "Cancel"), graphics = FALSE, title = txt) diff --git a/R/mo.R b/R/mo.R index fc6594bf..a1ed429b 100755 --- a/R/mo.R +++ b/R/mo.R @@ -152,7 +152,7 @@ #' \dontrun{ #' df$mo <- as.mo(df$microorganism_name) #' -#' # the select function of tidyverse is also supported: +#' # the select function of the Tidyverse is also supported: #' library(dplyr) #' df$mo <- df %>% #' select(microorganism_name) %>% @@ -1805,13 +1805,13 @@ parse_and_convert <- function(x) { if (NCOL(x) > 2) { stop("A maximum of two columns is allowed.", call. = FALSE) } else if (NCOL(x) == 2) { - # support tidyverse selection like: df %>% select(colA, colB) + # support Tidyverse selection like: df %>% select(colA, colB) # paste these columns together x <- as.data.frame(x, stringsAsFactors = FALSE) colnames(x) <- c("A", "B") x <- paste(x$A, x$B) } else { - # support tidyverse selection like: df %>% select(colA) + # support Tidyverse selection like: df %>% select(colA) x <- as.data.frame(x, stringsAsFactors = FALSE)[[1]] } } diff --git a/R/mo_source.R b/R/mo_source.R index 611b7524..fbcd0e1d 100644 --- a/R/mo_source.R +++ b/R/mo_source.R @@ -135,8 +135,7 @@ set_mo_source <- function(path) { } else if (path %like% "[.]xlsx?$") { # is Excel file (old or new) - stopifnot_installed_package("readxl") - read_excel <- get("read_excel", envir = asNamespace("readxl")) + read_excel <- import_fn("read_excel", "readxl") df <- read_excel(path) } else if (path %like% "[.]tsv$") { diff --git a/R/proportion.R b/R/proportion.R index 04547902..3bae3a7a 100755 --- a/R/proportion.R +++ b/R/proportion.R @@ -40,7 +40,7 @@ #' #' **Remember that you should filter your table to let it contain only first isolates!** This is needed to exclude duplicates and to reduce selection bias. Use [first_isolate()] to determine them in your data set. #' -#' These functions are not meant to count isolates, but to calculate the proportion of resistance/susceptibility. Use the `count()`][AMR::count()] functions to count isolates. The function [susceptibility()] is essentially equal to `count_susceptible() / count_all()`. *Low counts can influence the outcome - the `proportion` functions may camouflage this, since they only return the proportion (albeit being dependent on the `minimum` parameter).* +#' These functions are not meant to count isolates, but to calculate the proportion of resistance/susceptibility. Use the [`count()`][AMR::count()] functions to count isolates. The function [susceptibility()] is essentially equal to `count_susceptible() / count_all()`. *Low counts can influence the outcome - the `proportion` functions may camouflage this, since they only return the proportion (albeit being dependent on the `minimum` parameter).* #' #' The function [proportion_df()] takes any variable from `data` that has an [`rsi`] class (created with [as.rsi()]) and calculates the proportions R, I and S. It also supports grouped variables. The function [rsi_df()] works exactly like [proportion_df()], but adds the number of isolates. #' @section Combination therapy: diff --git a/R/resistance_predict.R b/R/resistance_predict.R index d121836a..c754b292 100755 --- a/R/resistance_predict.R +++ b/R/resistance_predict.R @@ -316,9 +316,9 @@ plot.resistance_predict <- function(x, main = paste("Resistance Prediction of", } # get plot() generic; this was moved from the 'graphics' pkg to the 'base' pkg in R 4.0.0 if (as.integer(R.Version()$major) >= 4) { - plot <- get("plot", envir = asNamespace("base")) + plot <- import_fn("plot", "base") } else { - plot <- get("plot", envir = asNamespace("graphics")) + plot <- import_fn("plot", "graphics") } plot(x = x$year, y = x$value, diff --git a/R/rsi.R b/R/rsi.R index 35cd711a..6cbd4c91 100755 --- a/R/rsi.R +++ b/R/rsi.R @@ -594,9 +594,9 @@ plot.rsi <- function(x, # get plot() generic; this was moved from the 'graphics' pkg to the 'base' pkg in R 4.0.0 if (as.integer(R.Version()$major) >= 4) { - plot <- get("plot", envir = asNamespace("base")) + plot <- import_fn("plot", "base") } else { - plot <- get("plot", envir = asNamespace("graphics")) + plot <- import_fn("plot", "graphics") } plot(x = data$x, y = data$s, diff --git a/docs/404.html b/docs/404.html index b5cae315..ae57627a 100644 --- a/docs/404.html +++ b/docs/404.html @@ -81,7 +81,7 @@ AMR (for R) - 1.2.0.9007 + 1.2.0.9008 diff --git a/docs/LICENSE-text.html b/docs/LICENSE-text.html index 00f0bec5..c07ef543 100644 --- a/docs/LICENSE-text.html +++ b/docs/LICENSE-text.html @@ -81,7 +81,7 @@ AMR (for R) - 1.2.0.9007 + 1.2.0.9008 diff --git a/docs/articles/AMR.html b/docs/articles/AMR.html index 7fbe2425..0765d4b7 100644 --- a/docs/articles/AMR.html +++ b/docs/articles/AMR.html @@ -39,7 +39,7 @@ AMR (for R) - 1.2.0 + 1.2.0.9008 @@ -186,7 +186,7 @@

How to conduct AMR analysis

Matthijs S. Berends

-

28 May 2020

+

17 June 2020

Source: vignettes/AMR.Rmd @@ -195,7 +195,7 @@ -

Note: values on this page will change with every website update since they are based on randomly created values and the page was written in R Markdown. However, the methodology remains unchanged. This page was generated on 28 May 2020.

+

Note: values on this page will change with every website update since they are based on randomly created values and the page was written in R Markdown. However, the methodology remains unchanged. This page was generated on 17 June 2020.

Introduction

@@ -226,21 +226,21 @@ -2020-05-28 +2020-06-17 abcd Escherichia coli S S -2020-05-28 +2020-06-17 abcd Escherichia coli S R -2020-05-28 +2020-06-17 efgh Escherichia coli R @@ -302,24 +302,24 @@

Put everything together

-

Using the sample() function, we can randomly select items from all objects we defined earlier. To let our fake data reflect reality a bit, we will also approximately define the probabilities of bacteria and the antibiotic results with the prob parameter.

+

Using the sample() function, we can randomly select items from all objects we defined earlier. To let our fake data reflect reality a bit, we will also approximately define the probabilities of bacteria and the antibiotic results with the prob parameter.

sample_size <- 20000
-data <- data.frame(date = sample(dates, size = sample_size, replace = TRUE),
-                   patient_id = sample(patients, size = sample_size, replace = TRUE),
-                   hospital = sample(hospitals, size = sample_size, replace = TRUE,
+data <- data.frame(date = sample(dates, size = sample_size, replace = TRUE),
+                   patient_id = sample(patients, size = sample_size, replace = TRUE),
+                   hospital = sample(hospitals, size = sample_size, replace = TRUE,
                                      prob = c(0.30, 0.35, 0.15, 0.20)),
-                   bacteria = sample(bacteria, size = sample_size, replace = TRUE,
+                   bacteria = sample(bacteria, size = sample_size, replace = TRUE,
                                      prob = c(0.50, 0.25, 0.15, 0.10)),
-                   AMX = sample(ab_interpretations, size = sample_size, replace = TRUE,
+                   AMX = sample(ab_interpretations, size = sample_size, replace = TRUE,
                                  prob = c(0.60, 0.05, 0.35)),
-                   AMC = sample(ab_interpretations, size = sample_size, replace = TRUE,
+                   AMC = sample(ab_interpretations, size = sample_size, replace = TRUE,
                                  prob = c(0.75, 0.10, 0.15)),
-                   CIP = sample(ab_interpretations, size = sample_size, replace = TRUE,
+                   CIP = sample(ab_interpretations, size = sample_size, replace = TRUE,
                                  prob = c(0.80, 0.00, 0.20)),
-                   GEN = sample(ab_interpretations, size = sample_size, replace = TRUE,
+                   GEN = sample(ab_interpretations, size = sample_size, replace = TRUE,
                                  prob = c(0.92, 0.00, 0.08)))
-

Using the left_join() function from the dplyr package, we can ‘map’ the gender to the patient ID using the patients_table object we created earlier:

-
data <- data %>% left_join(patients_table)
+

Using the left_join() function from the dplyr package, we can ‘map’ the gender to the patient ID using the patients_table object we created earlier:

+
data <- data %>% left_join(patients_table)

The resulting data set contains 20,000 blood culture isolates. With the head() function we can preview the first 6 rows of this data set:

head(data)
@@ -336,10 +336,10 @@ - - + + - + @@ -347,32 +347,10 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + @@ -380,23 +358,45 @@ - - + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + - - - - - - + + + + + + @@ -432,16 +432,16 @@ Longest: 1

- - - - + + + + - - + + @@ -456,7 +456,7 @@ Longest: 1

mutate_at(vars(AMX:GEN), as.rsi)

Finally, we will apply EUCAST rules on our antimicrobial results. In Europe, most medical microbiological laboratories already apply these rules. Our package features their latest insights on intrinsic resistance and exceptional phenotypes. Moreover, the eucast_rules() function can also apply additional rules, like forcing ampicillin = R when amoxicillin/clavulanic acid = R.

Because the amoxicillin (column AMX) and amoxicillin/clavulanic acid (column AMC) in our data were generated randomly, some rows will undoubtedly contain AMX = S and AMC = R, which is technically impossible. The eucast_rules() fixes this:

-
data <- eucast_rules(data, col_mo = "bacteria")
+
data <- eucast_rules(data, col_mo = "bacteria", rules = "all")

@@ -481,7 +481,7 @@ Longest: 1

# NOTE: Using column `bacteria` as input for `col_mo`. # NOTE: Using column `date` as input for `col_date`. # NOTE: Using column `patient_id` as input for `col_patient_id`.

-

So only 28.5% is suitable for resistance analysis! We can now filter on it with the filter() function, also from the dplyr package:

+

So only 28.2% is suitable for resistance analysis! We can now filter on it with the filter() function, also from the dplyr package:

data_1st <- data %>%
   filter(first == TRUE)

For future use, the above two syntaxes can be shortened with the filter_first_isolate() function:

@@ -491,7 +491,7 @@ Longest: 1

First weighted isolates

-

We made a slight twist to the CLSI algorithm, to take into account the antimicrobial susceptibility profile. Have a look at all isolates of patient U2, sorted on date:

+

We made a slight twist to the CLSI algorithm, to take into account the antimicrobial susceptibility profile. Have a look at all isolates of patient A2, sorted on date:

2013-12-18P102014-09-10V9 Hospital AEscherichia coliStreptococcus pneumoniae R S SF
2010-07-10K6Hospital CEscherichia coliSSSSM
2014-12-14F6Hospital CEscherichia coliSSSSM
2010-12-31N8Hospital DEscherichia coli2011-09-21Y7Hospital BStreptococcus pneumoniae S S SF
2010-11-24M52014-05-27U4Hospital BKlebsiella pneumoniaeSSSSF
2013-01-03I8 Hospital B Escherichia coliSSSRRR S M
2011-06-08K4Hospital BStreptococcus pneumoniaeSSSRM
2010-10-07Z8Hospital CEscherichia coliRR2017-09-29T5Hospital AStaphylococcus aureusSI S S F
1 M10,39751.99%10,39751.99%10,31951.60%10,31951.60%
2 F9,60348.02%9,68148.41% 20,000 100.00%
@@ -507,8 +507,8 @@ Longest: 1

- - + + @@ -518,10 +518,10 @@ Longest: 1

- - + + - + @@ -529,19 +529,19 @@ Longest: 1

- - + + + + + - - - - - + + @@ -551,10 +551,10 @@ Longest: 1

- - + + - + @@ -562,52 +562,52 @@ Longest: 1

- - + + - - - - - - - - - - - + + + + + + + + + + + - - + + - + - - + + - - + + - - + + @@ -643,8 +643,8 @@ Longest: 1

- - + + @@ -655,32 +655,32 @@ Longest: 1

- - + + - + - + - - + + + + + - - - - + - - + + @@ -691,47 +691,47 @@ Longest: 1

- - + + - + - + - - + + - - - + + + - - + + - - - + + + - - + + - + @@ -739,35 +739,35 @@ Longest: 1

- - + + - - + + - - + + - +
isolate
12010-03-30U22010-02-14A2 B_ESCHR_COLI R S
22010-07-30U22010-03-19A2 B_ESCHR_COLIRS S S S
32010-10-14U22010-08-09A2 B_ESCHR_COLISSS RSSS FALSE
42010-12-17U22010-12-29A2 B_ESCHR_COLI S S
52011-02-17U22011-02-03A2 B_ESCHR_COLIRS S S S
62011-03-17U22011-04-15A2 B_ESCHR_COLII S S SFALSE
72011-06-10U2B_ESCHR_COLIRSS S TRUE
72011-04-22A2B_ESCHR_COLISSSSFALSE
82011-07-17U22011-06-10A2 B_ESCHR_COLI RSR S R FALSE
92011-08-08U22011-07-20A2 B_ESCHR_COLIIS R SSS FALSE
102011-08-21U22011-08-06A2 B_ESCHR_COLI S S
12010-03-30U22010-02-14A2 B_ESCHR_COLI R S
22010-07-30U22010-03-19A2 B_ESCHR_COLIRS S S S FALSEFALSETRUE
32010-10-14U22010-08-09A2 B_ESCHR_COLISSS RSSSFALSE FALSETRUE
42010-12-17U22010-12-29A2 B_ESCHR_COLI S S
52011-02-17U22011-02-03A2 B_ESCHR_COLIRS S S S FALSETRUEFALSE
62011-03-17U22011-04-15A2 B_ESCHR_COLII S S SFALSEFALSESTRUETRUE
72011-06-10U22011-04-22A2 B_ESCHR_COLIR S S STRUETRUESFALSEFALSE
82011-07-17U22011-06-10A2 B_ESCHR_COLI RSR S R FALSE
92011-08-08U22011-07-20A2 B_ESCHR_COLIIS R SSS FALSE TRUE
102011-08-21U22011-08-06A2 B_ESCHR_COLI S S R S FALSEFALSETRUE
-

Instead of 2, now 6 isolates are flagged. In total, 78.7% of all isolates are marked ‘first weighted’ - 50.2% more than when using the CLSI guideline. In real life, this novel algorithm will yield 5-10% more isolates than the classic CLSI guideline.

+

Instead of 2, now 8 isolates are flagged. In total, 78.6% of all isolates are marked ‘first weighted’ - 50.4% more than when using the CLSI guideline. In real life, this novel algorithm will yield 5-10% more isolates than the classic CLSI guideline.

As with filter_first_isolate(), there’s a shortcut for this new algorithm too:

data_1st <- data %>%
   filter_first_weighted_isolate()
-

So we end up with 15,741 isolates for analysis.

+

So we end up with 15,719 isolates for analysis.

We can remove unneeded columns:

data_1st <- data_1st %>%
   select(-c(first, keyab))
@@ -775,6 +775,7 @@ Longest: 1

head(data_1st)
+ @@ -791,73 +792,46 @@ Longest: 1

- - + + + - + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - - - + + + @@ -866,20 +840,53 @@ Longest: 1

- - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
date patient_id hospital
2013-12-18P1012014-09-10V9 Hospital AB_ESCHR_COLIB_STRPT_PNMNRRSRFGram-positiveStreptococcuspneumoniaeTRUE
32014-05-27U4Hospital BB_KLBSL_PNMN R S S S F Gram-negativeEscherichiacoliTRUE
2010-07-10K6Hospital CB_ESCHR_COLISSSSMGram-negativeEscherichiacoliKlebsiellapneumoniae TRUE
2014-12-14F6Hospital CB_ESCHR_COLISSSSMGram-negativeEscherichiacoliTRUE
2010-12-31N8Hospital DB_ESCHR_COLISSSSFGram-negativeEscherichiacoliTRUE
2010-11-24M542013-01-03I8 Hospital B B_ESCHR_COLISSSRRR S M Gram-negative TRUE
2010-10-07Z8Hospital CB_ESCHR_COLIRR62017-09-29T5Hospital AB_STPHY_AURSSS S S FGram-positiveStaphylococcusaureusTRUE
82012-07-08B2Hospital BB_ESCHR_COLIRSSRM Gram-negative Escherichia coli TRUE
92014-01-07G7Hospital AB_STRPT_PNMNRRRRMGram-positiveStreptococcuspneumoniaeTRUE

Time for the analysis!

@@ -899,8 +906,8 @@ Longest: 1

data_1st %>% freq(genus, species)

Frequency table

Class: character
-Length: 15,741
-Available: 15,741 (100%, NA: 0 = 0%)
+Length: 15,719
+Available: 15,719 (100%, NA: 0 = 0%)
Unique: 4

Shortest: 16
Longest: 24

@@ -917,49 +924,170 @@ Longest: 24

1 Escherichia coli -7,943 -50.46% -7,943 -50.46% +7,906 +50.30% +7,906 +50.30% 2 Staphylococcus aureus -3,978 -25.27% -11,921 -75.73% +3,898 +24.80% +11,804 +75.09% 3 Streptococcus pneumoniae -2,248 -14.28% -14,169 -90.01% +2,330 +14.82% +14,134 +89.92% 4 Klebsiella pneumoniae -1,572 -9.99% -15,741 +1,585 +10.08% +15,719 100.00%
+
+

+Overview of different bug/drug combinations

+

If you want to get a quick glance of the number of isolates in different bug/drug combinations, you can use the bug_drug_combinations() function:

+
data_1st %>%
+  bug_drug_combinations() %>%
+  head() # show first 6 rows
+
# NOTE: Using column `bacteria` as input for `col_mo`.
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
moabSIRtotal
E. coliAMX378424438787906
E. coliAMC625227413807906
E. coliCIP6028018787906
E. coliGEN717607307906
K. pneumoniaeAMX0015851585
K. pneumoniaeAMC1241602841585
+

Using Tidyverse selections, you can also select columns based on the antibiotic class they are in:

+
data_1st %>%
+  select(bacteria, fluoroquinolones()) %>%
+  bug_drug_combinations()
+
# Selecting fluoroquinolones: `CIP` (ciprofloxacin)
+# NOTE: Using column `bacteria` as input for `col_mo`.
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
moabSIRtotal
E. coliCIP6028018787906
K. pneumoniaeCIP122303621585
S. aureusCIP296109373898
S. pneumoniaeCIP177705532330
+

This will only give you the crude numbers in the data. To calculate antimicrobial resistance, we use the resistance() and susceptibility() functions.

+

Resistance percentages

The functions resistance() and susceptibility() can be used to calculate antimicrobial resistance or susceptibility. For more specific analyses, the functions proportion_S(), proportion_SI(), proportion_I(), proportion_IR() and proportion_R() can be used to determine the proportion of a specific antimicrobial outcome.

As per the EUCAST guideline of 2019, we calculate resistance as the proportion of R (proportion_R(), equal to resistance()) and susceptibility as the proportion of S and I (proportion_SI(), equal to susceptibility()). These functions can be used on their own:

-
data_1st %>% resistance(AMX)
-# [1] 0.4476209
+
data_1st %>% resistance(AMX)
+# [1] 0.5382022

Or can be used in conjuction with group_by() and summarise(), both from the dplyr package:

-
data_1st %>%
+
data_1st %>%
   group_by(hospital) %>%
   summarise(amoxicillin = resistance(AMX))
+
# `summarise()` ungrouping output (override with `.groups` argument)
@@ -968,27 +1096,28 @@ Longest: 24

- + - + - + - +
hospital
Hospital A0.44027300.5410830
Hospital B0.46076090.5318994
Hospital C0.44375260.5342585
Hospital D0.43896350.5477099

Of course it would be very convenient to know the number of isolates responsible for the percentages. For that purpose the n_rsi() can be used, which works exactly like n_distinct() from the dplyr package. It counts all isolates available for every group (i.e. values S, I or R):

-
data_1st %>%
+
data_1st %>%
   group_by(hospital) %>%
   summarise(amoxicillin = resistance(AMX),
             available = n_rsi(AMX))
+
# `summarise()` ungrouping output (override with `.groups` argument)
@@ -998,32 +1127,33 @@ Longest: 24

- - + + - - + + - - + + - - + +
hospital
Hospital A0.440273046880.54108304783
Hospital B0.460760954410.53189945486
Hospital C0.443752624090.53425852306
Hospital D0.438963532030.54770993144

These functions can also be used to get the proportion of multiple antibiotics, to calculate empiric susceptibility of combination therapies very easily:

-
data_1st %>%
+
data_1st %>%
   group_by(genus) %>%
   summarise(amoxiclav = susceptibility(AMC),
             gentamicin = susceptibility(GEN),
             amoxiclav_genta = susceptibility(AMC, GEN))
+
# `summarise()` ungrouping output (override with `.groups` argument)
@@ -1034,32 +1164,32 @@ Longest: 24

- - - + + + - - - + + + - - - + + + - + - +
genus
Escherichia0.82966130.89928240.98627720.82544900.90766510.9864660
Klebsiella0.82506360.90839690.98409670.82082020.90157730.9892744
Staphylococcus0.82453490.92634490.98919050.81349410.92149820.9858902
Streptococcus0.61076510.5454936 0.00000000.61076510.5454936

To make a transition to the next part, let’s see how this difference could be plotted:

-
data_1st %>%
+
data_1st %>%
   group_by(genus) %>%
   summarise("1. Amoxi/clav" = susceptibility(AMC),
             "2. Gentamicin" = susceptibility(GEN),
@@ -1069,14 +1199,15 @@ Longest: 24

ggplot(aes(x = genus, y = value, fill = antibiotic)) + - geom_col(position = "dodge2")
+ geom_col(position = "dodge2") +# `summarise()` ungrouping output (override with `.groups` argument)

Plots

To show results in plots, most R users would nowadays use the ggplot2 package. This package lets you create plots in layers. You can read more about it on their website. A quick example would look like these syntaxes:

-
ggplot(data = a_data_set,
+
ggplot(data = a_data_set,
        mapping = aes(x = year,
                      y = value)) +
   geom_col() +
@@ -1089,12 +1220,12 @@ Longest: 24

ggplot(a_data_set) + geom_bar(aes(year))

The AMR package contains functions to extend this ggplot2 package, for example geom_rsi(). It automatically transforms data with count_df() or proportion_df() and show results in stacked bars. Its simplest and shortest example:

-
ggplot(data_1st) +
+
ggplot(data_1st) +
   geom_rsi(translate_ab = FALSE)

Omit the translate_ab = FALSE to have the antibiotic codes (AMX, AMC, CIP, GEN) translated to official WHO names (amoxicillin, amoxicillin/clavulanic acid, ciprofloxacin, gentamicin).

If we group on e.g. the genus column and add some additional functions from our package, we can create this:

-
# group the data on `genus`
+
# group the data on `genus`
 ggplot(data_1st %>% group_by(genus)) +
   # create bars with genus on x axis
   # it looks for variables with class `rsi`,
@@ -1116,7 +1247,7 @@ Longest: 24

theme(axis.text.y = element_text(face = "italic"))

To simplify this, we also created the ggplot_rsi() function, which combines almost all above functions:

-
data_1st %>%
+
data_1st %>%
   group_by(genus) %>%
   ggplot_rsi(x = "genus",
              facet = "antibiotic",
@@ -1130,7 +1261,7 @@ Longest: 24

Independence test

The next example uses the example_isolates data set. This is a data set included with this package and contains 2,000 microbial isolates with their full antibiograms. It reflects reality and can be used to practice AMR analysis.

We will compare the resistance to fosfomycin (column FOS) in hospital A and D. The input for the fisher.test() can be retrieved with a transformation like this:

-
# use package 'tidyr' to pivot data:
+
# use package 'tidyr' to pivot data:
 library(tidyr)
 
 check_FOS <- example_isolates %>%
@@ -1148,7 +1279,7 @@ Longest: 24

# [1,] 25 77 # [2,] 24 33

We can apply the test now with:

-
# do Fisher's Exact Test
+
# do Fisher's Exact Test
 fisher.test(check_FOS)
 # 
 #   Fisher's Exact Test for Count Data
diff --git a/docs/articles/AMR_files/figure-html/plot 1-1.png b/docs/articles/AMR_files/figure-html/plot 1-1.png
index 900dd0e7..976c1028 100644
Binary files a/docs/articles/AMR_files/figure-html/plot 1-1.png and b/docs/articles/AMR_files/figure-html/plot 1-1.png differ
diff --git a/docs/articles/AMR_files/figure-html/plot 3-1.png b/docs/articles/AMR_files/figure-html/plot 3-1.png
index cc04d1e8..758e69c8 100644
Binary files a/docs/articles/AMR_files/figure-html/plot 3-1.png and b/docs/articles/AMR_files/figure-html/plot 3-1.png differ
diff --git a/docs/articles/AMR_files/figure-html/plot 4-1.png b/docs/articles/AMR_files/figure-html/plot 4-1.png
index 7d603de7..46d8e39c 100644
Binary files a/docs/articles/AMR_files/figure-html/plot 4-1.png and b/docs/articles/AMR_files/figure-html/plot 4-1.png differ
diff --git a/docs/articles/AMR_files/figure-html/plot 5-1.png b/docs/articles/AMR_files/figure-html/plot 5-1.png
index 1e18c8ff..cb65db17 100644
Binary files a/docs/articles/AMR_files/figure-html/plot 5-1.png and b/docs/articles/AMR_files/figure-html/plot 5-1.png differ
diff --git a/docs/articles/index.html b/docs/articles/index.html
index a76ecdcd..7e84b631 100644
--- a/docs/articles/index.html
+++ b/docs/articles/index.html
@@ -81,7 +81,7 @@
       
       
         AMR (for R)
-        1.2.0.9007
+        1.2.0.9008
       
     
diff --git a/docs/authors.html b/docs/authors.html index aa508916..c2d62f4f 100644 --- a/docs/authors.html +++ b/docs/authors.html @@ -81,7 +81,7 @@ AMR (for R) - 1.2.0.9007 + 1.2.0.9008
diff --git a/docs/index.html b/docs/index.html index 144caf74..58b93b6b 100644 --- a/docs/index.html +++ b/docs/index.html @@ -43,7 +43,7 @@ AMR (for R) - 1.2.0.9007 + 1.2.0.9008
diff --git a/docs/news/index.html b/docs/news/index.html index 10ca6320..2c5c2581 100644 --- a/docs/news/index.html +++ b/docs/news/index.html @@ -81,7 +81,7 @@ AMR (for R) - 1.2.0.9007 + 1.2.0.9008
@@ -229,9 +229,9 @@ Source: NEWS.md
-
-

-AMR 1.2.0.9007 Unreleased +
+

+AMR 1.2.0.9008 Unreleased

@@ -251,7 +251,12 @@ tibble(J01CA01 = "S") %>% select(penicillins()) -#> Selecting beta-lactams/penicillins: `J01CA01` (ampicillin)

+#> Selecting beta-lactams/penicillins: `J01CA01` (ampicillin) + +# select an antibiotic class manually with `ab_class()` +example_isolates %>% + select(ab_class("mycobact")) +#> Selecting antimycobacterials: `RIF` (rifampicin)
@@ -260,7 +265,7 @@ Changed
  • Fixed a bug where eucast_rules() would not work on a tibble when the tibble or dplyr package was loaded
  • -
  • All *_join_microorganisms() functions now return the original data class (e.g. tibbles and data.tables)
  • +
  • All *_join_microorganisms() functions and bug_drug_combinations() now return the original data class (e.g. tibbles and data.tables)
  • Fixed a bug where as.ab() would return an error on invalid input values
  • Fixed a bug for using grouped versions of rsi_df(), proportion_df() and count_df(), and fixed a bug where not all different antimicrobial results were added as rows
  • Added function filter_penicillins() to filter isolates on a specific result in any column with a name in the antimicrobial ‘penicillins’ class (more specific: ATC subgroup Beta-lactam antibacterials, penicillins)
  • @@ -269,6 +274,7 @@
  • Added antibiotics code “FOX1” for cefoxitin screening (abbreviation “cfsc”) to the antibiotics data set
  • Improved auto-determination for columns of types <mo> and <Date>
  • +
  • Fixed a bug in bug_drug_combinations() for when only one antibiotic was in the input data
diff --git a/docs/pkgdown.yml b/docs/pkgdown.yml index f3164d9f..2869d661 100644 --- a/docs/pkgdown.yml +++ b/docs/pkgdown.yml @@ -10,7 +10,7 @@ articles: WHONET: WHONET.html benchmarks: benchmarks.html resistance_predict: resistance_predict.html -last_built: 2020-06-16T23:38Z +last_built: 2020-06-17T13:03Z urls: reference: https://msberends.gitlab.io/AMR/reference article: https://msberends.gitlab.io/AMR/articles diff --git a/docs/reference/antibiotic_class_selectors.html b/docs/reference/antibiotic_class_selectors.html index f4e2195b..cf1a4595 100644 --- a/docs/reference/antibiotic_class_selectors.html +++ b/docs/reference/antibiotic_class_selectors.html @@ -82,7 +82,7 @@ AMR (for R) - 1.2.0.9007 + 1.2.0.9008
@@ -235,7 +235,9 @@

Use these selection helpers inside any function that allows Tidyverse selections, like dplyr::select() or tidyr::pivot_longer(). They help to select the columns of antibiotics that are of a specific antibiotic class, without the need to define the columns or antibiotic abbreviations.

-
aminoglycosides()
+    
ab_class(ab_class)
+
+aminoglycosides()
 
 carbapenems()
 
@@ -261,6 +263,14 @@
 
 tetracyclines()
+

Arguments

+ + + + + + +
ab_class

an antimicrobial class, like "carbapenems". The columns group, atc_group1 and atc_group2 of the antibiotics data set will be searched (case-insensitive) for this value.

Details

@@ -277,11 +287,22 @@ example_isolates %>% select(carbapenems()) - # this will select columns 'mo', 'AMK', 'GEN', 'KAN' and 'TOB': example_isolates %>% select(mo, aminoglycosides()) + # this will select columns 'mo' and all antimycobacterial drugs ('RIF'): + example_isolates %>% + select(mo, ab_class("mycobact")) + + + # get bug/drug combinations for only macrolides in Gram-positives: + example_isolates %>% + filter(mo_gramstain(mo) %like% "pos") %>% + select(mo, macrolides()) %>% + bug_drug_combinations() %>% + format() + data.frame(irrelevant = "value", J01CA01 = "S") %>% # ATC code of ampicillin diff --git a/docs/reference/as.mo.html b/docs/reference/as.mo.html index d845cce9..261dcf76 100644 --- a/docs/reference/as.mo.html +++ b/docs/reference/as.mo.html @@ -82,7 +82,7 @@ AMR (for R) - 1.2.0 + 1.2.0.9008
@@ -425,7 +425,7 @@ This package contains the complete taxonomic tree of almost all microorganisms ( if (FALSE) { df$mo <- as.mo(df$microorganism_name) -# the select function of tidyverse is also supported: +# the select function of the Tidyverse is also supported: library(dplyr) df$mo <- df %>% select(microorganism_name) %>% diff --git a/docs/reference/index.html b/docs/reference/index.html index 3d951d31..d8ad6651 100644 --- a/docs/reference/index.html +++ b/docs/reference/index.html @@ -81,7 +81,7 @@ AMR (for R) - 1.2.0.9007 + 1.2.0.9008 @@ -420,6 +420,12 @@

Principal Component Analysis (for AMR)

+ +

ab_class() aminoglycosides() carbapenems() cephalosporins() cephalosporins_1st() cephalosporins_2nd() cephalosporins_3rd() cephalosporins_4th() cephalosporins_5th() fluoroquinolones() glycopeptides() macrolides() penicillins() tetracyclines()

+ +

Antibiotic class selectors

+ +

filter_ab_class() filter_aminoglycosides() filter_carbapenems() filter_cephalosporins() filter_1st_cephalosporins() filter_2nd_cephalosporins() filter_3rd_cephalosporins() filter_4th_cephalosporins() filter_5th_cephalosporins() filter_fluoroquinolones() filter_glycopeptides() filter_macrolides() filter_penicillins() filter_tetracyclines()

diff --git a/docs/reference/lifecycle.html b/docs/reference/lifecycle.html index e0dd7432..cb52b428 100644 --- a/docs/reference/lifecycle.html +++ b/docs/reference/lifecycle.html @@ -49,9 +49,9 @@ - +This page contains a section for every lifecycle (with text borrowed from the aforementioned Tidyverse website), so they can be used in the manual pages of the functions." /> @@ -84,7 +84,7 @@ This page contains a section for every lifecycle (with text borrowed from the af AMR (for R) - 1.2.0 + 1.2.0.9008 @@ -234,9 +234,9 @@ This page contains a section for every lifecycle (with text borrowed from the af
-

Functions in this AMR package are categorised using the lifecycle circle of the tidyverse as found on www.tidyverse.org/lifecycle.

-


-This page contains a section for every lifecycle (with text borrowed from the aforementioned tidyverse website), so they can be used in the manual pages of the functions.

+

Functions in this AMR package are categorised using the lifecycle circle of the Tidyverse as found on www.tidyverse.org/lifecycle.

+


+This page contains a section for every lifecycle (with text borrowed from the aforementioned Tidyverse website), so they can be used in the manual pages of the functions.

diff --git a/docs/reference/proportion.html b/docs/reference/proportion.html index 6df56250..86290947 100644 --- a/docs/reference/proportion.html +++ b/docs/reference/proportion.html @@ -83,7 +83,7 @@ resistance() should be used to calculate resistance, susceptibility() should be AMR (for R) - 1.2.0 + 1.2.0.9008 @@ -322,7 +322,7 @@ resistance() should be used to calculate resistance, susceptibility() should be

The function resistance() is equal to the function proportion_R(). The function susceptibility() is equal to the function proportion_SI().

Remember that you should filter your table to let it contain only first isolates! This is needed to exclude duplicates and to reduce selection bias. Use first_isolate() to determine them in your data set.

-

These functions are not meant to count isolates, but to calculate the proportion of resistance/susceptibility. Use the count()][AMR::count()] functions to count isolates. The function susceptibility() is essentially equal to count_susceptible() / count_all(). Low counts can influence the outcome - the proportion functions may camouflage this, since they only return the proportion (albeit being dependent on the minimum parameter).

+

These functions are not meant to count isolates, but to calculate the proportion of resistance/susceptibility. Use the count() functions to count isolates. The function susceptibility() is essentially equal to count_susceptible() / count_all(). Low counts can influence the outcome - the proportion functions may camouflage this, since they only return the proportion (albeit being dependent on the minimum parameter).

The function proportion_df() takes any variable from data that has an rsi class (created with as.rsi()) and calculates the proportions R, I and S. It also supports grouped variables. The function rsi_df() works exactly like proportion_df(), but adds the number of isolates.

Combination therapy

@@ -410,7 +410,7 @@ A microorganism is categorised as Susceptible, Increased exposure when SI = susceptibility(CIP, as_percent = TRUE), n1 = count_all(CIP), # the actual total; sum of all three n2 = n_rsi(CIP), # same - analogous to n_distinct - total = n()) # NOT the number of tested isolates! + total = n()) # NOT the number of tested isolates! # Calculate co-resistance between amoxicillin/clav acid and gentamicin, # so we can see that combination therapy does a lot more than mono therapy: diff --git a/man/antibiotic_class_selectors.Rd b/man/antibiotic_class_selectors.Rd index 71e5712b..9317fa1a 100644 --- a/man/antibiotic_class_selectors.Rd +++ b/man/antibiotic_class_selectors.Rd @@ -2,6 +2,7 @@ % Please edit documentation in R/ab_class_selectors.R \name{antibiotic_class_selectors} \alias{antibiotic_class_selectors} +\alias{ab_class} \alias{aminoglycosides} \alias{carbapenems} \alias{cephalosporins} @@ -17,6 +18,8 @@ \alias{tetracyclines} \title{Antibiotic class selectors} \usage{ +ab_class(ab_class) + aminoglycosides() carbapenems() @@ -43,6 +46,9 @@ penicillins() tetracyclines() } +\arguments{ +\item{ab_class}{an antimicrobial class, like \code{"carbapenems"}. The columns \code{group}, \code{atc_group1} and \code{atc_group2} of the \link{antibiotics} data set will be searched (case-insensitive) for this value.} +} \description{ Use these selection helpers inside any function that allows \href{https://tidyselect.r-lib.org/reference/language.html}{Tidyverse selections}, like \code{dplyr::select()} or \code{tidyr::pivot_longer()}. They help to select the columns of antibiotics that are of a specific antibiotic class, without the need to define the columns or antibiotic abbreviations. } @@ -58,16 +64,27 @@ if (require("dplyr")) { example_isolates \%>\% select(carbapenems()) - # this will select columns 'mo', 'AMK', 'GEN', 'KAN' and 'TOB': example_isolates \%>\% select(mo, aminoglycosides()) + # this will select columns 'mo' and all antimycobacterial drugs ('RIF'): + example_isolates \%>\% + select(mo, ab_class("mycobact")) + + + # get bug/drug combinations for only macrolides in Gram-positives: + example_isolates \%>\% + filter(mo_gramstain(mo) \%like\% "pos") \%>\% + select(mo, macrolides()) \%>\% + bug_drug_combinations() \%>\% + format() + data.frame(irrelevant = "value", J01CA01 = "S") \%>\% # ATC code of ampicillin select(penicillins()) # so the 'J01CA01' column is selected - + } } \seealso{ diff --git a/man/as.mo.Rd b/man/as.mo.Rd index 7ef4690c..446b970b 100644 --- a/man/as.mo.Rd +++ b/man/as.mo.Rd @@ -192,7 +192,7 @@ mo_gramstain("E. coli") # returns "Gram negative" \dontrun{ df$mo <- as.mo(df$microorganism_name) -# the select function of tidyverse is also supported: +# the select function of the Tidyverse is also supported: library(dplyr) df$mo <- df \%>\% select(microorganism_name) \%>\% diff --git a/man/lifecycle.Rd b/man/lifecycle.Rd index e3c85754..b7fa4eaf 100644 --- a/man/lifecycle.Rd +++ b/man/lifecycle.Rd @@ -4,10 +4,10 @@ \alias{lifecycle} \title{Lifecycles of functions in the \code{AMR} package} \description{ -Functions in this \code{AMR} package are categorised using \href{https://www.tidyverse.org/lifecycle}{the lifecycle circle of the \code{tidyverse} as found on www.tidyverse.org/lifecycle}. +Functions in this \code{AMR} package are categorised using \href{https://www.Tidyverse.org/lifecycle}{the lifecycle circle of the Tidyverse as found on www.tidyverse.org/lifecycle}. -\if{html}{\figure{lifecycle_tidyverse.svg}{options: height=200px style=margin-bottom:5px} \cr} -This page contains a section for every lifecycle (with text borrowed from the aforementioned \code{tidyverse} website), so they can be used in the manual pages of the functions. +\if{html}{\figure{lifecycle_Tidyverse.svg}{options: height=200px style=margin-bottom:5px} \cr} +This page contains a section for every lifecycle (with text borrowed from the aforementioned Tidyverse website), so they can be used in the manual pages of the functions. } \section{Experimental lifecycle}{ diff --git a/man/proportion.Rd b/man/proportion.Rd index a61ffcb0..bd7be656 100644 --- a/man/proportion.Rd +++ b/man/proportion.Rd @@ -83,7 +83,7 @@ The function \code{\link[=resistance]{resistance()}} is equal to the function \c \strong{Remember that you should filter your table to let it contain only first isolates!} This is needed to exclude duplicates and to reduce selection bias. Use \code{\link[=first_isolate]{first_isolate()}} to determine them in your data set. -These functions are not meant to count isolates, but to calculate the proportion of resistance/susceptibility. Use the \code{count()}][AMR::count()] functions to count isolates. The function \code{\link[=susceptibility]{susceptibility()}} is essentially equal to \code{count_susceptible() / count_all()}. \emph{Low counts can influence the outcome - the \code{proportion} functions may camouflage this, since they only return the proportion (albeit being dependent on the \code{minimum} parameter).} +These functions are not meant to count isolates, but to calculate the proportion of resistance/susceptibility. Use the \code{\link[AMR:count]{count()}} functions to count isolates. The function \code{\link[=susceptibility]{susceptibility()}} is essentially equal to \code{count_susceptible() / count_all()}. \emph{Low counts can influence the outcome - the \code{proportion} functions may camouflage this, since they only return the proportion (albeit being dependent on the \code{minimum} parameter).} The function \code{\link[=proportion_df]{proportion_df()}} takes any variable from \code{data} that has an \code{\link{rsi}} class (created with \code{\link[=as.rsi]{as.rsi()}}) and calculates the proportions R, I and S. It also supports grouped variables. The function \code{\link[=rsi_df]{rsi_df()}} works exactly like \code{\link[=proportion_df]{proportion_df()}}, but adds the number of isolates. } diff --git a/vignettes/AMR.Rmd b/vignettes/AMR.Rmd index 989d02c6..7dafb2e3 100755 --- a/vignettes/AMR.Rmd +++ b/vignettes/AMR.Rmd @@ -190,7 +190,7 @@ Finally, we will apply [EUCAST rules](http://www.eucast.org/expert_rules_and_int Because the amoxicillin (column `AMX`) and amoxicillin/clavulanic acid (column `AMC`) in our data were generated randomly, some rows will undoubtedly contain AMX = S and AMC = R, which is technically impossible. The `eucast_rules()` fixes this: ```{r eucast, warning = FALSE, message = FALSE} -data <- eucast_rules(data, col_mo = "bacteria") +data <- eucast_rules(data, col_mo = "bacteria", rules = "all") ``` # Adding new variables @@ -332,6 +332,41 @@ data_1st %>% freq(genus, species, header = TRUE) ``` +## Overview of different bug/drug combinations + +If you want to get a quick glance of the number of isolates in different bug/drug combinations, you can use the `bug_drug_combinations()` function: + +```{r bug_drg 1a, eval = FALSE} +data_1st %>% + bug_drug_combinations() %>% + head() # show first 6 rows +``` + +```{r bug_drg 1b, echo = FALSE, results = 'asis'} +knitr::kable(data_1st %>% + bug_drug_combinations() %>% + head(), + align = "c") +``` + +Using [Tidyverse selections](https://tidyselect.r-lib.org/reference/language.html), you can also select columns based on the antibiotic class they are in: + +```{r bug_drg 2a, eval = FALSE} +data_1st %>% + select(bacteria, fluoroquinolones()) %>% + bug_drug_combinations() +``` + + +```{r bug_drg 2b, echo = FALSE, results = 'asis'} +knitr::kable(data_1st %>% + select(bacteria, fluoroquinolones()) %>% + bug_drug_combinations(), + align = "c") +``` + +This will only give you the crude numbers in the data. To calculate antimicrobial resistance, we use the `resistance()` and `susceptibility()` functions. + ## Resistance percentages The functions `resistance()` and `susceptibility()` can be used to calculate antimicrobial resistance or susceptibility. For more specific analyses, the functions `proportion_S()`, `proportion_SI()`, `proportion_I()`, `proportion_IR()` and `proportion_R()` can be used to determine the proportion of a specific antimicrobial outcome.