Browse Source

(v1.4.0.9032) auto-data guessing for functions

new-mo-algorithm
parent
commit
1bdb136b3a
  1. 2
      .github/workflows/check.yaml
  2. 4
      DESCRIPTION
  3. 32
      NEWS.md
  4. 23
      R/aa_helper_functions.R
  5. 7
      R/ab_class_selectors.R
  6. 8
      R/eucast_rules.R
  7. 18
      R/first_isolate.R
  8. 3
      R/globals.R
  9. 3
      R/is_new_episode.R
  10. 26
      R/key_antibiotics.R
  11. 2
      R/like.R
  12. 74
      R/mdro.R
  13. 44
      R/mo_property.R
  14. 28
      R/rsi.R
  15. 10
      R/zzz.R
  16. 2
      docs/404.html
  17. 2
      docs/LICENSE-text.html
  18. 17
      docs/articles/EUCAST.html
  19. 76
      docs/articles/MDR.html
  20. 2
      docs/articles/index.html
  21. 2
      docs/authors.html
  22. 2
      docs/index.html
  23. 186
      docs/news/index.html
  24. 2
      docs/pkgdown.yml
  25. 11
      docs/reference/first_isolate.html
  26. 2
      docs/reference/index.html
  27. 45
      docs/reference/is_new_episode.html
  28. 25
      docs/reference/key_antibiotics.html
  29. 39
      docs/reference/mdro.html
  30. 4
      docs/reference/resistance_predict.html
  31. 2
      docs/survey.html
  32. 8
      man/first_isolate.Rd
  33. 3
      man/is_new_episode.Rd
  34. 20
      man/key_antibiotics.Rd
  35. 30
      man/mdro.Rd
  36. 2
      man/resistance_predict.Rd
  37. 12
      vignettes/EUCAST.Rmd
  38. 20
      vignettes/MDR.Rmd

2
.github/workflows/check.yaml

@ -64,7 +64,7 @@ jobs: @@ -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

4
DESCRIPTION

@ -1,6 +1,6 @@ @@ -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"),

32
NEWS.md

@ -1,28 +1,29 @@ @@ -1,28 +1,29 @@
# AMR 1.4.0.9031
## <small>Last updated: 3 December 2020</small>
# AMR 1.4.0.9032
## <small>Last updated: 7 December 2020</small>
### 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 @@ @@ -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

23
R/aa_helper_functions.R

@ -251,7 +251,7 @@ word_wrap <- function(..., @@ -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, @@ -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() { @@ -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 = " ") { @@ -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, ...) { @@ -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

7
R/ab_class_selectors.R

@ -179,10 +179,11 @@ ab_selector <- function(ab_class, function_name) { @@ -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)
}

8
R/eucast_rules.R

@ -620,8 +620,8 @@ eucast_rules <- function(x, @@ -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, @@ -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, @@ -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,

18
R/first_isolate.R

@ -27,7 +27,7 @@ @@ -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 @@ @@ -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 @@ @@ -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 @@ @@ -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, @@ -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, @@ -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, @@ -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

3
R/globals.R

@ -23,7 +23,8 @@ @@ -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",

3
R/is_new_episode.R

@ -43,7 +43,7 @@ @@ -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 @@ @@ -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)

26
R/key_antibiotics.R

@ -25,9 +25,9 @@ @@ -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 @@ @@ -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 @@ @@ -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, @@ -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)

2
R/like.R

@ -75,7 +75,7 @@ like <- function(x, pattern, ignore.case = TRUE) { @@ -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)
}

74
R/mdro.R

@ -27,6 +27,7 @@ @@ -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 @@ @@ -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
#' * `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"`)\cr
#'
#' * `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"`\cr
#'
#' * `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"`\cr
#'
#' * `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"`\cr
#'
#' * `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"`\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 = "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: <https://github.com/msberends/AMR/issues/new>.
#'
#' **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 @@ @@ -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, @@ -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, @@ -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, @@ -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, @@ -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, @@ -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", ...) { @@ -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", ...) { @@ -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", ...) { @@ -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", ...) { @@ -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", ...)

44
R/mo_property.R

@ -372,11 +372,9 @@ mo_is_intrinsic_resistant <- function(x, ab, language = get_locale(), ...) { @@ -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(), ...) { @@ -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, ...) { @@ -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)
}
}

