From 1bdb136b3a2f1033686bc17e285e44fefdc95a21 Mon Sep 17 00:00:00 2001 From: "Matthijs S. Berends" Date: Mon, 7 Dec 2020 16:06:42 +0100 Subject: [PATCH] (v1.4.0.9032) auto-data guessing for functions --- .github/workflows/check.yaml | 2 +- DESCRIPTION | 4 +- NEWS.md | 32 +++-- R/aa_helper_functions.R | 23 ++- R/ab_class_selectors.R | 7 +- R/eucast_rules.R | 8 +- R/first_isolate.R | 18 ++- R/globals.R | 3 +- R/is_new_episode.R | 3 +- R/key_antibiotics.R | 26 ++-- R/like.R | 2 +- R/mdro.R | 84 ++++++++--- R/mo_property.R | 44 +++--- R/rsi.R | 28 ++-- R/zzz.R | 10 ++ docs/404.html | 2 +- docs/LICENSE-text.html | 2 +- docs/articles/EUCAST.html | 17 ++- docs/articles/MDR.html | 76 +++++----- docs/articles/index.html | 2 +- docs/authors.html | 2 +- docs/index.html | 2 +- docs/news/index.html | 186 ++++++++++++------------- docs/pkgdown.yml | 2 +- docs/reference/first_isolate.html | 11 +- docs/reference/index.html | 2 +- docs/reference/is_new_episode.html | 45 +----- docs/reference/key_antibiotics.html | 25 ++-- docs/reference/mdro.html | 39 +++--- docs/reference/resistance_predict.html | 4 +- docs/survey.html | 2 +- man/first_isolate.Rd | 8 +- man/is_new_episode.Rd | 3 +- man/key_antibiotics.Rd | 20 +-- man/mdro.Rd | 30 ++-- man/resistance_predict.Rd | 2 +- vignettes/EUCAST.Rmd | 12 +- vignettes/MDR.Rmd | 20 ++- 38 files changed, 455 insertions(+), 353 deletions(-) diff --git a/.github/workflows/check.yaml b/.github/workflows/check.yaml index 50f6771e..0fb9fb97 100644 --- a/.github/workflows/check.yaml +++ b/.github/workflows/check.yaml @@ -64,7 +64,7 @@ jobs: - {os: ubuntu-16.04, r: '3.5', allowfail: false, rspm: "https://packagemanager.rstudio.com/cran/__linux__/xenial/latest"} - {os: ubuntu-16.04, r: '3.4', allowfail: true, rspm: "https://packagemanager.rstudio.com/cran/__linux__/xenial/latest"} - {os: ubuntu-16.04, r: '3.3', allowfail: true, rspm: "https://packagemanager.rstudio.com/cran/__linux__/xenial/latest"} - - {os: ubuntu-16.04, r: '3.2', allowfail: true, rspm: "https://packagemanager.rstudio.com/cran/__linux__/xenial/latest"} + # - {os: ubuntu-16.04, r: '3.2', allowfail: true, rspm: "https://packagemanager.rstudio.com/cran/__linux__/xenial/latest"} # older R versions cannot be tested, since tidyverse only supports last 4 R x.x versions env: R_REMOTES_NO_ERRORS_FROM_WARNINGS: true diff --git a/DESCRIPTION b/DESCRIPTION index d87df6de..9f7891fd 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: AMR -Version: 1.4.0.9031 -Date: 2020-12-03 +Version: 1.4.0.9032 +Date: 2020-12-07 Title: Antimicrobial Resistance Analysis Authors@R: c( person(role = c("aut", "cre"), diff --git a/NEWS.md b/NEWS.md index 756fb329..a999e024 100755 --- a/NEWS.md +++ b/NEWS.md @@ -1,28 +1,29 @@ -# AMR 1.4.0.9031 -## Last updated: 3 December 2020 +# AMR 1.4.0.9032 +## Last updated: 7 December 2020 ### New * Function `is_new_episode()` to determine patient episodes which are not necessarily based on microorganisms. It also supports grouped variables with e.g. `mutate()`, `filter()` and `summarise()` of the `dplyr` package: ```r + library(dplyr) example_isolates %>% group_by(patient_id, hospital_id) %>% filter(is_new_episode(date, episode_days = 60)) ``` -* Functions `mo_is_gram_negative()` and `mo_is_gram_positive()` as wrappers around `mo_gramstain()`. They always return `TRUE` or `FALSE` (except when the input is `NA` or the MO code is `UNKNOWN`), thus always return `FALSE` for species outside the taxonomic kingdom of Bacteria. They can even determine the column with microorganisms themselves when used inside `dplyr` verbs: - ```r - example_isolates %>% - filter(mo_is_gram_positive()) - #> NOTE: Using column `mo` as input for mo_is_gram_positive() - ``` -* Function `mo_is_intrinsic_resistant()` to test for intrinsic resistance, based on [EUCAST Intrinsic Resistance and Unusual Phenotypes v3.2](https://www.eucast.org/expert_rules_and_intrinsic_resistance/) from 2020. As with the new `mo_is_gram_*()` functions, if you have the `dplyr` package installed the column with microorganisms will be automatically determined when used inside `dplyr` verbs: - ```r - example_isolates %>% - filter(mo_is_intrinsic_resistant(ab = "Vancomycin")) - #> NOTE: Using column `mo` as input for mo_is_intrinsic_resistant() - ``` +* Functions `mo_is_gram_negative()` and `mo_is_gram_positive()` as wrappers around `mo_gramstain()`. They always return `TRUE` or `FALSE` (except when the input is `NA` or the MO code is `UNKNOWN`), thus always return `FALSE` for species outside the taxonomic kingdom of Bacteria. +* Function `mo_is_intrinsic_resistant()` to test for intrinsic resistance, based on [EUCAST Intrinsic Resistance and Unusual Phenotypes v3.2](https://www.eucast.org/expert_rules_and_intrinsic_resistance/) from 2020. ### Changed -* Reference data used for `as.rsi()` can now be set by the user, using the `reference_data` parameter. This allows for using own interpretation guidelines. +* Reference data used for `as.rsi()` can now be set by the user, using the `reference_data` parameter. This allows for using own interpretation guidelines. The user-set data must have the same structure as `rsi_translation`. +* Some functions are now context-aware when used inside `dplyr` verbs, such as `filter()`, `mutate()` and `summarise()`. This means that then the data parameter does not need to be set anymore. This is the case for the new functions `mo_is_gram_negative()`, `mo_is_gram_positive()`, `mo_is_intrinsic_resistant()` and for the existing functions `first_isolate()`, `key_antibiotics()`, `mdro()`, `brmo()`, `mrgn()`, `mdr_tb()`, `mdr_cmi2012()`, `eucast_exceptional_phenotypes()`. This was already the case for antibiotic selection functions (such as using `penicillins()` in `dplyr::select()`). + ```r + # to select first isolates that are Gram-negative + # and view results of cephalosporins and aminoglycosides: + library(dplyr) + example_isolates %>% + filter(first_isolate(), mo_is_gram_negative()) %>% + select(mo, cephalosporins(), aminoglycosides()) %>% + as_tibble() +``` * For all function parameters in the code, it is now defined what the exact type of user input should be (inspired by the [`typed`](https://github.com/moodymudskipper/typed) package). If the user input for a certain function does not meet the requirements for a specific parameter (such as the class or length), an informative error will be thrown. This makes the package more robust and the use of it more reproducible and reliable. In total, more than 400 arguments were defined. * Deprecated function `p_symbol()` that not really fits the scope of this package. It will be removed in a future version. See [here](https://github.com/msberends/AMR/blob/v1.4.0/R/p_symbol.R) for the source code to preserve it. * Better determination of disk zones and MIC values when running `as.rsi()` on a data.frame @@ -33,6 +34,7 @@ * Fixed a bug where `mo_uncertainties()` would not return the results based on the MO matching score * Fixed a bug where `as.mo()` would not return results for known laboratory codes for microorganisms * Fixed a bug where `as.ab()` would sometimes fail +* If using `as.rsi()` on MICs or disk diffusion while there is intrinsic antimicrobial resistance, a warning will be thrown to remind about this ### Other * All messages and warnings thrown by this package now break sentences on whole words diff --git a/R/aa_helper_functions.R b/R/aa_helper_functions.R index a819526b..9c208bc2 100755 --- a/R/aa_helper_functions.R +++ b/R/aa_helper_functions.R @@ -251,7 +251,7 @@ word_wrap <- function(..., msg <- gsub("\n", "*|*", msg, fixed = TRUE) if (isTRUE(as_note)) { - msg <- paste0("NOTE: ", gsub("note:? ?", "", msg, ignore.case = TRUE)) + msg <- paste0("NOTE: ", gsub("^note:? ?", "", msg, ignore.case = TRUE)) } # we need to correct for already applied style, that adds text like "\033[31m\" @@ -510,6 +510,21 @@ meet_criteria <- function(object, return(invisible()) } +get_current_data <- function(arg_name, call) { + # this mimics dplyr::cur_data_all for users that use our content-aware functions in dplyr verbs + cur_data_all_dplyr <- import_fn("cur_data_all", "dplyr", error_on_fail = FALSE) + if (is.null(cur_data_all_dplyr)) { + # dplyr not installed + stop_("argument `", arg_name, "` is missing, with no default", call = call) + } + tryCatch(cur_data_all_dplyr(), + # dplyr installed, but not used inside dplyr verb + error = function(e) stop_("argument `", arg_name, "` is missing with no default ", + "or function not used inside a valid dplyr verb", + # tryCatch adds 4 system calls, subtract them + call = call - 4)) +} + has_colour <- function() { # this is a base R version of crayon::has_color enabled <- getOption("crayon.enabled") @@ -567,7 +582,7 @@ has_colour <- function() { perl = TRUE) } -# the crayon colours +# set colours if console has_colour() try_colour <- function(..., before, after, collapse = " ") { txt <- paste0(unlist(list(...)), collapse = collapse) if (isTRUE(has_colour())) { @@ -611,7 +626,7 @@ font_grey <- function(..., collapse = " ") { try_colour(..., before = "\033[38;5;249m", after = "\033[39m", collapse = collapse) } font_grey_bg <- function(..., collapse = " ") { - try_colour(..., before = "\033[48;5;253m", after = "\033[49m", collapse = collapse) + try_colour(..., before = "\033[48;5;255m", after = "\033[49m", collapse = collapse) } font_green_bg <- function(..., collapse = " ") { try_colour(..., before = "\033[42m", after = "\033[49m", collapse = collapse) @@ -659,10 +674,12 @@ progress_ticker <- function(n = 1, n_min = 0, ...) { } set_clean_class <- function(x, new_class) { + # return the object with only the new class and no additional attributes where possible if (is.null(x)) { x <- NA_character_ } if (is.factor(x)) { + # keep only levels and remove all other attributes lvls <- levels(x) attributes(x) <- NULL levels(x) <- lvls diff --git a/R/ab_class_selectors.R b/R/ab_class_selectors.R index eb1cf5ce..0f932122 100644 --- a/R/ab_class_selectors.R +++ b/R/ab_class_selectors.R @@ -179,10 +179,11 @@ ab_selector <- function(ab_class, function_name) { message_("No antimicrobial agents of class ", ab_group, " found", examples, ".") } else { message_("Selecting ", ab_group, ": ", - paste(paste0("`", font_bold(agents, collapse = NULL), - "` (", ab_name(names(agents), tolower = TRUE, language = NULL), ")"), + paste(paste0("'", font_bold(agents, collapse = NULL), + "' (", ab_name(names(agents), tolower = TRUE, language = NULL), ")"), collapse = ", "), - as_note = FALSE) + as_note = FALSE, + extra_indent = nchar(paste0("Selecting ", ab_group, ": "))) } unname(agents) } diff --git a/R/eucast_rules.R b/R/eucast_rules.R index 163ddd78..f44b248e 100755 --- a/R/eucast_rules.R +++ b/R/eucast_rules.R @@ -620,8 +620,8 @@ eucast_rules <- function(x, if (any(c("all", "other") %in% rules)) { if (info == TRUE) { cat(font_bold(paste0("\nRules by this AMR package (", - font_red(paste0("v", utils::packageVersion("AMR"), ", ", - format(utils::packageDate("AMR"), "%Y"))), "), see ?eucast_rules\n"))) + font_red(paste0("v", utils::packageDescription("AMR")$Version, ", ", + format(utils::packageDescription("AMR")$Date, "%Y"))), "), see ?eucast_rules\n"))) } ab_enzyme <- subset(antibiotics, name %like% "/")[, c("ab", "name")] @@ -639,7 +639,7 @@ eucast_rules <- function(x, run_changes <- edit_rsi(x = x, col_mo = col_mo, to = "R", - rule = c(rule_current, "Other rules", "", paste0("Non-EUCAST: AMR package v", utils::packageVersion("AMR"))), + rule = c(rule_current, "Other rules", "", paste0("Non-EUCAST: AMR package v", utils::packageDescription("AMR")$Version)), rows = which(as.rsi_no_warning(x[, cols_ab[ab_enzyme[i, ]$ab]]) == "R"), cols = cols_ab[ab_enzyme[i, ]$base_ab], last_verbose_info = verbose_info, @@ -669,7 +669,7 @@ eucast_rules <- function(x, run_changes <- edit_rsi(x = x, col_mo = col_mo, to = "S", - rule = c(rule_current, "Other rules", "", paste0("Non-EUCAST: AMR package v", utils::packageVersion("AMR"))), + rule = c(rule_current, "Other rules", "", paste0("Non-EUCAST: AMR package v", utils::packageDescription("AMR")$Version)), rows = which(as.rsi_no_warning(x[, cols_ab[ab_enzyme[i, ]$base_ab]]) == "S"), cols = cols_ab[ab_enzyme[i, ]$ab], last_verbose_info = verbose_info, diff --git a/R/first_isolate.R b/R/first_isolate.R index 58705639..e47707c1 100755 --- a/R/first_isolate.R +++ b/R/first_isolate.R @@ -27,7 +27,7 @@ #' #' Determine first (weighted) isolates of all microorganisms of every patient per episode and (if needed) per specimen type. To determine patient episodes not necessarily based on microorganisms, use [is_new_episode()] that also supports grouping with the `dplyr` package. #' @inheritSection lifecycle Stable lifecycle -#' @param x a [data.frame] containing isolates. +#' @param x a [data.frame] containing isolates. Can be omitted when used inside `dplyr` verbs, such as `filter()`, `mutate()` and `summarise()`. #' @param col_date column name of the result date (or date that is was received on the lab), defaults to the first column with a date class #' @param col_patient_id column name of the unique IDs of the patients, defaults to the first column that starts with 'patient' or 'patid' (case insensitive) #' @param col_mo column name of the IDs of the microorganisms (see [as.mo()]), defaults to the first column of class [`mo`]. Values will be coerced using [as.mo()]. @@ -45,7 +45,10 @@ #' @param info print progress #' @param include_unknown logical to determine whether 'unknown' microorganisms should be included too, i.e. microbial code `"UNKNOWN"`, which defaults to `FALSE`. For WHONET users, this means that all records with organism code `"con"` (*contamination*) will be excluded at default. Isolates with a microbial ID of `NA` will always be excluded as first isolate. #' @param ... parameters passed on to [first_isolate()] when using [filter_first_isolate()], or parameters passed on to [key_antibiotics()] when using [filter_first_weighted_isolate()] -#' @details The [first_isolate()] function is a wrapper around the [is_new_episode()] function, but more efficient for data sets containing microorganism codes or names. +#' @details +#' These functions are context-aware when used inside `dplyr` verbs, such as `filter()`, `mutate()` and `summarise()`. This means that then the `x` parameter can be omitted, please see *Examples*. +#' +#' The [first_isolate()] function is a wrapper around the [is_new_episode()] function, but more efficient for data sets containing microorganism codes or names. #' #' All isolates with a microbial ID of `NA` will be excluded as first isolate. #' @@ -61,7 +64,7 @@ #' ``` #' x[first_isolate(x, ...), ] #' -#' x %>% filter(first_isolate(x, ...)) +#' x %>% filter(first_isolate(...)) #' ``` #' #' The function [filter_first_weighted_isolate()] is essentially equal to: @@ -109,6 +112,8 @@ #' #' # short-hand versions: #' example_isolates %>% +#' filter(first_isolate()) +#' example_isolates %>% #' filter_first_isolate() #' #' example_isolates %>% @@ -150,6 +155,9 @@ first_isolate <- function(x, info = interactive(), include_unknown = FALSE, ...) { + if (missing(x)) { + x <- get_current_data(arg_name = "x", call = -2) + } meet_criteria(x, allow_class = "data.frame") # also checks dimensions to be >0 meet_criteria(col_date, allow_class = "character", has_length = 1, allow_NULL = TRUE, is_in = colnames(x)) meet_criteria(col_patient_id, allow_class = "character", has_length = 1, allow_NULL = TRUE, is_in = colnames(x)) @@ -425,7 +433,7 @@ first_isolate <- function(x, message_(ifelse(include_unknown == TRUE, "Included ", "Excluded "), format(sum(x$newvar_mo == "UNKNOWN", na.rm = TRUE), decimal.mark = decimal.mark, big.mark = big.mark), - " isolates with a microbial ID 'UNKNOWN' (column `", font_bold(col_mo), "`)") + " isolates with a microbial ID 'UNKNOWN' (column '", font_bold(col_mo), "')") } x[which(x$newvar_mo == "UNKNOWN"), "newvar_first_isolate"] <- include_unknown @@ -433,7 +441,7 @@ first_isolate <- function(x, if (any(is.na(x$newvar_mo)) & info == TRUE) { message_("Excluded ", format(sum(is.na(x$newvar_mo), na.rm = TRUE), decimal.mark = decimal.mark, big.mark = big.mark), - " isolates with a microbial ID 'NA' (column `", font_bold(col_mo), "`)") + " isolates with a microbial ID 'NA' (column '", font_bold(col_mo), "')") } x[which(is.na(x$newvar_mo)), "newvar_first_isolate"] <- FALSE diff --git a/R/globals.R b/R/globals.R index f615d4b5..2e870b65 100755 --- a/R/globals.R +++ b/R/globals.R @@ -23,7 +23,8 @@ # how to conduct AMR analysis: https://msberends.github.io/AMR/ # # ==================================================================== # -globalVariables(c(".rowid", +globalVariables(c("...length", # for pm_group_split() on R 3.3 + ".rowid", "ab", "ab_txt", "angle", diff --git a/R/is_new_episode.R b/R/is_new_episode.R index 1b6bfd96..0ef4632c 100644 --- a/R/is_new_episode.R +++ b/R/is_new_episode.R @@ -43,7 +43,7 @@ #' #' is_new_episode(example_isolates$date) #' is_new_episode(example_isolates$date, episode_days = 60) -#' +#' #' \donttest{ #' if (require("dplyr")) { #' # is_new_episode() can also be used in dplyr verbs to determine patient #' # episodes based on any (combination of) grouping variables: @@ -79,6 +79,7 @@ #' group_by(patient_id, mo, hospital_id, ward_icu) %>% #' mutate(flag_episode = is_new_episode(date)) #' } +#' } is_new_episode <- function(x, episode_days = 365, ...) { meet_criteria(x, allow_class = c("Date", "POSIXt")) meet_criteria(episode_days, allow_class = c("numeric", "double", "integer"), has_length = 1) diff --git a/R/key_antibiotics.R b/R/key_antibiotics.R index a74e1942..d5bac505 100755 --- a/R/key_antibiotics.R +++ b/R/key_antibiotics.R @@ -25,9 +25,9 @@ #' Key antibiotics for first *weighted* isolates #' -#' These function can be used to determine first isolates (see [first_isolate()]). Using key antibiotics to determine first isolates is more reliable than without key antibiotics. These selected isolates will then be called first *weighted* isolates. +#' These function can be used to determine first isolates (see [first_isolate()]). Using key antibiotics to determine first isolates is more reliable than without key antibiotics. These selected isolates can then be called first *weighted* isolates. #' @inheritSection lifecycle Stable lifecycle -#' @param x a data.frame with antibiotics columns, like `AMX` or `amox` +#' @param x a [data.frame] with antibiotics columns, like `AMX` or `amox`. Can be omitted when used inside `dplyr` verbs, such as `filter()`, `mutate()` and `summarise()`. #' @param y,z character vectors to compare #' @inheritParams first_isolate #' @param universal_1,universal_2,universal_3,universal_4,universal_5,universal_6 column names of **broad-spectrum** antibiotics, case-insensitive. See details for which antibiotics will be used at default (which are guessed with [guess_ab_col()]). @@ -35,7 +35,10 @@ #' @param GramNeg_1,GramNeg_2,GramNeg_3,GramNeg_4,GramNeg_5,GramNeg_6 column names of antibiotics for **Gram-negatives**, case-insensitive. See details for which antibiotics will be used at default (which are guessed with [guess_ab_col()]). #' @param warnings give a warning about missing antibiotic columns (they will be ignored) #' @param ... other parameters passed on to functions -#' @details The function [key_antibiotics()] returns a character vector with 12 antibiotic results for every isolate. These isolates can then be compared using [key_antibiotics_equal()], to check if two isolates have generally the same antibiogram. Missing and invalid values are replaced with a dot (`"."`) by [key_antibiotics()] and ignored by [key_antibiotics_equal()]. +#' @details +#' The [key_antibiotics()] function is context-aware when used inside `dplyr` verbs, such as `filter()`, `mutate()` and `summarise()`. This means that then the `x` parameter can be omitted, please see *Examples*. +#' +#' The function [key_antibiotics()] returns a character vector with 12 antibiotic results for every isolate. These isolates can then be compared using [key_antibiotics_equal()], to check if two isolates have generally the same antibiogram. Missing and invalid values are replaced with a dot (`"."`) by [key_antibiotics()] and ignored by [key_antibiotics_equal()]. #' #' The [first_isolate()] function only uses this function on the same microbial species from the same patient. Using this, e.g. an MRSA will be included after a susceptible *S. aureus* (MSSA) is found within the same patient episode. Without key antibiotic comparison it would not. See [first_isolate()] for more info. #' @@ -77,30 +80,30 @@ #' # `example_isolates` is a dataset available in the AMR package. #' # See ?example_isolates. #' -#' # output of the `key_antibiotics` function could be like this: +#' # output of the `key_antibiotics()` function could be like this: #' strainA <- "SSSRR.S.R..S" #' strainB <- "SSSIRSSSRSSS" #' -#' # can those strings can be compared with: +#' # those strings can be compared with: #' key_antibiotics_equal(strainA, strainB) #' # TRUE, because I is ignored (as well as missing values) #' #' key_antibiotics_equal(strainA, strainB, ignore_I = FALSE) -#' # FALSE, because I is not ignored and so the 4th value differs +#' # FALSE, because I is not ignored and so the 4th character differs #' #' \donttest{ #' if (require("dplyr")) { #' # set key antibiotics to a new variable #' my_patients <- example_isolates %>% -#' mutate(keyab = key_antibiotics(.)) %>% +#' mutate(keyab = key_antibiotics()) %>% # no need to define `x` #' mutate( #' # now calculate first isolates -#' first_regular = first_isolate(., col_keyantibiotics = FALSE), +#' first_regular = first_isolate(col_keyantibiotics = FALSE), #' # and first WEIGHTED isolates -#' first_weighted = first_isolate(., col_keyantibiotics = "keyab") +#' first_weighted = first_isolate(col_keyantibiotics = "keyab") #' ) #' -#' # Check the difference, in this data set it results in 7% more isolates: +#' # Check the difference, in this data set it results in a lot more isolates: #' sum(my_patients$first_regular, na.rm = TRUE) #' sum(my_patients$first_weighted, na.rm = TRUE) #' } @@ -127,6 +130,9 @@ key_antibiotics <- function(x, GramNeg_6 = guess_ab_col(x, "meropenem"), warnings = TRUE, ...) { + if (missing(x)) { + x <- get_current_data(arg_name = "x", call = -2) + } meet_criteria(x, allow_class = "data.frame") meet_criteria(col_mo, allow_class = "character", has_length = 1, allow_NULL = TRUE, allow_NA = TRUE) meet_criteria(universal_1, allow_class = "character", has_length = 1, allow_NULL = TRUE, allow_NA = TRUE) diff --git a/R/like.R b/R/like.R index 02d7dfac..02e634e3 100755 --- a/R/like.R +++ b/R/like.R @@ -75,7 +75,7 @@ like <- function(x, pattern, ignore.case = TRUE) { # set to fixed if no regex found fixed <- !any(is_possibly_regex(pattern)) if (ignore.case == TRUE) { - # set here, otherwise if fixed = TRUE, this warning will be thrown: argument 'ignore.case = TRUE' will be ignored + # set here, otherwise if fixed = TRUE, this warning will be thrown: argument `ignore.case = TRUE` will be ignored x <- tolower(x) pattern <- tolower(pattern) } diff --git a/R/mdro.R b/R/mdro.R index ca5f79ed..f1191cd8 100755 --- a/R/mdro.R +++ b/R/mdro.R @@ -27,6 +27,7 @@ #' #' Determine which isolates are multidrug-resistant organisms (MDRO) according to international and national guidelines. #' @inheritSection lifecycle Stable lifecycle +#' @param x a [data.frame] with antibiotics columns, like `AMX` or `amox`. Can be omitted when used inside `dplyr` verbs, such as `filter()`, `mutate()` and `summarise()`. #' @param guideline a specific guideline to follow. When left empty, the publication by Magiorakos *et al.* (2012, Clinical Microbiology and Infection) will be followed, please see *Details*. #' @inheritParams eucast_rules #' @param pct_required_classes minimal required percentage of antimicrobial classes that must be available per isolate, rounded down. For example, with the default guideline, 17 antimicrobial classes must be available for *S. aureus*. Setting this `pct_required_classes` argument to `0.5` (default) means that for every *S. aureus* isolate at least 8 different classes must be available. Any lower number of available classes will return `NA` for that isolate. @@ -34,23 +35,36 @@ #' @param verbose a logical to turn Verbose mode on and off (default is off). In Verbose mode, the function does not return the MDRO results, but instead returns a data set in logbook form with extensive info about which isolates would be MDRO-positive, or why they are not. #' @inheritSection eucast_rules Antibiotics #' @details +#' These functions are context-aware when used inside `dplyr` verbs, such as `filter()`, `mutate()` and `summarise()`. This means that then the `x` parameter can be omitted, please see *Examples*. +#' #' For the `pct_required_classes` argument, values above 1 will be divided by 100. This is to support both fractions (`0.75` or `3/4`) and percentages (`75`). #' #' Currently supported guidelines are (case-insensitive): #' -#' - `guideline = "CMI2012"`\cr -#' Magiorakos AP, Srinivasan A *et al.* "Multidrug-resistant, extensively drug-resistant and pandrug-resistant bacteria: an international expert proposal for interim standard definitions for acquired resistance." Clinical Microbiology and Infection (2012) ([link](https://www.clinicalmicrobiologyandinfection.com/article/S1198-743X(14)61632-3/fulltext)) -#' - `guideline = "EUCAST3.2"` (or simply `guideline = "EUCAST"`)\cr -#' The European international guideline - EUCAST Expert Rules Version 3.2 "Intrinsic Resistance and Unusual Phenotypes" ([link](https://www.eucast.org/fileadmin/src/media/PDFs/EUCAST_files/Expert_Rules/2020/Intrinsic_Resistance_and_Unusual_Phenotypes_Tables_v3.2_20200225.pdf)) -#' - `guideline = "EUCAST3.1"`\cr -#' The European international guideline - EUCAST Expert Rules Version 3.1 "Intrinsic Resistance and Exceptional Phenotypes Tables" ([link](https://www.eucast.org/fileadmin/src/media/PDFs/EUCAST_files/Expert_Rules/Expert_rules_intrinsic_exceptional_V3.1.pdf)) -#' - `guideline = "TB"`\cr -#' The international guideline for multi-drug resistant tuberculosis - World Health Organization "Companion handbook to the WHO guidelines for the programmatic management of drug-resistant tuberculosis" ([link](https://www.who.int/tb/publications/pmdt_companionhandbook/en/)) -#' - `guideline = "MRGN"`\cr -#' The German national guideline - Mueller et al. (2015) Antimicrobial Resistance and Infection Control 4:7. DOI: 10.1186/s13756-015-0047-6 -#' - `guideline = "BRMO"`\cr -#' The Dutch national guideline - Rijksinstituut voor Volksgezondheid en Milieu "WIP-richtlijn BRMO (Bijzonder Resistente Micro-Organismen) (ZKH)" ([link](https://www.rivm.nl/wip-richtlijn-brmo-bijzonder-resistente-micro-organismen-zkh)) +#' * `guideline = "CMI2012"` (default) #' +#' Magiorakos AP, Srinivasan A *et al.* "Multidrug-resistant, extensively drug-resistant and pandrug-resistant bacteria: an international expert proposal for interim standard definitions for acquired resistance." Clinical Microbiology and Infection (2012) ([link](https://www.clinicalmicrobiologyandinfection.com/article/S1198-743X(14)61632-3/fulltext)) +#' +#' * `guideline = "EUCAST3.2"` (or simply `guideline = "EUCAST"`) +#' +#' The European international guideline - EUCAST Expert Rules Version 3.2 "Intrinsic Resistance and Unusual Phenotypes" ([link](https://www.eucast.org/fileadmin/src/media/PDFs/EUCAST_files/Expert_Rules/2020/Intrinsic_Resistance_and_Unusual_Phenotypes_Tables_v3.2_20200225.pdf)) +#' +#' * `guideline = "EUCAST3.1"` +#' +#' The European international guideline - EUCAST Expert Rules Version 3.1 "Intrinsic Resistance and Exceptional Phenotypes Tables" ([link](https://www.eucast.org/fileadmin/src/media/PDFs/EUCAST_files/Expert_Rules/Expert_rules_intrinsic_exceptional_V3.1.pdf)) +#' +#' * `guideline = "TB"` +#' +#' The international guideline for multi-drug resistant tuberculosis - World Health Organization "Companion handbook to the WHO guidelines for the programmatic management of drug-resistant tuberculosis" ([link](https://www.who.int/tb/publications/pmdt_companionhandbook/en/)) +#' +#' * `guideline = "MRGN"` +#' +#' The German national guideline - Mueller et al. (2015) Antimicrobial Resistance and Infection Control 4:7. DOI: 10.1186/s13756-015-0047-6 +#' +#' * `guideline = "BRMO"` +#' +#' The Dutch national guideline - Rijksinstituut voor Volksgezondheid en Milieu "WIP-richtlijn BRMO (Bijzonder Resistente Micro-Organismen) (ZKH)" ([link](https://www.rivm.nl/wip-richtlijn-brmo-bijzonder-resistente-micro-organismen-zkh)) +#' #' Please suggest your own (country-specific) guidelines by letting us know: . #' #' **Note:** Every test that involves the Enterobacteriaceae family, will internally be performed using its newly named *order* Enterobacterales, since the Enterobacteriaceae family has been taxonomically reclassified by Adeolu *et al.* in 2016. Before that, Enterobacteriaceae was the only family under the Enterobacteriales (with an i) order. All species under the old Enterobacteriaceae family are still under the new Enterobacterales (without an i) order, but divided into multiple families. The way tests are performed now by this [mdro()] function makes sure that results from before 2016 and after 2016 are identical. @@ -79,10 +93,12 @@ #' mdro() %>% #' table() #' +#' # no need to define `x` when used inside dplyr verbs: #' example_isolates %>% -#' mutate(EUCAST = eucast_exceptional_phenotypes(.), -#' BRMO = brmo(.), -#' MRGN = mrgn(.)) +#' mutate(MDRO = mdro(), +#' EUCAST = eucast_exceptional_phenotypes(), +#' BRMO = brmo(), +#' MRGN = mrgn()) #' } #' } mdro <- function(x, @@ -93,6 +109,9 @@ mdro <- function(x, combine_SI = TRUE, verbose = FALSE, ...) { + if (missing(x)) { + x <- get_current_data(arg_name = "x", call = -2) + } meet_criteria(x, allow_class = "data.frame") meet_criteria(guideline, allow_class = "character", has_length = 1, allow_NULL = TRUE) meet_criteria(col_mo, allow_class = "character", has_length = 1, is_in = colnames(x), allow_NULL = TRUE) @@ -175,24 +194,28 @@ mdro <- function(x, guideline$author <- "Magiorakos AP, Srinivasan A, Carey RB, ..., Vatopoulos A, Weber JT, Monnet DL" guideline$version <- "N/A" guideline$source <- "Clinical Microbiology and Infection 18:3, 2012. DOI: 10.1111/j.1469-0691.2011.03570.x" - - } else if (guideline$code == "eucast3.2") { - guideline$name <- "EUCAST Expert Rules, \"Intrinsic Resistance and Unusual Phenotypes\"" - guideline$author <- "EUCAST (European Committee on Antimicrobial Susceptibility Testing)" - guideline$version <- "3.2, 2020" - guideline$source <- "https://www.eucast.org/fileadmin/src/media/PDFs/EUCAST_files/Expert_Rules/2020/Intrinsic_Resistance_and_Unusual_Phenotypes_Tables_v3.2_20200225.pdf" + guideline$type <- "MDRs/XDRs/PDRs" } else if (guideline$code == "eucast3.1") { guideline$name <- "EUCAST Expert Rules, \"Intrinsic Resistance and Exceptional Phenotypes Tables\"" guideline$author <- "EUCAST (European Committee on Antimicrobial Susceptibility Testing)" guideline$version <- "3.1, 2016" guideline$source <- "https://www.eucast.org/fileadmin/src/media/PDFs/EUCAST_files/Expert_Rules/Expert_rules_intrinsic_exceptional_V3.1.pdf" + guideline$type <- "EUCAST Exceptional Phenotypes" + + } else if (guideline$code == "eucast3.2") { + guideline$name <- "EUCAST Expert Rules, \"Intrinsic Resistance and Unusual Phenotypes\"" + guideline$author <- "EUCAST (European Committee on Antimicrobial Susceptibility Testing)" + guideline$version <- "3.2, 2020" + guideline$source <- "https://www.eucast.org/fileadmin/src/media/PDFs/EUCAST_files/Expert_Rules/2020/Intrinsic_Resistance_and_Unusual_Phenotypes_Tables_v3.2_20200225.pdf" + guideline$type <- "EUCAST Unusual Phenotypes" } else if (guideline$code == "tb") { guideline$name <- "Companion handbook to the WHO guidelines for the programmatic management of drug-resistant tuberculosis" guideline$author <- "WHO (World Health Organization)" guideline$version <- "WHO/HTM/TB/2014.11, 2014" guideline$source <- "https://www.who.int/tb/publications/pmdt_companionhandbook/en/" + guideline$type <- "MDR-TB's" # support per country: } else if (guideline$code == "mrgn") { @@ -200,12 +223,14 @@ mdro <- function(x, guideline$author <- "M\u00fcller J, Voss A, K\u00f6ck R, ..., Kern WV, Wendt C, Friedrich AW" guideline$version <- "N/A" guideline$source <- "Antimicrobial Resistance and Infection Control 4:7, 2015. DOI: 10.1186/s13756-015-0047-6" + guideline$type <- "MRGNs" } else if (guideline$code == "brmo") { guideline$name <- "WIP-Richtlijn Bijzonder Resistente Micro-organismen (BRMO)" guideline$author <- "RIVM (Rijksinstituut voor de Volksgezondheid)" guideline$version <- "Revision as of December 2017" guideline$source <- "https://www.rivm.nl/Documenten_en_publicaties/Professioneel_Praktisch/Richtlijnen/Infectieziekten/WIP_Richtlijnen/WIP_Richtlijnen/Ziekenhuizen/WIP_richtlijn_BRMO_Bijzonder_Resistente_Micro_Organismen_ZKH" + guideline$type <- "BRMOs" } else { stop("This guideline is currently unsupported: ", guideline$code, call. = FALSE) } @@ -1194,7 +1219,7 @@ mdro <- function(x, if (sum(!is.na(x$MDRO) == 0)) { cat(font_bold(paste0("=> Found 0 MDROs since no isolates are covered by the guideline"))) } else { - cat(font_bold(paste0("=> Found ", sum(x$MDRO %in% c(2:5), na.rm = TRUE), " MDROs out of ", sum(!is.na(x$MDRO)), + cat(font_bold(paste0("=> Found ", sum(x$MDRO %in% c(2:5), na.rm = TRUE), " ", guideline$type, " out of ", sum(!is.na(x$MDRO)), " isolates (", trimws(percentage(sum(x$MDRO %in% c(2:5), na.rm = TRUE) / sum(!is.na(x$MDRO)))), ")\n"))) } } @@ -1255,6 +1280,9 @@ mdro <- function(x, #' @rdname mdro #' @export brmo <- function(x, guideline = "BRMO", ...) { + if (missing(x)) { + x <- get_current_data(arg_name = "x", call = -2) + } meet_criteria(x, allow_class = "data.frame") meet_criteria(guideline, allow_class = "character", has_length = 1) mdro(x, guideline = "BRMO", ...) @@ -1263,6 +1291,9 @@ brmo <- function(x, guideline = "BRMO", ...) { #' @rdname mdro #' @export mrgn <- function(x, guideline = "MRGN", ...) { + if (missing(x)) { + x <- get_current_data(arg_name = "x", call = -2) + } meet_criteria(x, allow_class = "data.frame") meet_criteria(guideline, allow_class = "character", has_length = 1) mdro(x = x, guideline = "MRGN", ...) @@ -1271,6 +1302,9 @@ mrgn <- function(x, guideline = "MRGN", ...) { #' @rdname mdro #' @export mdr_tb <- function(x, guideline = "TB", ...) { + if (missing(x)) { + x <- get_current_data(arg_name = "x", call = -2) + } meet_criteria(x, allow_class = "data.frame") meet_criteria(guideline, allow_class = "character", has_length = 1) mdro(x = x, guideline = "TB", ...) @@ -1279,6 +1313,9 @@ mdr_tb <- function(x, guideline = "TB", ...) { #' @rdname mdro #' @export mdr_cmi2012 <- function(x, guideline = "CMI2012", ...) { + if (missing(x)) { + x <- get_current_data(arg_name = "x", call = -2) + } meet_criteria(x, allow_class = "data.frame") meet_criteria(guideline, allow_class = "character", has_length = 1) mdro(x = x, guideline = "CMI2012", ...) @@ -1287,6 +1324,9 @@ mdr_cmi2012 <- function(x, guideline = "CMI2012", ...) { #' @rdname mdro #' @export eucast_exceptional_phenotypes <- function(x, guideline = "EUCAST", ...) { + if (missing(x)) { + x <- get_current_data(arg_name = "x", call = -2) + } meet_criteria(x, allow_class = "data.frame") meet_criteria(guideline, allow_class = "character", has_length = 1) mdro(x = x, guideline = "EUCAST", ...) diff --git a/R/mo_property.R b/R/mo_property.R index 23842286..252302a7 100755 --- a/R/mo_property.R +++ b/R/mo_property.R @@ -372,11 +372,9 @@ mo_is_intrinsic_resistant <- function(x, ab, language = get_locale(), ...) { meet_criteria(ab, allow_NA = FALSE) meet_criteria(language, has_length = 1, is_in = c(LANGUAGES_SUPPORTED, ""), allow_NULL = TRUE, allow_NA = TRUE) - x.mo <- as.mo(x, language = language, ...) - x <- mo_name(x.mo, language = NULL) # has to match intrinsic_resistant$microorganism - ab <- ab_name(ab, language = NULL, # has to match intrinsic_resistant$antibiotic - flag_multiple_results = FALSE, - info = FALSE) + x <- as.mo(x, language = language, ...) + ab <- as.ab(ab, language = NULL, flag_multiple_results = FALSE, info = FALSE) + if (length(x) == 1 & length(ab) > 1) { x <- rep(x, length(ab)) } else if (length(ab) == 1 & length(x) > 1) { @@ -389,15 +387,13 @@ mo_is_intrinsic_resistant <- function(x, ab, language = get_locale(), ...) { # show used version number once per session if (is.null(getOption("AMR_intrinsic_resistance_note", NULL))) { message_("Determining intrinsic resistance based on ", - AMR:::format_eucast_version_nr(3.2, FALSE), ". ", - font_bold("This message is shown once per session.")) + format_eucast_version_nr(3.2, FALSE), ". ", + font_bold("This note is shown only once per session.")) options(AMR_intrinsic_resistance_note = "shown") } - # this saves about 50% in calculation time - intrinsic_to_check <- intrinsic_resistant[which(intrinsic_resistant$microorganism %in% x | - intrinsic_resistant$antibiotic %in% ab), , drop = FALSE] - paste(x, ab) %in% paste(intrinsic_to_check$microorganism, intrinsic_to_check$antibiotic) + # runs against internal vector: INTRINSIC_R (see zzz.R) + paste(x, ab) %in% INTRINSIC_R } #' @rdname mo_property @@ -616,23 +612,17 @@ mo_validate <- function(x, property, language, ...) { } find_mo_col <- function(fn) { - # this function tries to find an mo column using dplyr:::peek_mask() for mo_is_*() functions, + # this function tries to find an mo column using dplyr::cur_data_all() for mo_is_*() functions, # which is useful when functions are used within dplyr verbs - peek_mask_dplyr <- import_fn("peek_mask", "dplyr", error_on_fail = FALSE) - if (!is.null(peek_mask_dplyr)) { - df <- NULL - mo <- NULL - try({ - df <- as.data.frame(peek_mask_dplyr()$across_cols(), stringsAsFactors = FALSE) - mo <- suppressMessages(search_type_in_df(df, "mo")) - }, silent = TRUE) - if (!is.null(df) && !is.null(mo) && is.data.frame(df)) { - message_("Using column '", font_bold(mo), "' as input for ", fn, "()") - return(df[, mo, drop = TRUE]) - } else { - stop_("Argument `x` is missing and no column with info about microorganisms could be found.", call = -2) - } + df <- get_current_data("x", call = -3) # will return an error if not found + mo <- NULL + try({ + mo <- suppressMessages(search_type_in_df(df, "mo")) + }, silent = TRUE) + if (!is.null(df) && !is.null(mo) && is.data.frame(df)) { + message_("Using column '", font_bold(mo), "' as input for ", fn, "()") + return(df[, mo, drop = TRUE]) } else { - stop_("Argument `x` is missing.", call = -2) + stop_("argument `x` is missing and no column with info about microorganisms could be found.", call = -2) } } diff --git a/R/rsi.R b/R/rsi.R index 87b47526..f75f577b 100755 --- a/R/rsi.R +++ b/R/rsi.R @@ -354,7 +354,7 @@ as.rsi.mic <- function(x, uti <- rep(uti, length(x)) } - message_("=> Interpreting MIC values of `", font_bold(ab), "` (", + message_("=> Interpreting MIC values of '", font_bold(ab), "' (", ifelse(ab_coerced != ab, paste0(ab_coerced, ", "), ""), ab_name(ab_coerced, tolower = TRUE), ")", mo_var_found, " according to ", ifelse(identical(reference_data, AMR::rsi_translation), @@ -444,7 +444,7 @@ as.rsi.disk <- function(x, uti <- rep(uti, length(x)) } - message_("=> Interpreting disk zones of `", font_bold(ab), "` (", + message_("=> Interpreting disk zones of '", font_bold(ab), "' (", ifelse(ab_coerced != ab, paste0(ab_coerced, ", "), ""), ab_name(ab_coerced, tolower = TRUE), ")", mo_var_found, " according to ", ifelse(identical(reference_data, AMR::rsi_translation), @@ -720,22 +720,23 @@ exec_as.rsi <- function(method, lookup_other <- paste(mo_other, ab) if (all(trans$uti == TRUE, na.rm = TRUE) & all(uti == FALSE)) { - message_("WARNING.", add_fn = list(font_red, font_bold), as_note = FALSE) + message_("WARNING.", add_fn = list(font_yellow, font_bold), as_note = FALSE) warning_("Interpretation of ", font_bold(ab_name(ab, tolower = TRUE)), " for some microorganisms is only available for (uncomplicated) urinary tract infections (UTI). Use parameter 'uti' to set which isolates are from urine. See ?as.rsi.", call = FALSE) warned <- TRUE } + any_is_intrinsic_resistant <- FALSE + for (i in seq_len(length(x))) { - if (isTRUE(add_intrinsic_resistance)) { + is_intrinsic_r <- paste(mo[i], ab) %in% INTRINSIC_R + any_is_intrinsic_resistant <- any_is_intrinsic_resistant | is_intrinsic_r + + if (isTRUE(add_intrinsic_resistance) & is_intrinsic_r) { if (!guideline_coerced %like% "EUCAST") { warning_("Using 'add_intrinsic_resistance' is only useful when using EUCAST guidelines, since the rules for intrinsic resistance are based on EUCAST.", call = FALSE) } else { - get_record <- subset(intrinsic_resistant, - microorganism == mo_name(mo[i], language = NULL) & antibiotic == ab_name(ab, language = NULL)) - if (nrow(get_record) > 0) { - new_rsi[i] <- "R" - next - } + new_rsi[i] <- "R" + next } } @@ -795,6 +796,13 @@ exec_as.rsi <- function(method, } } + if (any_is_intrinsic_resistant & guideline_coerced %like% "EUCAST" & !isTRUE(add_intrinsic_resistance)) { + # found some intrinsic resistance, but was not applied + message_("WARNING.", add_fn = list(font_yellow, font_bold), as_note = FALSE) + warning_("Found intrinsic resistance in some bug/drug combinations, although it was not applied.\nUse `as.rsi(..., add_intrinsic_resistance = TRUE)` to apply it.", call = FALSE) + warned <- TRUE + } + new_rsi <- x_bak %pm>% pm_left_join(data.frame(x_mo = paste0(df$x, df$mo), new_rsi, stringsAsFactors = FALSE), diff --git a/R/zzz.R b/R/zzz.R index 8a11e4d5..3e5f1c79 100755 --- a/R/zzz.R +++ b/R/zzz.R @@ -36,6 +36,10 @@ value = create_MO.old_lookup(), envir = asNamespace("AMR")) + assign(x = "INTRINSIC_R", + value = create_intr_resistance(), + envir = asNamespace("AMR")) + assign(x = "LANGUAGES_SUPPORTED", value = sort(c("en", unique(translations_file$lang))), envir = asNamespace("AMR")) @@ -86,6 +90,12 @@ font_bold("options(AMR_silentstart = TRUE)"), "]")) } +create_intr_resistance <- function() { + # for mo_is_intrinsic_resistant() - saves a lot of time when executed on this vector + paste(AMR::microorganisms[match(AMR::intrinsic_resistant$microorganism, AMR::microorganisms$fullname), "mo", drop = TRUE], + AMR::antibiotics[match(AMR::intrinsic_resistant$antibiotic, AMR::antibiotics$name), "ab", drop = TRUE]) +} + create_species_cons_cops <- function(type = c("CoNS", "CoPS")) { # Determination of which staphylococcal species are CoNS/CoPS according to: # - Becker et al. 2014, PMID 25278577 diff --git a/docs/404.html b/docs/404.html index 5562eea2..faf804e7 100644 --- a/docs/404.html +++ b/docs/404.html @@ -81,7 +81,7 @@ AMR (for R) - 1.4.0.9031 + 1.4.0.9032 diff --git a/docs/LICENSE-text.html b/docs/LICENSE-text.html index cde8c1a8..aba3301e 100644 --- a/docs/LICENSE-text.html +++ b/docs/LICENSE-text.html @@ -81,7 +81,7 @@ AMR (for R) - 1.4.0.9031 + 1.4.0.9032 diff --git a/docs/articles/EUCAST.html b/docs/articles/EUCAST.html index d1c6cf95..204ae865 100644 --- a/docs/articles/EUCAST.html +++ b/docs/articles/EUCAST.html @@ -39,7 +39,7 @@ AMR (for R) - 1.4.0.9000 + 1.4.0.9032 @@ -228,8 +228,17 @@ # mo ampicillin # 1 Klebsiella R # 2 Escherichia S -

EUCAST rules can not only be used for correction, they can also be used for filling in known resistance and susceptibility based on results of other antimicrobials drugs. This process is called interpretive reading and is part of the eucast_rules() function as well:

+

A more convenient function is mo_is_intrinsic_resistant() that uses the same guideline, but allows to check for one or more specific microorganisms or antibiotics:

+mo_is_intrinsic_resistant(c("Klebsiella", "Escherichia"),
+                          "ampicillin")
+# [1]  TRUE FALSE
+
+mo_is_intrinsic_resistant("Klebsiella",
+                          c("ampicillin", "kanamycin"))
+# [1]  TRUE FALSE
+

EUCAST rules can not only be used for correction, they can also be used for filling in known resistance and susceptibility based on results of other antimicrobials drugs. This process is called interpretive reading, is basically a form of imputation, and is part of the eucast_rules() function as well:

+
 data <- data.frame(mo = c("Staphylococcus aureus",
                           "Enterococcus faecalis",
                           "Escherichia coli",
@@ -243,7 +252,7 @@
                    PEN = "S",       # Benzylenicillin
                    FOX = "S",       # Cefoxitin
                    stringsAsFactors = FALSE)
-
+
 data
@@ -309,7 +318,7 @@
-
+
 
diff --git a/docs/articles/MDR.html b/docs/articles/MDR.html
index 1b5377b2..40463820 100644
--- a/docs/articles/MDR.html
+++ b/docs/articles/MDR.html
@@ -39,7 +39,7 @@
       
         AMR (for R)
-        1.4.0.9000
+        1.4.0.9032
       
 
@@ -217,7 +217,11 @@
 

Magiorakos AP, Srinivasan A et al. “Multidrug-resistant, extensively drug-resistant and pandrug-resistant bacteria: an international expert proposal for interim standard definitions for acquired resistance.” Clinical Microbiology and Infection (2012) (link)

  • -

    guideline = "EUCAST"

    +

    guideline = "EUCAST3.2" (or simply guideline = "EUCAST")

    +

    The European international guideline - EUCAST Expert Rules Version 3.2 “Intrinsic Resistance and Unusual Phenotypes” (link)

    +
  • +
  • +

    guideline = "EUCAST3.1"

    The European international guideline - EUCAST Expert Rules Version 3.1 “Intrinsic Resistance and Exceptional Phenotypes Tables” (link)

  • @@ -226,13 +230,14 @@
  • guideline = "MRGN"

    -

    The German national guideline - Mueller et al. (2015) Antimicrobial Resistance and Infection Control 4:7. (link)

    +

    The German national guideline - Mueller et al. (2015) Antimicrobial Resistance and Infection Control 4:7. DOI: 10.1186/s13756-015-0047-6

  • guideline = "BRMO"

    -

    The Dutch national guideline - Rijksinstituut voor Volksgezondheid en Milieu “WIP-richtlijn BRMO (Bijzonder Resistente Micro-Organismen) [ZKH]” (link)

    +

    The Dutch national guideline - Rijksinstituut voor Volksgezondheid en Milieu “WIP-richtlijn BRMO (Bijzonder Resistente Micro-Organismen) (ZKH)” (link)

  • +

    Please suggest your own (country-specific) guidelines by letting us know: https://github.com/msberends/AMR/issues/new.

    @@ -246,8 +251,8 @@ example_isolates %>% mdro() %>% freq() # show frequency table of the result -# Warning in mdro(.): NA introduced for isolates where the available percentage of -# antimicrobial classes was below 50% (set with `pct_required_classes`)

    +# Warning in warning_("NA introduced for isolates where the available percentage of antimicrobial classes was below ", : NA introduced for isolates where the available percentage of antimicrobial +# classes was below 50% (set with `pct_required_classes`)

    Frequency table

    Class: factor > ordered (numeric)
    Length: 2,000
    @@ -313,26 +318,27 @@ Unique: 2

     head(my_TB_data)
     #   rifampicin isoniazid gatifloxacin ethambutol pyrazinamide moxifloxacin
    -# 1          R         S            S          R            R            S
    -# 2          I         R            S          R            S            I
    -# 3          R         R            S          S            S            S
    -# 4          R         R            S          I            S            S
    -# 5          S         I            R          S            R            S
    -# 6          S         S            S          R            S            S
    +# 1          S         I            R          S            R            R
    +# 2          R         S            S          R            I            S
    +# 3          I         R            I          S            R            S
    +# 4          I         S            S          R            S            R
    +# 5          R         R            S          S            R            R
    +# 6          S         R            I          S            S            I
     #   kanamycin
    -# 1         S
    +# 1         R
     # 2         S
     # 3         S
    -# 4         S
    -# 5         S
    -# 6         R
    +# 4 R +# 5 R +# 6 S

    We can now add the interpretation of MDR-TB to our data set. You can use:

     mdro(my_TB_data, guideline = "TB")

    or its shortcut mdr_tb():

     my_TB_data$mdr <- mdr_tb(my_TB_data)
    -# NOTE: No column found as input for `col_mo`, assuming all records contain Mycobacterium tuberculosis.
    +# NOTE: No column found as input for `col_mo`, assuming all records contain +# Mycobacterium tuberculosis.

    Create a frequency table of the results:

     freq(my_TB_data$mdr)
    @@ -355,40 +361,40 @@ Unique: 5

    - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - + + diff --git a/docs/articles/index.html b/docs/articles/index.html index ff62373d..20d49cb0 100644 --- a/docs/articles/index.html +++ b/docs/articles/index.html @@ -81,7 +81,7 @@ AMR (for R) - 1.4.0.9031 + 1.4.0.9032 diff --git a/docs/authors.html b/docs/authors.html index 7628ecd8..e2e94091 100644 --- a/docs/authors.html +++ b/docs/authors.html @@ -81,7 +81,7 @@ AMR (for R) - 1.4.0.9031 + 1.4.0.9032 diff --git a/docs/index.html b/docs/index.html index 07ad307f..d0957299 100644 --- a/docs/index.html +++ b/docs/index.html @@ -43,7 +43,7 @@ AMR (for R) - 1.4.0.9031 + 1.4.0.9032 diff --git a/docs/news/index.html b/docs/news/index.html index acfbb1f3..c2b10a6b 100644 --- a/docs/news/index.html +++ b/docs/news/index.html @@ -81,7 +81,7 @@ AMR (for R) - 1.4.0.9031 + 1.4.0.9032 @@ -236,13 +236,13 @@ Source: NEWS.md -
    -

    -AMR 1.4.0.9031 Unreleased +
    +

    +AMR 1.4.0.9032 Unreleased

    -
    +

    -Last updated: 3 December 2020 +Last updated: 7 December 2020

    @@ -251,42 +251,42 @@
  • Function is_new_episode() to determine patient episodes which are not necessarily based on microorganisms. It also supports grouped variables with e.g. mutate(), filter() and summarise() of the dplyr package:

    +library(dplyr)
     example_isolates %>%
    -  group_by(patient_id, hospital_id) %>%
    -  filter(is_new_episode(date, episode_days = 60))
    -
  • -
  • -

    Functions mo_is_gram_negative() and mo_is_gram_positive() as wrappers around mo_gramstain(). They always return TRUE or FALSE (except when the input is NA or the MO code is UNKNOWN), thus always return FALSE for species outside the taxonomic kingdom of Bacteria. They can even determine the column with microorganisms themselves when used inside dplyr verbs:

    -
    -example_isolates %>%
    -  filter(mo_is_gram_positive())
    -#> NOTE: Using column `mo` as input for mo_is_gram_positive()
    -
  • -
  • -

    Function mo_is_intrinsic_resistant() to test for intrinsic resistance, based on EUCAST Intrinsic Resistance and Unusual Phenotypes v3.2 from 2020. As with the new mo_is_gram_*() functions, if you have the dplyr package installed the column with microorganisms will be automatically determined when used inside dplyr verbs:

    -
    -example_isolates %>%
    -  filter(mo_is_intrinsic_resistant(ab = "Vancomycin"))
    -#> NOTE: Using column `mo` as input for mo_is_intrinsic_resistant()
    + group_by(patient_id, hospital_id) %>% + filter(is_new_episode(date, episode_days = 60))
  • +
  • Functions mo_is_gram_negative() and mo_is_gram_positive() as wrappers around mo_gramstain(). They always return TRUE or FALSE (except when the input is NA or the MO code is UNKNOWN), thus always return FALSE for species outside the taxonomic kingdom of Bacteria.

  • +
  • Function mo_is_intrinsic_resistant() to test for intrinsic resistance, based on EUCAST Intrinsic Resistance and Unusual Phenotypes v3.2 from 2020.

  • Changed

      -
    • Reference data used for as.rsi() can now be set by the user, using the reference_data parameter. This allows for using own interpretation guidelines.
    • -
    • For all function parameters in the code, it is now defined what the exact type of user input should be (inspired by the typed package). If the user input for a certain function does not meet the requirements for a specific parameter (such as the class or length), an informative error will be thrown. This makes the package more robust and the use of it more reproducible and reliable. In total, more than 400 arguments were defined.
    • -
    • Deprecated function p_symbol() that not really fits the scope of this package. It will be removed in a future version. See here for the source code to preserve it.
    • -
    • Better determination of disk zones and MIC values when running as.rsi() on a data.frame
    • -
    • Updated coagulase-negative staphylococci determination with Becker et al. 2020 (PMID 32056452), meaning that the species S. argensis, S. caeli, S. debuckii, S. edaphicus and S. pseudoxylosus are now all considered CoNS
    • -
    • Fix for using parameter reference_df in as.mo() and mo_*() functions that contain old microbial codes (from previous package versions)
    • -
    • Fix for using as.rsi() on a data.frame in older R versions
    • +
    • Reference data used for as.rsi() can now be set by the user, using the reference_data parameter. This allows for using own interpretation guidelines. The user-set data must have the same structure as rsi_translation.

    • -as.rsi() on a data.frame will not print a message anymore if the values are already clean R/SI values
    • -
    • Fixed a bug where mo_uncertainties() would not return the results based on the MO matching score
    • -
    • Fixed a bug where as.mo() would not return results for known laboratory codes for microorganisms
    • -
    • Fixed a bug where as.ab() would sometimes fail
    • +

      Some functions are now context-aware when used inside dplyr verbs, such as filter(), mutate() and summarise(). This means that then the data parameter does not need to be set anymore. This is the case for the new functions mo_is_gram_negative(), mo_is_gram_positive(), mo_is_intrinsic_resistant() and for the existing functions first_isolate(), key_antibiotics(), mdro(), brmo(), mrgn(), mdr_tb(), mdr_cmi2012(), eucast_exceptional_phenotypes(). This was already the case for antibiotic selection functions (such as using penicillins() in dplyr::select()).

      +
      +# to select first isolates that are Gram-negative 
      +# and view results of cephalosporins and aminoglycosides:
      +library(dplyr)
      +example_isolates %>%
      +  filter(first_isolate(), mo_is_gram_negative()) %>% 
      +  select(mo, cephalosporins(), aminoglycosides()) %>% 
      +  as_tibble()
      + +
    • For all function parameters in the code, it is now defined what the exact type of user input should be (inspired by the typed package). If the user input for a certain function does not meet the requirements for a specific parameter (such as the class or length), an informative error will be thrown. This makes the package more robust and the use of it more reproducible and reliable. In total, more than 400 arguments were defined.

    • +
    • Deprecated function p_symbol() that not really fits the scope of this package. It will be removed in a future version. See here for the source code to preserve it.

    • +
    • Better determination of disk zones and MIC values when running as.rsi() on a data.frame

    • +
    • Updated coagulase-negative staphylococci determination with Becker et al. 2020 (PMID 32056452), meaning that the species S. argensis, S. caeli, S. debuckii, S. edaphicus and S. pseudoxylosus are now all considered CoNS

    • +
    • Fix for using parameter reference_df in as.mo() and mo_*() functions that contain old microbial codes (from previous package versions)

    • +
    • Fix for using as.rsi() on a data.frame in older R versions

    • +
    • as.rsi() on a data.frame will not print a message anymore if the values are already clean R/SI values

    • +
    • Fixed a bug where mo_uncertainties() would not return the results based on the MO matching score

    • +
    • Fixed a bug where as.mo() would not return results for known laboratory codes for microorganisms

    • +
    • Fixed a bug where as.ab() would sometimes fail

    • +
    • If using as.rsi() on MICs or disk diffusion while there is intrinsic antimicrobial resistance, a warning will be thrown to remind about this

    @@ -313,7 +313,7 @@
  • Data set intrinsic_resistant. This data set contains all bug-drug combinations where the ‘bug’ is intrinsic resistant to the ‘drug’ according to the latest EUCAST insights. It contains just two columns: microorganism and antibiotic.

    Curious about which enterococci are actually intrinsic resistant to vancomycin?

    -
    +
     library(AMR)
     library(dplyr)
     intrinsic_resistant %>%
    @@ -335,7 +335,7 @@
     
    • Support for using dplyr’s across() to interpret MIC values or disk zone diameters, which also automatically determines the column with microorganism names or codes.

      -
      +
       # until dplyr 1.0.0
       your_data %>% mutate_if(is.mic, as.rsi)
       your_data %>% mutate_if(is.disk, as.rsi)
      @@ -352,7 +352,7 @@
       
    • Added intelligent data cleaning to as.disk(), so numbers can also be extracted from text and decimal numbers will always be rounded up:

      -
      +
       as.disk(c("disk zone: 23.4 mm", 23.4))
       #> Class <disk>
       #> [1] 24 24
      @@ -412,7 +412,7 @@
    • Function ab_from_text() to retrieve antimicrobial drug names, doses and forms of administration from clinical texts in e.g. health care records, which also corrects for misspelling since it uses as.ab() internally

    • Tidyverse selection helpers for antibiotic classes, that help to select the columns of antibiotics that are of a specific antibiotic class, without the need to define the columns or antibiotic abbreviations. They can be used in any function that allows selection helpers, like dplyr::select() and tidyr::pivot_longer():

      -
      +
       library(dplyr)
       
       # Columns 'IPM' and 'MEM' are in the example_isolates data set
      @@ -496,7 +496,7 @@
       

      Making this package independent of especially the tidyverse (e.g. packages dplyr and tidyr) tremendously increases sustainability on the long term, since tidyverse functions change quite often. Good for users, but hard for package maintainers. Most of our functions are replaced with versions that only rely on base R, which keeps this package fully functional for many years to come, without requiring a lot of maintenance to keep up with other packages anymore. Another upside it that this package can now be used with all versions of R since R-3.0.0 (April 2013). Our package is being used in settings where the resources are very limited. Fewer dependencies on newer software is helpful for such settings.

      Negative effects of this change are:

        -
      • Function freq() that was borrowed from the cleaner package was removed. Use cleaner::freq(), or run library("cleaner") before you use freq().
      • +
      • Function freq() that was borrowed from the cleaner package was removed. Use cleaner::freq(), or run library("cleaner") before you use freq().
      • Printing values of class mo or rsi in a tibble will no longer be in colour and printing rsi in a tibble will show the class <ord>, not <rsi> anymore. This is purely a visual effect.
      • All functions from the mo_* family (like mo_name() and mo_gramstain()) are noticeably slower when running on hundreds of thousands of rows.
      • For developers: classes mo and ab now both also inherit class character, to support any data transformation. This change invalidates code that checks for class length == 1.
      • @@ -600,7 +600,7 @@ This works for all drug combinations, such as ampicillin/sulbactam, ceftazidime/
      • Fixed important floating point error for some MIC comparisons in EUCAST 2020 guideline

      • Interpretation from MIC values (and disk zones) to R/SI can now be used with mutate_at() of the dplyr package:

        -
        +
         yourdata %>% 
           mutate_at(vars(antibiotic1:antibiotic25), as.rsi, mo = "E. coli")
         
        @@ -628,7 +628,7 @@ This works for all drug combinations, such as ampicillin/sulbactam, ceftazidime/
         
        • Support for LOINC codes in the antibiotics data set. Use ab_loinc() to retrieve LOINC codes, or use a LOINC code for input in any ab_* function:

          -
          +
           ab_loinc("ampicillin")
           #> [1] "21066-6" "3355-5"  "33562-0" "33919-2" "43883-8" "43884-6" "87604-5"
           ab_name("21066-6")
          @@ -638,7 +638,7 @@ This works for all drug combinations, such as ampicillin/sulbactam, ceftazidime/
           
        • Support for SNOMED CT codes in the microorganisms data set. Use mo_snomed() to retrieve SNOMED codes, or use a SNOMED code for input in any mo_* function:

          -
          +
           mo_snomed("S. aureus")
           #> [1] 115329001   3092008 113961008
           mo_name(115329001)
          @@ -702,10 +702,10 @@ This works for all drug combinations, such as ampicillin/sulbactam, ceftazidime/
           
          • If you were dependent on the old Enterobacteriaceae family e.g. by using in your code:

            -
            +
             if (mo_family(somebugs) == "Enterobacteriaceae") ...

            then please adjust this to:

            -
            +
             if (mo_order(somebugs) == "Enterobacterales") ...
          @@ -718,7 +718,7 @@ This works for all drug combinations, such as ampicillin/sulbactam, ceftazidime/
          • Functions susceptibility() and resistance() as aliases of proportion_SI() and proportion_R(), respectively. These functions were added to make it more clear that “I” should be considered susceptible and not resistant.

            -
            +
             library(dplyr)
             example_isolates %>%
               group_by(bug = mo_name(mo)) %>% 
            @@ -746,7 +746,7 @@ This works for all drug combinations, such as ampicillin/sulbactam, ceftazidime/
             
          • More intelligent way of coping with some consonants like “l” and “r”

          • Added a score (a certainty percentage) to mo_uncertainties(), that is calculated using the Levenshtein distance:

            -
            +
             as.mo(c("Stafylococcus aureus",
                     "staphylokok aureuz"))
             #> Warning: 
            @@ -804,13 +804,13 @@ This works for all drug combinations, such as ampicillin/sulbactam, ceftazidime/
             
            • Determination of first isolates now excludes all ‘unknown’ microorganisms at default, i.e. microbial code "UNKNOWN". They can be included with the new parameter include_unknown:

              -
              +
               first_isolate(..., include_unknown = TRUE)

              For WHONET users, this means that all records/isolates with organism code "con" (contamination) will be excluded at default, since as.mo("con") = "UNKNOWN". The function always shows a note with the number of ‘unknown’ microorganisms that were included or excluded.

            • For code consistency, classes ab and mo will now be preserved in any subsetting or assignment. For the sake of data integrity, this means that invalid assignments will now result in NA:

              -
              +
               # how it works in base R:
               x <- factor("A")
               x[1] <- "B"
              @@ -824,7 +824,7 @@ This works for all drug combinations, such as ampicillin/sulbactam, ceftazidime/
               #> invalid microorganism code, NA generated

              This is important, because a value like "testvalue" could never be understood by e.g. mo_name(), although the class would suggest a valid microbial code.

            • -
            • Function freq() has moved to a new package, clean (CRAN link), since creating frequency tables actually does not fit the scope of this package. The freq() function still works, since it is re-exported from the clean package (which will be installed automatically upon updating this AMR package).

            • +
            • Function freq() has moved to a new package, clean (CRAN link), since creating frequency tables actually does not fit the scope of this package. The freq() function still works, since it is re-exported from the clean package (which will be installed automatically upon updating this AMR package).

            • Renamed data set septic_patients to example_isolates

            @@ -834,7 +834,7 @@ This works for all drug combinations, such as ampicillin/sulbactam, ceftazidime/
            • Function bug_drug_combinations() to quickly get a data.frame with the results of all bug-drug combinations in a data set. The column containing microorganism codes is guessed automatically and its input is transformed with mo_shortname() at default:

              -
              +
               x <- bug_drug_combinations(example_isolates)
               #> NOTE: Using column `mo` as input for `col_mo`.
               x[1:4, ]
              @@ -856,12 +856,12 @@ This works for all drug combinations, such as ampicillin/sulbactam, ceftazidime/
               #> 4 Gram-negative AMX 227  0 405   632
               #> NOTE: Use 'format()' on this result to get a publicable/printable format.

              You can format this to a printable format, ready for reporting or exporting to e.g. Excel with the base R format() function:

              -
              +
               format(x, combine_IR = FALSE)
            • Additional way to calculate co-resistance, i.e. when using multiple antimicrobials as input for portion_* functions or count_* functions. This can be used to determine the empiric susceptibility of a combination therapy. A new parameter only_all_tested (which defaults to FALSE) replaces the old also_single_tested and can be used to select one of the two methods to count isolates and calculate portions. The difference can be seen in this example table (which is also on the portion and count help pages), where the %SI is being determined:

              -
              +
               # --------------------------------------------------------------------
               #                     only_all_tested = FALSE  only_all_tested = TRUE
               #                     -----------------------  -----------------------
              @@ -882,7 +882,7 @@ This works for all drug combinations, such as ampicillin/sulbactam, ceftazidime/
               
            • tibble printing support for classes rsi, mic, disk, ab mo. When using tibbles containing antimicrobial columns, values S will print in green, values I will print in yellow and values R will print in red. Microbial IDs (class mo) will emphasise on the genus and species, not on the kingdom.

              -
              +
               # (run this on your own console, as this page does not support colour printing)
               library(dplyr)
               example_isolates %>%
              @@ -964,7 +964,7 @@ This works for all drug combinations, such as ampicillin/sulbactam, ceftazidime/
               
              • Function rsi_df() to transform a data.frame to a data set containing only the microbial interpretation (S, I, R), the antibiotic, the percentage of S/I/R and the number of available isolates. This is a convenient combination of the existing functions count_df() and portion_df() to immediately show resistance percentages and number of available isolates:

                -
                +
                 septic_patients %>%
                   select(AMX, CIP) %>%
                   rsi_df()
                @@ -990,7 +990,7 @@ This works for all drug combinations, such as ampicillin/sulbactam, ceftazidime/
                 
              • UPEC (Uropathogenic E. coli)

              All these lead to the microbial ID of E. coli:

              -
              +
               as.mo("UPEC")
               # B_ESCHR_COL
               mo_name("UPEC")
              @@ -1087,21 +1087,21 @@ This works for all drug combinations, such as ampicillin/sulbactam, ceftazidime/
               
            • The age() function gained a new parameter exact to determine ages with decimals
            • Removed deprecated functions guess_mo(), guess_atc(), EUCAST_rules(), interpretive_reading(), rsi()
            • -
            • Frequency tables (freq()): +
            • Frequency tables (freq()):
              • speed improvement for microbial IDs

              • fixed factor level names for R Markdown

              • when all values are unique it now shows a message instead of a warning

              • support for boxplots:

                -
                +
                 septic_patients %>% 
                -  freq(age) %>% 
                +  freq(age) %>% 
                   boxplot()
                 # grouped boxplots:
                 septic_patients %>% 
                   group_by(hospital_id) %>% 
                -  freq(age) %>%
                +  freq(age) %>%
                   boxplot()
              @@ -1111,7 +1111,7 @@ This works for all drug combinations, such as ampicillin/sulbactam, ceftazidime/
            • Added ceftazidim intrinsic resistance to Streptococci
            • Changed default settings for age_groups(), to let groups of fives and tens end with 100+ instead of 120+
            • -
            • Fix for freq() for when all values are NA +
            • Fix for freq() for when all values are NA
            • Fix for first_isolate() for when dates are missing
            • Improved speed of guess_ab_col() @@ -1188,7 +1188,7 @@ This works for all drug combinations, such as ampicillin/sulbactam, ceftazidime/
            • New filters for antimicrobial classes. Use these functions to filter isolates on results in one of more antibiotics from a specific class:

              -
              +
               filter_aminoglycosides()
               filter_carbapenems()
               filter_cephalosporins()
              @@ -1201,7 +1201,7 @@ This works for all drug combinations, such as ampicillin/sulbactam, ceftazidime/
               filter_macrolides()
               filter_tetracyclines()

              The antibiotics data set will be searched, after which the input data will be checked for column names with a value in any abbreviations, codes or official names found in the antibiotics data set. For example:

              -
              +
               septic_patients %>% filter_glycopeptides(result = "R")
               # Filtering on glycopeptide antibacterials: any of `vanc` or `teic` is R
               septic_patients %>% filter_glycopeptides(result = "R", scope = "all")
              @@ -1209,7 +1209,7 @@ This works for all drug combinations, such as ampicillin/sulbactam, ceftazidime/
               
            • All ab_* functions are deprecated and replaced by atc_* functions:

              -
              +
               ab_property -> atc_property()
               ab_name -> atc_name()
               ab_official -> atc_official()
              @@ -1229,19 +1229,19 @@ This works for all drug combinations, such as ampicillin/sulbactam, ceftazidime/
               
            • New function age_groups() to split ages into custom or predefined groups (like children or elderly). This allows for easier demographic antimicrobial resistance analysis per age group.

            • New function ggplot_rsi_predict() as well as the base R plot() function can now be used for resistance prediction calculated with resistance_predict():

              -
              +
               x <- resistance_predict(septic_patients, col_ab = "amox")
               plot(x)
               ggplot_rsi_predict(x)
            • Functions filter_first_isolate() and filter_first_weighted_isolate() to shorten and fasten filtering on data sets with antimicrobial results, e.g.:

              -
              +
               septic_patients %>% filter_first_isolate(...)
               # or
               filter_first_isolate(septic_patients, ...)

              is equal to:

              -
              +
               septic_patients %>%
                 mutate(only_firsts = first_isolate(septic_patients, ...)) %>%
                 filter(only_firsts == TRUE) %>%
              @@ -1273,7 +1273,7 @@ This works for all drug combinations, such as ampicillin/sulbactam, ceftazidime/
               
              • Now handles incorrect spelling, like i instead of y and f instead of ph:

                -
                +
                 # mo_fullname() uses as.mo() internally
                 
                 mo_fullname("Sthafilokockus aaureuz")
                @@ -1284,7 +1284,7 @@ This works for all drug combinations, such as ampicillin/sulbactam, ceftazidime/
                 
              • Uncertainty of the algorithm is now divided into four levels, 0 to 3, where the default allow_uncertain = TRUE is equal to uncertainty level 2. Run ?as.mo for more info about these levels.

                -
                +
                 # equal:
                 as.mo(..., allow_uncertain = TRUE)
                 as.mo(..., allow_uncertain = 2)
                @@ -1298,7 +1298,7 @@ This works for all drug combinations, such as ampicillin/sulbactam, ceftazidime/
                 
              • All microbial IDs that found are now saved to a local file ~/.Rhistory_mo. Use the new function clean_mo_history() to delete this file, which resets the algorithms.

              • Incoercible results will now be considered ‘unknown’, MO code UNKNOWN. On foreign systems, properties of these will be translated to all languages already previously supported: German, Dutch, French, Italian, Spanish and Portuguese:

                -
                +
                 mo_genus("qwerty", language = "es")
                 # Warning: 
                 # one unique value (^= 100.0%) could not be coerced and is considered 'unknown': "qwerty". Use mo_failures() to review it.
                @@ -1343,24 +1343,24 @@ This works for all drug combinations, such as ampicillin/sulbactam, ceftazidime/
                 
            • -
            • Frequency tables (freq() function): +
            • Frequency tables (freq() function):
              • Support for tidyverse quasiquotation! Now you can create frequency tables of function outcomes:

                -
                +
                 # Determine genus of microorganisms (mo) in `septic_patients` data set:
                 # OLD WAY
                 septic_patients %>%
                   mutate(genus = mo_genus(mo)) %>%
                -  freq(genus)
                +  freq(genus)
                 # NEW WAY
                 septic_patients %>% 
                -  freq(mo_genus(mo))
                +  freq(mo_genus(mo))
                 
                 # Even supports grouping variables:
                 septic_patients %>%
                   group_by(gender) %>% 
                -  freq(mo_genus(mo))
                + freq(mo_genus(mo))
              • Header info is now available as a list, with the header function

              • The parameter header is now set to TRUE at default, even for markdown

              • @@ -1430,7 +1430,7 @@ This works for all drug combinations, such as ampicillin/sulbactam, ceftazidime/
              • Fewer than 3 characters as input for as.mo will return NA

              • Function as.mo (and all mo_* wrappers) now supports genus abbreviations with “species” attached

                -
                +
                 as.mo("E. species")        # B_ESCHR
                 mo_fullname("E. spp.")     # "Escherichia species"
                 as.mo("S. spp")            # B_STPHY
                @@ -1442,20 +1442,20 @@ This works for all drug combinations, such as ampicillin/sulbactam, ceftazidime/
                 
              • Using portion_* functions now throws a warning when total available isolate is below parameter minimum

              • Functions as.mo, as.rsi, as.mic, as.atc and freq will not set package name as attribute anymore

              • -

                Frequency tables - freq():

                +

                Frequency tables - freq():

                • Support for grouping variables, test with:

                  -
                  +
                   septic_patients %>% 
                     group_by(hospital_id) %>% 
                  -  freq(gender)
                  + freq(gender)
                • Support for (un)selecting columns:

                  -
                  +
                   septic_patients %>% 
                  -  freq(hospital_id) %>% 
                  +  freq(hospital_id) %>% 
                     select(-count, -cum_count) # only get item, percent, cum_percent
                • Check for hms::is.hms

                • @@ -1473,7 +1473,7 @@ This works for all drug combinations, such as ampicillin/sulbactam, ceftazidime/
                • Removed diacritics from all authors (columns microorganisms$ref and microorganisms.old$ref) to comply with CRAN policy to only allow ASCII characters

                • Fix for mo_property not working properly

                • Fix for eucast_rules where some Streptococci would become ceftazidime R in EUCAST rule 4.5

                • -
                • Support for named vectors of class mo, useful for top_freq()

                • +
                • Support for named vectors of class mo, useful for top_freq()

                • ggplot_rsi and scale_y_percent have breaks parameter

                • AI improvements for as.mo:

                  @@ -1532,7 +1532,7 @@ This works for all drug combinations, such as ampicillin/sulbactam, ceftazidime/

                They also come with support for German, Dutch, French, Italian, Spanish and Portuguese:

                -
                +
                 mo_gramstain("E. coli")
                 # [1] "Gram negative"
                 mo_gramstain("E. coli", language = "de") # German
                @@ -1542,7 +1542,7 @@ This works for all drug combinations, such as ampicillin/sulbactam, ceftazidime/
                 mo_fullname("S. group A", language = "pt") # Portuguese
                 # [1] "Streptococcus grupo A"

                Furthermore, former taxonomic names will give a note about the current taxonomic name:

                -
                +
                 mo_gramstain("Esc blattae")
                 # Note: 'Escherichia blattae' (Burgess et al., 1973) was renamed 'Shimwellia blattae' (Priest and Barker, 2010)
                 # [1] "Gram negative"
                @@ -1556,7 +1556,7 @@ This works for all drug combinations, such as ampicillin/sulbactam, ceftazidime/
              • Function is.rsi.eligible to check for columns that have valid antimicrobial results, but do not have the rsi class yet. Transform the columns of your raw data with: data %>% mutate_if(is.rsi.eligible, as.rsi)

              • Functions as.mo and is.mo as replacements for as.bactid and is.bactid (since the microoganisms data set not only contains bacteria). These last two functions are deprecated and will be removed in a future release. The as.mo function determines microbial IDs using intelligent rules:

                -
                +
                 as.mo("E. coli")
                 # [1] B_ESCHR_COL
                 as.mo("MRSA")
                @@ -1564,7 +1564,7 @@ This works for all drug combinations, such as ampicillin/sulbactam, ceftazidime/
                 as.mo("S group A")
                 # [1] B_STRPTC_GRA

                And with great speed too - on a quite regular Linux server from 2007 it takes us less than 0.02 seconds to transform 25,000 items:

                -
                +
                 thousands_of_E_colis <- rep("E. coli", 25000)
                 microbenchmark::microbenchmark(as.mo(thousands_of_E_colis), unit = "s")
                 # Unit: seconds
                @@ -1597,7 +1597,7 @@ This works for all drug combinations, such as ampicillin/sulbactam, ceftazidime/
                 
              • Added three antimicrobial agents to the antibiotics data set: Terbinafine (D01BA02), Rifaximin (A07AA11) and Isoconazole (D01AC05)

              • Added 163 trade names to the antibiotics data set, it now contains 298 different trade names in total, e.g.:

                -
                +
                 ab_official("Bactroban")
                 # [1] "Mupirocin"
                 ab_name(c("Bactroban", "Amoxil", "Zithromax", "Floxapen"))
                @@ -1613,7 +1613,7 @@ This works for all drug combinations, such as ampicillin/sulbactam, ceftazidime/
                 
              • Added parameters minimum and as_percent to portion_df

              • Support for quasiquotation in the functions series count_* and portions_*, and n_rsi. This allows to check for more than 2 vectors or columns.

                -
                +
                 septic_patients %>% select(amox, cipr) %>% count_IR()
                 # which is the same as:
                 septic_patients %>% count_IR(amox, cipr)
                @@ -1632,14 +1632,14 @@ This works for all drug combinations, such as ampicillin/sulbactam, ceftazidime/
                 
              • Added longest en shortest character length in the frequency table (freq) header of class character

              • Support for types (classes) list and matrix for freq

                -
                +
                 my_matrix = with(septic_patients, matrix(c(age, gender), ncol = 2))
                -freq(my_matrix)
                +freq(my_matrix)

                For lists, subsetting is possible:

                -
                +
                 my_list = list(age = septic_patients$age, gender = septic_patients$gender)
                -my_list %>% freq(age)
                -my_list %>% freq(gender)
                +my_list %>% freq(age) +my_list %>% freq(gender)
            • @@ -1713,13 +1713,13 @@ This works for all drug combinations, such as ampicillin/sulbactam, ceftazidime/
              • A vignette to explain its usage
              • Support for rsi (antimicrobial resistance) to use as input
              • -
              • Support for table to use as input: freq(table(x, y)) +
              • Support for table to use as input: freq(table(x, y))
              • Support for existing functions hist and plot to use a frequency table as input: hist(freq(df$age))
              • Support for as.vector, as.data.frame, as_tibble and format
              • -
              • Support for quasiquotation: freq(mydata, mycolumn) is the same as mydata %>% freq(mycolumn) +
              • Support for quasiquotation: freq(mydata, mycolumn) is the same as mydata %>% freq(mycolumn)
              • Function top_freq function to return the top/below n items as vector
              • Header of frequency tables now also show Mean Absolute Deviaton (MAD) and Interquartile Range (IQR)
              • diff --git a/docs/pkgdown.yml b/docs/pkgdown.yml index 5ea3ce6d..4f7bedc2 100644 --- a/docs/pkgdown.yml +++ b/docs/pkgdown.yml @@ -12,7 +12,7 @@ articles: datasets: datasets.html resistance_predict: resistance_predict.html welcome_to_AMR: welcome_to_AMR.html -last_built: 2020-12-03T21:21Z +last_built: 2020-12-07T15:06Z urls: reference: https://msberends.github.io/AMR//reference article: https://msberends.github.io/AMR//articles diff --git a/docs/reference/first_isolate.html b/docs/reference/first_isolate.html index c90e27e0..8e94eb00 100644 --- a/docs/reference/first_isolate.html +++ b/docs/reference/first_isolate.html @@ -82,7 +82,7 @@ AMR (for R) - 1.4.0.9030 + 1.4.0.9032
              @@ -285,7 +285,7 @@
  • - + @@ -366,7 +366,8 @@

    A logical vector

    Details

    -

    The first_isolate() function is a wrapper around the is_new_episode() function, but more efficient for data sets containing microorganism codes or names.

    +

    These functions are context-aware when used inside dplyr verbs, such as filter(), mutate() and summarise(). This means that then the x parameter can be omitted, please see Examples.

    +

    The first_isolate() function is a wrapper around the is_new_episode() function, but more efficient for data sets containing microorganism codes or names.

    All isolates with a microbial ID of NA will be excluded as first isolate.

    Why this is so important

    @@ -378,7 +379,7 @@

    The functions filter_first_isolate() and filter_first_weighted_isolate() are helper functions to quickly filter on first isolates.

    The function filter_first_isolate() is essentially equal to either:

      x[first_isolate(x, ...), ]
       
    -  x %>% filter(first_isolate(x, ...))
    +  x %>% filter(first_isolate(...))
     

    The function filter_first_weighted_isolate() is essentially equal to:

      x %>%
    @@ -433,6 +434,8 @@ The lifecycle of this function is stablefilter(first_isolate == TRUE)
      
       # short-hand versions:
    +  example_isolates %>%
    +    filter(first_isolate())
       example_isolates %>%
         filter_first_isolate()
         
    diff --git a/docs/reference/index.html b/docs/reference/index.html
    index 7d4d77c0..5b4fcbd7 100644
    --- a/docs/reference/index.html
    +++ b/docs/reference/index.html
    @@ -81,7 +81,7 @@
           
           
             AMR (for R)
    -        1.4.0.9031
    +        1.4.0.9032
           
         
     
    diff --git a/docs/reference/is_new_episode.html b/docs/reference/is_new_episode.html
    index ea361cc3..d1372913 100644
    --- a/docs/reference/is_new_episode.html
    +++ b/docs/reference/is_new_episode.html
    @@ -82,7 +82,7 @@
           
           
             AMR (for R)
    -        1.4.0.9030
    +        1.4.0.9032
           
         
     
    @@ -281,48 +281,7 @@ The lifecycle of this function is experimen
     

    On our website https://msberends.github.io/AMR/ you can find a comprehensive tutorial about how to conduct AMR analysis, the complete documentation of all functions and an example analysis using WHONET data. As we would like to better understand the backgrounds and needs of our users, please participate in our survey!

    Examples

    -
    # `example_isolates` is a dataset available in the AMR package.
    -# See ?example_isolates.
    -
    -is_new_episode(example_isolates$date)
    -is_new_episode(example_isolates$date, episode_days = 60)
    -
    -if (require("dplyr")) {
    -  # is_new_episode() can also be used in dplyr verbs to determine patient
    -  # episodes based on any (combination of) grouping variables:
    -  example_isolates %>%
    -    mutate(condition = sample(x = c("A", "B", "C"), 
    -                              size = 2000,
    -                              replace = TRUE)) %>% 
    -    group_by(condition) %>%
    -    mutate(new_episode = is_new_episode(date))
    -  
    -  example_isolates %>%
    -    group_by(hospital_id) %>% 
    -    summarise(patients = n_distinct(patient_id),
    -              n_episodes_365 = sum(is_new_episode(date, episode_days = 365)),
    -              n_episodes_60  = sum(is_new_episode(date, episode_days = 60)),
    -              n_episodes_30  = sum(is_new_episode(date, episode_days = 30)))
    -    
    -    
    -  # grouping on patients and microorganisms leads to the same results
    -  # as first_isolate():
    -  x <- example_isolates %>%
    -    filter(first_isolate(., include_unknown = TRUE))
    -    
    -  y <- example_isolates %>%
    -    group_by(patient_id, mo) %>%
    -    filter(is_new_episode(date))
    -
    -  identical(x$patient_id, y$patient_id)
    -  
    -  # but is_new_episode() has a lot more flexibility than first_isolate(),
    -  # since you can now group on anything that seems relevant:
    -  example_isolates %>%
    -    group_by(patient_id, mo, hospital_id, ward_icu) %>%
    -    mutate(flag_episode = is_new_episode(date))
    -}
    -
    +
    
       
       
     
    @@ -239,7 +239,7 @@
         
     
         
    -

    These function can be used to determine first isolates (see first_isolate()). Using key antibiotics to determine first isolates is more reliable than without key antibiotics. These selected isolates will then be called first weighted isolates.

    +

    These function can be used to determine first isolates (see first_isolate()). Using key antibiotics to determine first isolates is more reliable than without key antibiotics. These selected isolates can then be called first weighted isolates.

    key_antibiotics(
    @@ -281,7 +281,7 @@
         
    - + @@ -331,7 +331,8 @@

    Details

    -

    The function key_antibiotics() returns a character vector with 12 antibiotic results for every isolate. These isolates can then be compared using key_antibiotics_equal(), to check if two isolates have generally the same antibiogram. Missing and invalid values are replaced with a dot (".") by key_antibiotics() and ignored by key_antibiotics_equal().

    +

    The key_antibiotics() function is context-aware when used inside dplyr verbs, such as filter(), mutate() and summarise(). This means that then the x parameter can be omitted, please see Examples.

    +

    The function key_antibiotics() returns a character vector with 12 antibiotic results for every isolate. These isolates can then be compared using key_antibiotics_equal(), to check if two isolates have generally the same antibiogram. Missing and invalid values are replaced with a dot (".") by key_antibiotics() and ignored by key_antibiotics_equal().

    The first_isolate() function only uses this function on the same microbial species from the same patient. Using this, e.g. an MRSA will be included after a susceptible S. aureus (MSSA) is found within the same patient episode. Without key antibiotic comparison it would not. See first_isolate() for more info.

    At default, the antibiotics that are used for Gram-positive bacteria are:

    • Amoxicillin

    • @@ -395,30 +396,30 @@ The lifecycle of this function is stable# `example_isolates` is a dataset available in the AMR package. # See ?example_isolates. -# output of the `key_antibiotics` function could be like this: +# output of the `key_antibiotics()` function could be like this: strainA <- "SSSRR.S.R..S" strainB <- "SSSIRSSSRSSS" -# can those strings can be compared with: +# those strings can be compared with: key_antibiotics_equal(strainA, strainB) # TRUE, because I is ignored (as well as missing values) key_antibiotics_equal(strainA, strainB, ignore_I = FALSE) -# FALSE, because I is not ignored and so the 4th value differs +# FALSE, because I is not ignored and so the 4th character differs # \donttest{ if (require("dplyr")) { # set key antibiotics to a new variable my_patients <- example_isolates %>% - mutate(keyab = key_antibiotics(.)) %>% + mutate(keyab = key_antibiotics()) %>% # no need to define `x` mutate( # now calculate first isolates - first_regular = first_isolate(., col_keyantibiotics = FALSE), + first_regular = first_isolate(col_keyantibiotics = FALSE), # and first WEIGHTED isolates - first_weighted = first_isolate(., col_keyantibiotics = "keyab") + first_weighted = first_isolate(col_keyantibiotics = "keyab") ) - # Check the difference, in this data set it results in 7% more isolates: + # Check the difference, in this data set it results in a lot more isolates: sum(my_patients$first_regular, na.rm = TRUE) sum(my_patients$first_weighted, na.rm = TRUE) } diff --git a/docs/reference/mdro.html b/docs/reference/mdro.html index f9e9f15c..52d923d6 100644 --- a/docs/reference/mdro.html +++ b/docs/reference/mdro.html @@ -82,7 +82,7 @@ AMR (for R) - 1.4.0.9000 + 1.4.0.9032 @@ -268,7 +268,7 @@
    - + @@ -319,20 +319,21 @@ Ordered factor with levels Details -

    For the pct_required_classes argument, values above 1 will be divided by 100. This is to support both fractions (0.75 or 3/4) and percentages (75).

    +

    These functions are context-aware when used inside dplyr verbs, such as filter(), mutate() and summarise(). This means that then the x parameter can be omitted, please see Examples.

    +

    For the pct_required_classes argument, values above 1 will be divided by 100. This is to support both fractions (0.75 or 3/4) and percentages (75).

    Currently supported guidelines are (case-insensitive):

      -
    • guideline = "CMI2012"
      -Magiorakos AP, Srinivasan A et al. "Multidrug-resistant, extensively drug-resistant and pandrug-resistant bacteria: an international expert proposal for interim standard definitions for acquired resistance." Clinical Microbiology and Infection (2012) (link)

    • -
    • guideline = "EUCAST3.2" (or simply guideline = "EUCAST")
      -The European international guideline - EUCAST Expert Rules Version 3.2 "Intrinsic Resistance and Unusual Phenotypes" (link)

    • -
    • guideline = "EUCAST3.1"
      -The European international guideline - EUCAST Expert Rules Version 3.1 "Intrinsic Resistance and Exceptional Phenotypes Tables" (link)

    • -
    • guideline = "TB"
      -The international guideline for multi-drug resistant tuberculosis - World Health Organization "Companion handbook to the WHO guidelines for the programmatic management of drug-resistant tuberculosis" (link)

    • -
    • guideline = "MRGN"
      -The German national guideline - Mueller et al. (2015) Antimicrobial Resistance and Infection Control 4:7. DOI: 10.1186/s13756-015-0047-6

    • -
    • guideline = "BRMO"
      -The Dutch national guideline - Rijksinstituut voor Volksgezondheid en Milieu "WIP-richtlijn BRMO (Bijzonder Resistente Micro-Organismen) (ZKH)" (link)

    • +
    • guideline = "CMI2012" (default)

      +

      Magiorakos AP, Srinivasan A et al. "Multidrug-resistant, extensively drug-resistant and pandrug-resistant bacteria: an international expert proposal for interim standard definitions for acquired resistance." Clinical Microbiology and Infection (2012) (link)

    • +
    • guideline = "EUCAST3.2" (or simply guideline = "EUCAST")

      +

      The European international guideline - EUCAST Expert Rules Version 3.2 "Intrinsic Resistance and Unusual Phenotypes" (link)

    • +
    • guideline = "EUCAST3.1"

      +

      The European international guideline - EUCAST Expert Rules Version 3.1 "Intrinsic Resistance and Exceptional Phenotypes Tables" (link)

    • +
    • guideline = "TB"

      +

      The international guideline for multi-drug resistant tuberculosis - World Health Organization "Companion handbook to the WHO guidelines for the programmatic management of drug-resistant tuberculosis" (link)

    • +
    • guideline = "MRGN"

      +

      The German national guideline - Mueller et al. (2015) Antimicrobial Resistance and Infection Control 4:7. DOI: 10.1186/s13756-015-0047-6

    • +
    • guideline = "BRMO"

      +

      The Dutch national guideline - Rijksinstituut voor Volksgezondheid en Milieu "WIP-richtlijn BRMO (Bijzonder Resistente Micro-Organismen) (ZKH)" (link)

    Please suggest your own (country-specific) guidelines by letting us know: https://github.com/msberends/AMR/issues/new.

    @@ -380,10 +381,12 @@ A microorganism is categorised as Susceptible, Increased exposure when mdro() %>% table() + # no need to define `x` when used inside dplyr verbs: example_isolates %>% - mutate(EUCAST = eucast_exceptional_phenotypes(.), - BRMO = brmo(.), - MRGN = mrgn(.)) + mutate(MDRO = mdro(), + EUCAST = eucast_exceptional_phenotypes(), + BRMO = brmo(), + MRGN = mrgn()) } # } diff --git a/docs/reference/resistance_predict.html b/docs/reference/resistance_predict.html index a173fb04..c9db5554 100644 --- a/docs/reference/resistance_predict.html +++ b/docs/reference/resistance_predict.html @@ -82,7 +82,7 @@ AMR (for R) - 1.4.0.9000 + 1.4.0.9032 @@ -287,7 +287,7 @@
    - + diff --git a/docs/survey.html b/docs/survey.html index 6751d323..5724d0ba 100644 --- a/docs/survey.html +++ b/docs/survey.html @@ -81,7 +81,7 @@ AMR (for R) - 1.4.0.9031 + 1.4.0.9032 diff --git a/man/first_isolate.Rd b/man/first_isolate.Rd index 8f5bdba8..5c81f4cd 100755 --- a/man/first_isolate.Rd +++ b/man/first_isolate.Rd @@ -50,7 +50,7 @@ filter_first_weighted_isolate( ) } \arguments{ -\item{x}{a \link{data.frame} containing isolates.} +\item{x}{a \link{data.frame} containing isolates. Can be omitted when used inside \code{dplyr} verbs, such as \code{filter()}, \code{mutate()} and \code{summarise()}.} \item{col_date}{column name of the result date (or date that is was received on the lab), defaults to the first column with a date class} @@ -93,6 +93,8 @@ A \code{\link{logical}} vector Determine first (weighted) isolates of all microorganisms of every patient per episode and (if needed) per specimen type. To determine patient episodes not necessarily based on microorganisms, use \code{\link[=is_new_episode]{is_new_episode()}} that also supports grouping with the \code{dplyr} package. } \details{ +These functions are context-aware when used inside \code{dplyr} verbs, such as \code{filter()}, \code{mutate()} and \code{summarise()}. This means that then the \code{x} parameter can be omitted, please see \emph{Examples}. + The \code{\link[=first_isolate]{first_isolate()}} function is a wrapper around the \code{\link[=is_new_episode]{is_new_episode()}} function, but more efficient for data sets containing microorganism codes or names. All isolates with a microbial ID of \code{NA} will be excluded as first isolate. @@ -107,7 +109,7 @@ The functions \code{\link[=filter_first_isolate]{filter_first_isolate()}} and \c The function \code{\link[=filter_first_isolate]{filter_first_isolate()}} is essentially equal to either:\preformatted{ x[first_isolate(x, ...), ] - x \%>\% filter(first_isolate(x, ...)) + x \%>\% filter(first_isolate(...)) } The function \code{\link[=filter_first_weighted_isolate]{filter_first_weighted_isolate()}} is essentially equal to:\preformatted{ x \%>\% @@ -161,6 +163,8 @@ if (require("dplyr")) { filter(first_isolate == TRUE) # short-hand versions: + example_isolates \%>\% + filter(first_isolate()) example_isolates \%>\% filter_first_isolate() diff --git a/man/is_new_episode.Rd b/man/is_new_episode.Rd index fd8bf1a0..1873f3ba 100644 --- a/man/is_new_episode.Rd +++ b/man/is_new_episode.Rd @@ -41,7 +41,7 @@ On our website \url{https://msberends.github.io/AMR/} you can find \href{https:/ is_new_episode(example_isolates$date) is_new_episode(example_isolates$date, episode_days = 60) - +#' \donttest{ if (require("dplyr")) { # is_new_episode() can also be used in dplyr verbs to determine patient # episodes based on any (combination of) grouping variables: @@ -78,3 +78,4 @@ if (require("dplyr")) { mutate(flag_episode = is_new_episode(date)) } } +} diff --git a/man/key_antibiotics.Rd b/man/key_antibiotics.Rd index 51607a9e..8e747281 100755 --- a/man/key_antibiotics.Rd +++ b/man/key_antibiotics.Rd @@ -40,7 +40,7 @@ key_antibiotics_equal( ) } \arguments{ -\item{x}{a data.frame with antibiotics columns, like \code{AMX} or \code{amox}} +\item{x}{a \link{data.frame} with antibiotics columns, like \code{AMX} or \code{amox}. Can be omitted when used inside \code{dplyr} verbs, such as \code{filter()}, \code{mutate()} and \code{summarise()}.} \item{col_mo}{column name of the IDs of the microorganisms (see \code{\link[=as.mo]{as.mo()}}), defaults to the first column of class \code{\link{mo}}. Values will be coerced using \code{\link[=as.mo]{as.mo()}}.} @@ -65,9 +65,11 @@ key_antibiotics_equal( \item{info}{print progress} } \description{ -These function can be used to determine first isolates (see \code{\link[=first_isolate]{first_isolate()}}). Using key antibiotics to determine first isolates is more reliable than without key antibiotics. These selected isolates will then be called first \emph{weighted} isolates. +These function can be used to determine first isolates (see \code{\link[=first_isolate]{first_isolate()}}). Using key antibiotics to determine first isolates is more reliable than without key antibiotics. These selected isolates can then be called first \emph{weighted} isolates. } \details{ +The \code{\link[=key_antibiotics]{key_antibiotics()}} function is context-aware when used inside \code{dplyr} verbs, such as \code{filter()}, \code{mutate()} and \code{summarise()}. This means that then the \code{x} parameter can be omitted, please see \emph{Examples}. + The function \code{\link[=key_antibiotics]{key_antibiotics()}} returns a character vector with 12 antibiotic results for every isolate. These isolates can then be compared using \code{\link[=key_antibiotics_equal]{key_antibiotics_equal()}}, to check if two isolates have generally the same antibiogram. Missing and invalid values are replaced with a dot (\code{"."}) by \code{\link[=key_antibiotics]{key_antibiotics()}} and ignored by \code{\link[=key_antibiotics_equal]{key_antibiotics_equal()}}. The \code{\link[=first_isolate]{first_isolate()}} function only uses this function on the same microbial species from the same patient. Using this, e.g. an MRSA will be included after a susceptible \emph{S. aureus} (MSSA) is found within the same patient episode. Without key antibiotic comparison it would not. See \code{\link[=first_isolate]{first_isolate()}} for more info. @@ -136,30 +138,30 @@ On our website \url{https://msberends.github.io/AMR/} you can find \href{https:/ # `example_isolates` is a dataset available in the AMR package. # See ?example_isolates. -# output of the `key_antibiotics` function could be like this: +# output of the `key_antibiotics()` function could be like this: strainA <- "SSSRR.S.R..S" strainB <- "SSSIRSSSRSSS" -# can those strings can be compared with: +# those strings can be compared with: key_antibiotics_equal(strainA, strainB) # TRUE, because I is ignored (as well as missing values) key_antibiotics_equal(strainA, strainB, ignore_I = FALSE) -# FALSE, because I is not ignored and so the 4th value differs +# FALSE, because I is not ignored and so the 4th character differs \donttest{ if (require("dplyr")) { # set key antibiotics to a new variable my_patients <- example_isolates \%>\% - mutate(keyab = key_antibiotics(.)) \%>\% + mutate(keyab = key_antibiotics()) \%>\% # no need to define `x` mutate( # now calculate first isolates - first_regular = first_isolate(., col_keyantibiotics = FALSE), + first_regular = first_isolate(col_keyantibiotics = FALSE), # and first WEIGHTED isolates - first_weighted = first_isolate(., col_keyantibiotics = "keyab") + first_weighted = first_isolate(col_keyantibiotics = "keyab") ) - # Check the difference, in this data set it results in 7\% more isolates: + # Check the difference, in this data set it results in a lot more isolates: sum(my_patients$first_regular, na.rm = TRUE) sum(my_patients$first_weighted, na.rm = TRUE) } diff --git a/man/mdro.Rd b/man/mdro.Rd index db9cd275..acc575ff 100644 --- a/man/mdro.Rd +++ b/man/mdro.Rd @@ -40,7 +40,7 @@ mdr_cmi2012(x, guideline = "CMI2012", ...) eucast_exceptional_phenotypes(x, guideline = "EUCAST", ...) } \arguments{ -\item{x}{data with antibiotic columns, such as \code{amox}, \code{AMX} and \code{AMC}} +\item{x}{a \link{data.frame} with antibiotics columns, like \code{AMX} or \code{amox}. Can be omitted when used inside \code{dplyr} verbs, such as \code{filter()}, \code{mutate()} and \code{summarise()}.} \item{guideline}{a specific guideline to follow. When left empty, the publication by Magiorakos \emph{et al.} (2012, Clinical Microbiology and Infection) will be followed, please see \emph{Details}.} @@ -72,21 +72,29 @@ Ordered \link{factor} with levels \code{Negative} < \verb{Positive, unconfirmed} Determine which isolates are multidrug-resistant organisms (MDRO) according to international and national guidelines. } \details{ +These functions are context-aware when used inside \code{dplyr} verbs, such as \code{filter()}, \code{mutate()} and \code{summarise()}. This means that then the \code{x} parameter can be omitted, please see \emph{Examples}. + For the \code{pct_required_classes} argument, values above 1 will be divided by 100. This is to support both fractions (\code{0.75} or \code{3/4}) and percentages (\code{75}). Currently supported guidelines are (case-insensitive): \itemize{ -\item \code{guideline = "CMI2012"}\cr +\item \code{guideline = "CMI2012"} (default) + Magiorakos AP, Srinivasan A \emph{et al.} "Multidrug-resistant, extensively drug-resistant and pandrug-resistant bacteria: an international expert proposal for interim standard definitions for acquired resistance." Clinical Microbiology and Infection (2012) (\href{https://www.clinicalmicrobiologyandinfection.com/article/S1198-743X(14)61632-3/fulltext}{link}) -\item \code{guideline = "EUCAST3.2"} (or simply \code{guideline = "EUCAST"})\cr +\item \code{guideline = "EUCAST3.2"} (or simply \code{guideline = "EUCAST"}) + The European international guideline - EUCAST Expert Rules Version 3.2 "Intrinsic Resistance and Unusual Phenotypes" (\href{https://www.eucast.org/fileadmin/src/media/PDFs/EUCAST_files/Expert_Rules/2020/Intrinsic_Resistance_and_Unusual_Phenotypes_Tables_v3.2_20200225.pdf}{link}) -\item \code{guideline = "EUCAST3.1"}\cr +\item \code{guideline = "EUCAST3.1"} + The European international guideline - EUCAST Expert Rules Version 3.1 "Intrinsic Resistance and Exceptional Phenotypes Tables" (\href{https://www.eucast.org/fileadmin/src/media/PDFs/EUCAST_files/Expert_Rules/Expert_rules_intrinsic_exceptional_V3.1.pdf}{link}) -\item \code{guideline = "TB"}\cr +\item \code{guideline = "TB"} + The international guideline for multi-drug resistant tuberculosis - World Health Organization "Companion handbook to the WHO guidelines for the programmatic management of drug-resistant tuberculosis" (\href{https://www.who.int/tb/publications/pmdt_companionhandbook/en/}{link}) -\item \code{guideline = "MRGN"}\cr +\item \code{guideline = "MRGN"} + The German national guideline - Mueller et al. (2015) Antimicrobial Resistance and Infection Control 4:7. DOI: 10.1186/s13756-015-0047-6 -\item \code{guideline = "BRMO"}\cr +\item \code{guideline = "BRMO"} + The Dutch national guideline - Rijksinstituut voor Volksgezondheid en Milieu "WIP-richtlijn BRMO (Bijzonder Resistente Micro-Organismen) (ZKH)" (\href{https://www.rivm.nl/wip-richtlijn-brmo-bijzonder-resistente-micro-organismen-zkh}{link}) } @@ -140,10 +148,12 @@ if (require("dplyr")) { mdro() \%>\% table() + # no need to define `x` when used inside dplyr verbs: example_isolates \%>\% - mutate(EUCAST = eucast_exceptional_phenotypes(.), - BRMO = brmo(.), - MRGN = mrgn(.)) + mutate(MDRO = mdro(), + EUCAST = eucast_exceptional_phenotypes(), + BRMO = brmo(), + MRGN = mrgn()) } } } diff --git a/man/resistance_predict.Rd b/man/resistance_predict.Rd index 94ee7d5e..d14e56e8 100644 --- a/man/resistance_predict.Rd +++ b/man/resistance_predict.Rd @@ -47,7 +47,7 @@ ggplot_rsi_predict( ) } \arguments{ -\item{x}{a \link{data.frame} containing isolates.} +\item{x}{a \link{data.frame} containing isolates. Can be omitted when used inside \code{dplyr} verbs, such as \code{filter()}, \code{mutate()} and \code{summarise()}.} \item{col_ab}{column name of \code{x} containing antimicrobial interpretations (\code{"R"}, \code{"I"} and \code{"S"})} diff --git a/vignettes/EUCAST.Rmd b/vignettes/EUCAST.Rmd index 84f1c90a..6f2bcef7 100644 --- a/vignettes/EUCAST.Rmd +++ b/vignettes/EUCAST.Rmd @@ -47,7 +47,17 @@ oops eucast_rules(oops, info = FALSE) ``` -EUCAST rules can not only be used for correction, they can also be used for filling in known resistance and susceptibility based on results of other antimicrobials drugs. This process is called *interpretive reading* and is part of the `eucast_rules()` function as well: +A more convenient function is `mo_is_intrinsic_resistant()` that uses the same guideline, but allows to check for one or more specific microorganisms or antibiotics: + +```{r, warning = FALSE, message = FALSE} +mo_is_intrinsic_resistant(c("Klebsiella", "Escherichia"), + "ampicillin") + +mo_is_intrinsic_resistant("Klebsiella", + c("ampicillin", "kanamycin")) +``` + +EUCAST rules can not only be used for correction, they can also be used for filling in known resistance and susceptibility based on results of other antimicrobials drugs. This process is called *interpretive reading*, is basically a form of imputation, and is part of the `eucast_rules()` function as well: ```{r, warning = FALSE, message = FALSE} data <- data.frame(mo = c("Staphylococcus aureus", diff --git a/vignettes/MDR.Rmd b/vignettes/MDR.Rmd index ec2d839a..4a26b9ec 100644 --- a/vignettes/MDR.Rmd +++ b/vignettes/MDR.Rmd @@ -32,20 +32,30 @@ For WHONET data (and most other data), all settings are automatically set correc The function support multiple guidelines. You can select a guideline with the `guideline` parameter. Currently supported guidelines are (case-insensitive): * `guideline = "CMI2012"` (default) - + Magiorakos AP, Srinivasan A *et al.* "Multidrug-resistant, extensively drug-resistant and pandrug-resistant bacteria: an international expert proposal for interim standard definitions for acquired resistance." Clinical Microbiology and Infection (2012) ([link](https://www.clinicalmicrobiologyandinfection.com/article/S1198-743X(14)61632-3/fulltext)) -* `guideline = "EUCAST"` +* `guideline = "EUCAST3.2"` (or simply `guideline = "EUCAST"`) + + The European international guideline - EUCAST Expert Rules Version 3.2 "Intrinsic Resistance and Unusual Phenotypes" ([link](https://www.eucast.org/fileadmin/src/media/PDFs/EUCAST_files/Expert_Rules/2020/Intrinsic_Resistance_and_Unusual_Phenotypes_Tables_v3.2_20200225.pdf)) + +* `guideline = "EUCAST3.1"` + The European international guideline - EUCAST Expert Rules Version 3.1 "Intrinsic Resistance and Exceptional Phenotypes Tables" ([link](https://www.eucast.org/fileadmin/src/media/PDFs/EUCAST_files/Expert_Rules/Expert_rules_intrinsic_exceptional_V3.1.pdf)) + * `guideline = "TB"` - + The international guideline for multi-drug resistant tuberculosis - World Health Organization "Companion handbook to the WHO guidelines for the programmatic management of drug-resistant tuberculosis" ([link](https://www.who.int/tb/publications/pmdt_companionhandbook/en/)) + * `guideline = "MRGN"` + + The German national guideline - Mueller et al. (2015) Antimicrobial Resistance and Infection Control 4:7. DOI: 10.1186/s13756-015-0047-6 - The German national guideline - Mueller et al. (2015) Antimicrobial Resistance and Infection Control 4:7. ([link](https://doi.org/10.1186/s13756-015-0047-6)) * `guideline = "BRMO"` + + The Dutch national guideline - Rijksinstituut voor Volksgezondheid en Milieu "WIP-richtlijn BRMO (Bijzonder Resistente Micro-Organismen) (ZKH)" ([link](https://www.rivm.nl/wip-richtlijn-brmo-bijzonder-resistente-micro-organismen-zkh)) - The Dutch national guideline - Rijksinstituut voor Volksgezondheid en Milieu "WIP-richtlijn BRMO (Bijzonder Resistente Micro-Organismen) [ZKH]" ([link](https://www.rivm.nl/Documenten_en_publicaties/Professioneel_Praktisch/Richtlijnen/Infectieziekten/WIP_Richtlijnen/WIP_Richtlijnen/Ziekenhuizen/WIP_richtlijn_BRMO_Bijzonder_Resistente_Micro_Organismen_ZKH)) +Please suggest your own (country-specific) guidelines by letting us know: . #### Examples
    1 Mono-resistant326265.24%326265.24%331366.26%331366.26%
    2 Negative66413.28%392678.52%63112.62%394478.88%
    3 Multi-drug-resistant60912.18%453590.70%57511.50%451990.38%
    4 Poly-resistant2835.66%481896.36%2755.50%479495.88%
    5 Extensively drug-resistant1823.64%2064.12% 5000 100.00%
    x

    a data.frame containing isolates.

    a data.frame containing isolates. Can be omitted when used inside dplyr verbs, such as filter(), mutate() and summarise().

    col_date
    x

    a data.frame with antibiotics columns, like AMX or amox

    a data.frame with antibiotics columns, like AMX or amox. Can be omitted when used inside dplyr verbs, such as filter(), mutate() and summarise().

    col_mo
    x

    data with antibiotic columns, such as amox, AMX and AMC

    a data.frame with antibiotics columns, like AMX or amox. Can be omitted when used inside dplyr verbs, such as filter(), mutate() and summarise().

    guideline
    x

    a data.frame containing isolates.

    a data.frame containing isolates. Can be omitted when used inside dplyr verbs, such as filter(), mutate() and summarise().

    col_ab