28
R/rsi.R

@ -354,7 +354,7 @@ as.rsi.mic <- function(x, @@ -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, @@ -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, @@ -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, @@ -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),

10
R/zzz.R

@ -36,6 +36,10 @@ @@ -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 @@ @@ -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

2
docs/404.html

@ -81,7 +81,7 @@ @@ -81,7 +81,7 @@
</button>
<span class="navbar-brand">
<a class="navbar-link" href="https://msberends.github.io/AMR//index.html">AMR (for R)</a>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.4.0.9031</span>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.4.0.9032</span>
</span>
</div>

2
docs/LICENSE-text.html

@ -81,7 +81,7 @@ @@ -81,7 +81,7 @@
</button>
<span class="navbar-brand">
<a class="navbar-link" href="index.html">AMR (for R)</a>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.4.0.9031</span>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.4.0.9032</span>
</span>
</div>

17
docs/articles/EUCAST.html

@ -39,7 +39,7 @@ @@ -39,7 +39,7 @@
</button>
<span class="navbar-brand">
<a class="navbar-link" href="../index.html">AMR (for R)</a>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.4.0.9000</span>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.4.0.9032</span>
</span>
</div>
@ -228,8 +228,17 @@ @@ -228,8 +228,17 @@
<span class="co"># mo ampicillin</span>
<span class="co"># 1 Klebsiella R</span>
<span class="co"># 2 Escherichia S</span></pre></div>
<p>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 <em>interpretive reading</em> and is part of the <code><a href="../reference/eucast_rules.html">eucast_rules()</a></code> function as well:</p>
<p>A more convenient function is <code><a href="../reference/mo_property.html">mo_is_intrinsic_resistant()</a></code> that uses the same guideline, but allows to check for one or more specific microorganisms or antibiotics:</p>
<div class="sourceCode" id="cb2"><pre class="downlit">
<span class="fu"><a href="../reference/mo_property.html">mo_is_intrinsic_resistant</a></span><span class="op">(</span><span class="fu"><a href="https://rdrr.io/r/base/c.html">c</a></span><span class="op">(</span><span class="st">"Klebsiella"</span>, <span class="st">"Escherichia"</span><span class="op">)</span>,
<span class="st">"ampicillin"</span><span class="op">)</span>
<span class="co"># [1] TRUE FALSE</span>
<span class="fu"><a href="../reference/mo_property.html">mo_is_intrinsic_resistant</a></span><span class="op">(</span><span class="st">"Klebsiella"</span>,
<span class="fu"><a href="https://rdrr.io/r/base/c.html">c</a></span><span class="op">(</span><span class="st">"ampicillin"</span>, <span class="st">"kanamycin"</span><span class="op">)</span><span class="op">)</span>
<span class="co"># [1] TRUE FALSE</span></pre></div>
<p>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 <em>interpretive reading</em>, is basically a form of imputation, and is part of the <code><a href="../reference/eucast_rules.html">eucast_rules()</a></code> function as well:</p>
<div class="sourceCode" id="cb3"><pre class="downlit">
<span class="va">data</span> <span class="op">&lt;-</span> <span class="fu"><a href="https://rdrr.io/r/base/data.frame.html">data.frame</a></span><span class="op">(</span>mo <span class="op">=</span> <span class="fu"><a href="https://rdrr.io/r/base/c.html">c</a></span><span class="op">(</span><span class="st">"Staphylococcus aureus"</span>,
<span class="st">"Enterococcus faecalis"</span>,
<span class="st">"Escherichia coli"</span>,
@ -243,7 +252,7 @@ @@ -243,7 +252,7 @@
PEN <span class="op">=</span> <span class="st">"S"</span>, <span class="co"># Benzylenicillin</span>
FOX <span class="op">=</span> <span class="st">"S"</span>, <span class="co"># Cefoxitin</span>
stringsAsFactors <span class="op">=</span> <span class="cn">FALSE</span><span class="op">)</span></pre></div>
<div class="sourceCode" id="cb3"><pre class="downlit">
<div class="sourceCode" id="cb4"><pre class="downlit">
<span class="va">data</span></pre></div>
<table class="table">
<thead><tr class="header">
@ -309,7 +318,7 @@ @@ -309,7 +318,7 @@
</tr>
</tbody>
</table>
<div class="sourceCode" id="cb4"><pre class="downlit">
<div class="sourceCode" id="cb5"><pre class="downlit">
<span class="fu"><a href="../reference/eucast_rules.html">eucast_rules</a></span><span class="op">(</span><span class="va">data</span><span class="op">)</span></pre></div>
<table class="table">
<thead><tr class="header">

76
docs/articles/MDR.html

@ -39,7 +39,7 @@ @@ -39,7 +39,7 @@
</button>
<span class="navbar-brand">
<a class="navbar-link" href="../index.html">AMR (for R)</a>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.4.0.9000</span>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.4.0.9032</span>
</span>
</div>
@ -217,7 +217,11 @@ @@ -217,7 +217,11 @@
<p>Magiorakos AP, Srinivasan A <em>et al.</em> “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) (<a href="https://www.clinicalmicrobiologyandinfection.com/article/S1198-743X(14)61632-3/fulltext">link</a>)</p>
</li>
<li>
<p><code>guideline = "EUCAST"</code></p>
<p><code>guideline = "EUCAST3.2"</code> (or simply <code>guideline = "EUCAST"</code>)</p>
<p>The European international guideline - EUCAST Expert Rules Version 3.2 “Intrinsic Resistance and Unusual Phenotypes” (<a 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</a>)</p>
</li>
<li>
<p><code>guideline = "EUCAST3.1"</code></p>
<p>The European international guideline - EUCAST Expert Rules Version 3.1 “Intrinsic Resistance and Exceptional Phenotypes Tables” (<a href="https://www.eucast.org/fileadmin/src/media/PDFs/EUCAST_files/Expert_Rules/Expert_rules_intrinsic_exceptional_V3.1.pdf">link</a>)</p>
</li>
<li>
@ -226,13 +230,14 @@ @@ -226,13 +230,14 @@
</li>
<li>
<p><code>guideline = "MRGN"</code></p>
<p>The German national guideline - Mueller et al. (2015) Antimicrobial Resistance and Infection Control 4:7. (<a href="https://doi.org/10.1186/s13756-015-0047-6">link</a>)</p>
<p>The German national guideline - Mueller et al. (2015) Antimicrobial Resistance and Infection Control 4:7. DOI: 10.1186/s13756-015-0047-6</p>
</li>
<li>
<p><code>guideline = "BRMO"</code></p>
<p>The Dutch national guideline - Rijksinstituut voor Volksgezondheid en Milieu “WIP-richtlijn BRMO (Bijzonder Resistente Micro-Organismen) [ZKH]” (<a href="https://www.rivm.nl/Documenten_en_publicaties/Professioneel_Praktisch/Richtlijnen/Infectieziekten/WIP_Richtlijnen/WIP_Richtlijnen/Ziekenhuizen/WIP_richtlijn_BRMO_Bijzonder_Resistente_Micro_Organismen_ZKH">link</a>)</p>
<p>The Dutch national guideline - Rijksinstituut voor Volksgezondheid en Milieu “WIP-richtlijn BRMO (Bijzonder Resistente Micro-Organismen) (ZKH)” (<a href="https://www.rivm.nl/wip-richtlijn-brmo-bijzonder-resistente-micro-organismen-zkh">link</a>)</p>
</li>
</ul>
<p>Please suggest your own (country-specific) guidelines by letting us know: <a href="https://github.com/msberends/AMR/issues/new" class="uri">https://github.com/msberends/AMR/issues/new</a>.</p>
</div>
<div id="examples" class="section level4">
<h4 class="hasAnchor">
@ -246,8 +251,8 @@ @@ -246,8 +251,8 @@
<span class="va">example_isolates</span> <span class="op">%&gt;%</span>
<span class="fu"><a href="../reference/mdro.html">mdro</a></span><span class="op">(</span><span class="op">)</span> <span class="op">%&gt;%</span>
<span class="fu"><a href="https://rdrr.io/pkg/cleaner/man/freq.html">freq</a></span><span class="op">(</span><span class="op">)</span> <span class="co"># show frequency table of the result</span>
<span class="co"># Warning in mdro(.): NA introduced for isolates where the available percentage of</span>
<span class="co"># antimicrobial classes was below 50% (set with `pct_required_classes`)</span></pre></div>
<span class="co"># 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</span>
<span class="co"># classes was below 50% (set with `pct_required_classes`)</span></pre></div>
<p><strong>Frequency table</strong></p>
<p>Class: factor &gt; ordered (numeric)<br>
Length: 2,000<br>
@ -313,26 +318,27 @@ Unique: 2</p> @@ -313,26 +318,27 @@ Unique: 2</p>
<div class="sourceCode" id="cb5"><pre class="downlit">
<span class="fu"><a href="https://rdrr.io/r/utils/head.html">head</a></span><span class="op">(</span><span class="va">my_TB_data</span><span class="op">)</span>
<span class="co"># rifampicin isoniazid gatifloxacin ethambutol pyrazinamide moxifloxacin</span>
<span class="co"># 1 R S S R R S</span>
<span class="co"># 2 I R S R S I</span>
<span class="co"># 3 R R S S S S</span>
<span class="co"># 4 R R S I S S</span>
<span class="co"># 5 S I R S R S</span>
<span class="co"># 6 S S S R S S</span>
<span class="co"># 1 S I R S R R</span>
<span class="co"># 2 R S S R I S</span>
<span class="co"># 3 I R I S R S</span>
<span class="co"># 4 I S S R S R</span>
<span class="co"># 5 R R S S R R</span>
<span class="co"># 6 S R I S S I</span>
<span class="co"># kanamycin</span>
<span class="co"># 1 S</span>
<span class="co"># 1 R</span>
<span class="co"># 2 S</span>
<span class="co"># 3 S</span>
<span class="co"># 4 S</span>
<span class="co"># 5 S</span>
<span class="co"># 6 R</span></pre></div>
<span class="co"># 4 R</span>
<span class="co"># 5 R</span>
<span class="co"># 6 S</span></pre></div>
<p>We can now add the interpretation of MDR-TB to our data set. You can use:</p>
<div class="sourceCode" id="cb6"><pre class="downlit">
<span class="fu"><a href="../reference/mdro.html">mdro</a></span><span class="op">(</span><span class="va">my_TB_data</span>, guideline <span class="op">=</span> <span class="st">"TB"</span><span class="op">)</span></pre></div>
<p>or its shortcut <code><a href="../reference/mdro.html">mdr_tb()</a></code>:</p>
<div class="sourceCode" id="cb7"><pre class="downlit">
<span class="va">my_TB_data</span><span class="op">$</span><span class="va">mdr</span> <span class="op">&lt;-</span> <span class="fu"><a href="../reference/mdro.html">mdr_tb</a></span><span class="op">(</span><span class="va">my_TB_data</span><span class="op">)</span>
<span class="co"># NOTE: No column found as input for `col_mo`, assuming all records contain Mycobacterium tuberculosis.</span></pre></div>
<span class="co"># NOTE: No column found as input for `col_mo`, assuming all records contain</span>
<span class="co"># Mycobacterium tuberculosis.</span></pre></div>
<p>Create a frequency table of the results:</p>
<div class="sourceCode" id="cb8"><pre class="downlit">
<span class="fu"><a href="https://rdrr.io/pkg/cleaner/man/freq.html">freq</a></span><span class="op">(</span><span class="va">my_TB_data</span><span class="op">$</span><span class="va">mdr</span><span class="op">)</span></pre></div>
@ -355,40 +361,40 @@ Unique: 5</p> @@ -355,40 +361,40 @@ Unique: 5</p>
<tr class="odd">
<td align="left">1</td>
<td align="left">Mono-resistant</td>
<td align="right">3262</td>
<td align="right">65.24%</td>
<td align="right">3262</td>
<td align="right">65.24%</td>
<td align="right">3313</td>
<td align="right">66.26%</td>
<td align="right">3313</td>
<td align="right">66.26%</td>
</tr>
<tr class="even">
<td align="left">2</td>
<td align="left">Negative</td>
<td align="right">664</td>
<td align="right">13.28%</td>
<td align="right">3926</td>
<td align="right">78.52%</td>
<td align="right">631</td>
<td align="right">12.62%</td>
<td align="right">3944</td>
<td align="right">78.88%</td>
</tr>
<tr class="odd">
<td align="left">3</td>
<td align="left">Multi-drug-resistant</td>
<td align="right">609</td>
<td align="right">12.18%</td>
<td align="right">4535</td>
<td align="right">90.70%</td>
<td align="right">575</td>
<td align="right">11.50%</td>
<td align="right">4519</td>
<td align="right">90.38%</td>
</tr>
<tr class="even">
<td align="left">4</td>
<td align="left">Poly-resistant</td>
<td align="right">283</td>
<td align="right">5.66%</td>
<td align="right">4818</td>
<td align="right">96.36%</td>
<td align="right">275</td>
<td align="right">5.50%</td>
<td align="right">4794</td>
<td align="right">95.88%</td>
</tr>
<tr class="odd">
<td align="left">5</td>
<td align="left">Extensively drug-resistant</td>
<td align="right">182</td>
<td align="right">3.64%</td>
<td align="right">206</td>
<td align="right">4.12%</td>
<td align="right">5000</td>
<td align="right">100.00%</td>
</tr>

2
docs/articles/index.html

@ -81,7 +81,7 @@ @@ -81,7 +81,7 @@
</button>
<span class="navbar-brand">
<a class="navbar-link" href="../index.html">AMR (for R)</a>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.4.0.9031</span>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.4.0.9032</span>
</span>
</div>

2
docs/authors.html

@ -81,7 +81,7 @@ @@ -81,7 +81,7 @@
</button>
<span class="navbar-brand">
<a class="navbar-link" href="index.html">AMR (for R)</a>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.4.0.9031</span>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.4.0.9032</span>
</span>
</div>

2
docs/index.html

@ -43,7 +43,7 @@ @@ -43,7 +43,7 @@
</button>
<span class="navbar-brand">
<a class="navbar-link" href="index.html">AMR (for R)</a>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.4.0.9031</span>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.4.0.9032</span>
</span>
</div>

186
docs/news/index.html

@ -81,7 +81,7 @@ @@ -81,7 +81,7 @@
</button>
<span class="navbar-brand">
<a class="navbar-link" href="../index.html">AMR (for R)</a>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.4.0.9031</span>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.4.0.9032</span>
</span>
</div>
@ -236,13 +236,13 @@ @@ -236,13 +236,13 @@
<small>Source: <a href='https://github.com/msberends/AMR/blob/master/NEWS.md'><code>NEWS.md</code></a></small>
</div>
<div id="amr-1409031" class="section level1">
<h1 class="page-header" data-toc-text="1.4.0.9031">
<a href="#amr-1409031" class="anchor"></a>AMR 1.4.0.9031<small> Unreleased </small>
<div id="amr-1409032" class="section level1">
<h1 class="page-header" data-toc-text="1.4.0.9032">
<a href="#amr-1409032" class="anchor"></a>AMR 1.4.0.9032<small> Unreleased </small>
</h1>
<div id="last-updated-3-december-2020" class="section level2">
<div id="last-updated-7-december-2020" class="section level2">
<h2 class="hasAnchor">
<a href="#last-updated-3-december-2020" class="anchor"></a><small>Last updated: 3 December 2020</small>
<a href="#last-updated-7-december-2020" class="anchor"></a><small>Last updated: 7 December 2020</small>
</h2>
<div id="new" class="section level3">
<h3 class="hasAnchor">
@ -251,42 +251,42 @@ @@ -251,42 +251,42 @@
<li>
<p>Function <code><a href="../reference/is_new_episode.html">is_new_episode()</a></code> to determine patient episodes which are not necessarily based on microorganisms. It also supports grouped variables with e.g. <code><a href="https://dplyr.tidyverse.org/reference/mutate.html">mutate()</a></code>, <code><a href="https://dplyr.tidyverse.org/reference/filter.html">filter()</a></code> and <code><a href="https://dplyr.tidyverse.org/reference/summarise.html">summarise()</a></code> of the <code>dplyr</code> package:</p>
<div class="sourceCode" id="cb1"><pre class="downlit">
<span class="kw"><a href="https://rdrr.io/r/base/library.html">library</a></span><span class="op">(</span><span class="va"><a href="https://dplyr.tidyverse.org">dplyr</a></span><span class="op">)</span>
<span class="va">example_isolates</span> <span class="op">%&gt;%</span>
<span class="fu">group_by</span><span class="op">(</span><span class="va">patient_id</span>, <span class="va">hospital_id</span><span class="op">)</span> <span class="op">%&gt;%</span>
<span class="fu"><a href="https://rdrr.io/r/stats/filter.html">filter</a></span><span class="op">(</span><span class="fu"><a href="../reference/is_new_episode.html">is_new_episode</a></span><span class="op">(</span><span class="va">date</span>, episode_days <span class="op">=</span> <span class="fl">60</span><span class="op">)</span><span class="op">)</span></pre></div>
</li>
<li>
<p>Functions <code><a href="../reference/mo_property.html">mo_is_gram_negative()</a></code> and <code><a href="../reference/mo_property.html">mo_is_gram_positive()</a></code> as wrappers around <code><a href="../reference/mo_property.html">mo_gramstain()</a></code>. They always return <code>TRUE</code> or <code>FALSE</code> (except when the input is <code>NA</code> or the MO code is <code>UNKNOWN</code>), thus always return <code>FALSE</code> for species outside the taxonomic kingdom of Bacteria. They can even determine the column with microorganisms themselves when used inside <code>dplyr</code> verbs:</p>
<div class="sourceCode" id="cb2"><pre class="downlit">
<span class="va">example_isolates</span> <span class="op">%&gt;%</span>
<span class="fu"><a href="https://rdrr.io/r/stats/filter.html">filter</a></span><span class="op">(</span><span class="fu"><a href="../reference/mo_property.html">mo_is_gram_positive</a></span><span class="op">(</span><span class="op">)</span><span class="op">)</span>
<span class="co">#&gt; NOTE: Using column `mo` as input for mo_is_gram_positive()</span></pre></div>
</li>
<li>
<p>Function <code><a href="../reference/mo_property.html">mo_is_intrinsic_resistant()</a></code> to test for intrinsic resistance, based on <a href="https://www.eucast.org/expert_rules_and_intrinsic_resistance/">EUCAST Intrinsic Resistance and Unusual Phenotypes v3.2</a> from 2020. As with the new <code>mo_is_gram_*()</code> functions, if you have the <code>dplyr</code> package installed the column with microorganisms will be automatically determined when used inside <code>dplyr</code> verbs:</p>
<div class="sourceCode" id="cb3"><pre class="downlit">
<span class="va">example_isolates</span> <span class="op">%&gt;%</span>
<span class="fu"><a href="https://rdrr.io/r/stats/filter.html">filter</a></span><span class="op">(</span><span class="fu"><a href="../reference/mo_property.html">mo_is_intrinsic_resistant</a></span><span class="op">(</span>ab <span class="op">=</span> <span class="st">"Vancomycin"</span><span class="op">)</span><span class="op">)</span>
<span class="co">#&gt; NOTE: Using column `mo` as input for mo_is_intrinsic_resistant()</span></pre></div>
<span class="fu"><a href="https://dplyr.tidyverse.org/reference/group_by.html">group_by</a></span><span class="op">(</span><span class="va">patient_id</span>, <span class="va">hospital_id</span><span class="op">)</span> <span class="op">%&gt;%</span>
<span class="fu"><a href="https://dplyr.tidyverse.org/reference/filter.html">filter</a></span><span class="op">(</span><span class="fu"><a href="../reference/is_new_episode.html">is_new_episode</a></span><span class="op">(</span><span class="va">date</span>, episode_days <span class="op">=</span> <span class="fl">60</span><span class="op">)</span><span class="op">)</span></pre></div>
</li>
<li><p>Functions <code><a href="../reference/mo_property.html">mo_is_gram_negative()</a></code> and <code><a href="../reference/mo_property.html">mo_is_gram_positive()</a></code> as wrappers around <code><a href="../reference/mo_property.html">mo_gramstain()</a></code>. They always return <code>TRUE</code> or <code>FALSE</code> (except when the input is <code>NA</code> or the MO code is <code>UNKNOWN</code>), thus always return <code>FALSE</code> for species outside the taxonomic kingdom of Bacteria.</p></li>
<li><p>Function <code><a href="../reference/mo_property.html">mo_is_intrinsic_resistant()</a></code> to test for intrinsic resistance, based on <a href="https://www.eucast.org/expert_rules_and_intrinsic_resistance/">EUCAST Intrinsic Res