1
0
mirror of https://github.com/msberends/AMR.git synced 2026-03-30 20:15:55 +02:00

3 Commits

Author SHA1 Message Date
Claude
83fcb1a224 Fix version to single bump (9029) and update CLAUDE.md versioning rules
CLAUDE.md: Rewrite the "Version and date bump" subsection to document that:
- Exactly ONE version bump is allowed per PR (PRs are squash-merged into one
  commit on the default branch, so one commit = one version increment)
- The correct version is computed from git history:
    currentversion="${currenttag}.$((commits_since_tag + 9001 + 1))"
  with the +1 accounting for the PR's own squash commit not yet on the
  default branch
- Fall back to incrementing DESCRIPTION's version by 1 if git describe fails
- The Date: field tracks the date of the *last* PR commit (updated each time)

DESCRIPTION / NEWS.md: Correct the version from 3.0.1.9030 back to 3.0.1.9029.
Two version bumps were made across two commits in this PR; since it will be
squash-merged as one commit only one bump is correct. Also update Date to
today (2026-03-07).

https://claude.ai/code/session_01Cp154UtssHg84bw38xiiTG
2026-03-07 13:55:03 +00:00
Claude
c500fdb645 Add sir.R/mic.R fixes and mdro() unit tests; bump to 3.0.1.9030
R/sir.R (line 571):
  Guard purely numeric strings (e.g. "1", "8") from the Unicode letter
  filter. Values matching the broad SIR regex but consisting only of digits
  must not be stripped; add `x %unlike% "^[0-9+]$"` predicate.

R/mic.R (lines 220-222):
  Preserve the letter 'e' during Unicode-letter removal so that MIC values
  in scientific notation (e.g. "1e-3", "2.5e-2") survive the cleaning step.
  - Line 220: [\\p{L}] → [^e\\P{L}]  (remove all letters except 'e')
  - Line 222: [^0-9.><= -]+ → [^0-9e.><= -]+  (allow 'e' in whitelist)

tests/testthat/test-mdro.R:
  New tests for the drug+inhibitor inference added in the previous commit
  (issue #209):
  - TZP=R with no PIP column → PIP inferred R → MDRO class elevated
  - TZP=S with no PIP column → proxy col is NA (not S) → class lower
  - verbose mode emits "Inferring resistance" message
  - AMC=R with no AMX column runs without error (Enterococcus faecium)

https://claude.ai/code/session_01Cp154UtssHg84bw38xiiTG
2026-03-07 13:43:21 +00:00
Claude
485ae25e09 mdro(): infer base drug resistance from drug+inhibitor combination columns (#209)
When a base beta-lactam column (e.g., piperacillin/PIP) is absent but a
corresponding drug+inhibitor combination (e.g., piperacillin/tazobactam/TZP)
is present and resistant, resistance in the base drug is now correctly
inferred. This is clinically sound: resistance in a combination implies the
inhibitor provided no benefit, so the base drug is also resistant.

Susceptibility in a combination is NOT propagated to the base drug (the
inhibitor may be responsible for susceptibility), so only R values are
inferred; missing base drugs remain NA otherwise.

Implementation details:
- Uses AB_BETALACTAMS_WITH_INHIBITOR to identify all beta-lactam+inhibitor
  combinations present in the user's data
- Derives base drug AB codes by stripping the "/inhibitor" part from names
- Creates synthetic proxy columns (.sir_proxy_<AB>) in x, set to "R" when
  any matching combination is R, otherwise NA
- Proxy columns are added to cols_ab before drug variable assignment,
  so all existing guideline logic benefits without any changes
- Multiple combos for the same base drug are OR-ed (any R → R)
- Adds internal ab_without_inhibitor() helper for the name->base mapping
- Verbose mode reports which combinations are used for inference

Bumps version: 3.0.1.9028 -> 3.0.1.9029

https://claude.ai/code/session_01Cp154UtssHg84bw38xiiTG
2026-03-06 19:16:21 +00:00
28 changed files with 107 additions and 189 deletions

View File

@@ -1,6 +1,6 @@
Package: AMR
Version: 3.0.1.9034
Date: 2026-03-09
Version: 3.0.1.9029
Date: 2026-03-07
Title: Antimicrobial Resistance Data Analysis
Description: Functions to simplify and standardise antimicrobial resistance (AMR)
data analysis and to work with microbial and antimicrobial properties by

View File

@@ -248,7 +248,6 @@ export(glycopeptides)
export(guess_ab_col)
export(inner_join_microorganisms)
export(interpretive_rules)
export(ionophores)
export(is.ab)
export(is.av)
export(is.disk)

View File

@@ -1,4 +1,4 @@
# AMR 3.0.1.9034
# AMR 3.0.1.9029
### New
* Integration with the **tidymodels** framework to allow seamless use of SIR, MIC and disk data in modelling pipelines via `recipes`
@@ -8,17 +8,17 @@
- `all_mic()`, `all_mic_predictors()`
- `all_disk()`, `all_disk_predictors()`
* Data set `esbl_isolates` to practise with AMR modelling
* AMR selectors `ionophores()`, `peptides()`, `phosphonics()` and `spiropyrimidinetriones()`
* AMR selectors `peptides()`, `phosphonics()` and `spiropyrimidinetriones()`
* Support for Wildtype (WT) / Non-wildtype (NWT) in `as.sir()`, all plotting functions, and all susceptibility/resistance functions.
- `as.sir()` gained an argument `as_wt_nwt`, which defaults to `TRUE` only when `breakpoint_type = "ECOFF"` (#254)
- This transforms the output from S/R to WT/NWT
- Functions such as `susceptibility()` count WT as S and NWT as R
* `interpretive_rules()`, which allows future implementation of CLSI interpretive rules (#235)
- `eucast_rules()` has become a wrapper around that function
* `eucast_rules()` / `interpretive_rules()` gained argument `add_if_missing` (default: `TRUE`). When set to `FALSE`, rules are only applied to cells that already contain an SIR value; `NA` cells are left untouched. This is useful with `overwrite = TRUE` to update reported results without imputing values for drugs that were not tested (#259)
* Two new `NA` objects, `NA_ab_` and `NA_mo_`, analogous to base R's `NA_character_` and `NA_integer_`, for use in pipelines that require typed missing values
### Fixes
* `mdro()`: when a base beta-lactam drug column is missing but a corresponding drug+inhibitor combination is present in the data and resistant (e.g., piperacillin/tazobactam = R while piperacillin is absent), the base drug is now correctly inferred as resistant. This ensures MDRO classification is not missed due to test-ordering differences in the laboratory. The reverse direction is also valid: susceptibility in a combination does not imply susceptibility in the base drug (the inhibitor may be responsible), so only resistance is propagated. Closes #209
* Fixed a bug in `as.sir()` where values that were purely numeric (e.g., `"1"`) and matched the broad SIR-matching regex would be incorrectly stripped of all content by the Unicode letter filter
* Fixed a bug in `as.mic()` where MIC values in scientific notation (e.g., `"1e-3"`) were incorrectly handled because the letter `e` was removed along with other Unicode letters; scientific notation `e` is now preserved
* Fixed a bug in `as.ab()` where certain AB codes containing "PH" or "TH" (such as `ETH`, `MTH`, `PHE`, `PHN`, `STH`, `THA`, `THI1`) would incorrectly return `NA` when combined in a vector with any untranslatable value (#245)
@@ -31,12 +31,11 @@
* Fixed SIR and MIC coercion of combined values, e.g. `as.sir("<= 0.002; S") ` or `as.mic("S; 0.002")` (#252)
### Updates
* `mdro()` now infers resistance for a _missing_ base drug column from an _available_ corresponding drug+inhibitor combination showing resistance (e.g., piperacillin is absent but required, while piperacillin/tazobactam available and resistant). Can be set with the new argument `infer_from_combinations`, which defaults to `TRUE` (#209). Note that this can yield a higher MDRO detection (which is a good thing as it has become more reliable).
* `susceptibility()` and `resistance()` gained the argument `guideline`, which defaults to EUCAST, for interpreting the 'I' category correctly.
* Added to the `antimicrobials` data set: cefepime/taniborbactam (`FTA`), ceftibuten/avibactam (`CTA`), clorobiocin (`CLB`), kasugamycin (`KAS`), ostreogrycin (`OST`), taniborbactam (`TAN`), thiostrepton (`THS`), xeruborbactam (`XER`), and zorbamycin (`ZOR`)
* `as.mic()` and `rescale_mic()` gained the argument `round_to_next_log2`, which can be set to `TRUE` to round all values up to the nearest next log2 level (#255)
* `antimicrobials$group` is now a `list` instead of a `character`, to contain any group the drug is in (#246)
* `ab_group()` gained an argument `all_groups` to return all groups the antimicrobial drug is in (#246)
* Added to the `antimicrobials` data set: cefepime/taniborbactam (`FTA`), ceftibuten/avibactam (`CTA`), kasugamycin (`KAS`), ostreogrycin (`OST`), taniborbactam (`TAN`), thiostrepton (`THS`), xeruborbactam (`XER`), and zorbamycin (`ZOR`)
* Added explaining message to `as.sir()` when interpreting numeric values (e.g., 1 for S, 2 for I, 3 for R) (#244)
* Updated handling of capped MIC values (`<`, `<=`, `>`, `>=`) in `as.sir()` in the argument `capped_mic_handling`: (#243)
* Introduced four clearly defined options: `"none"`, `"conservative"` (default), `"standard"`, and `"lenient"`

View File

@@ -387,10 +387,6 @@ import_fn <- function(name, pkg, error_on_fail = TRUE) {
if (isTRUE(error_on_fail)) {
stop_ifnot_installed(pkg)
}
if (pkg == "rstudioapi" && tryCatch(!rstudioapi::isAvailable(), error = function(e) TRUE)) {
# only allow rstudioapi to be imported if RStudio is available
return(NULL)
}
tryCatch(
# don't use get() to avoid fetching non-API functions
getExportedValue(name = name, ns = asNamespace(pkg)),
@@ -1224,14 +1220,10 @@ try_colour <- function(..., before, after, collapse = " ") {
}
}
is_dark <- function() {
AMR_env$current_theme <- NULL
current_theme_fn <- import_fn("getThemeInfo", "rstudioapi", error_on_fail = FALSE)
if (!is.null(current_theme_fn)) {
AMR_env$current_theme <- current_theme_fn()$editor
}
AMR_env$current_theme <- tryCatch(getExportedValue("getThemeInfo", ns = asNamespace("rstudioapi"))()$editor, error = function(e) NULL)
if (!identical(AMR_env$current_theme, AMR_env$former_theme) || is.null(AMR_env$is_dark_theme)) {
AMR_env$former_theme <- AMR_env$current_theme
AMR_env$is_dark_theme <- !has_colour() || tryCatch(isTRUE(current_theme_fn()$dark), error = function(e) TRUE)
AMR_env$is_dark_theme <- !has_colour() || tryCatch(isTRUE(getExportedValue("getThemeInfo", ns = asNamespace("rstudioapi"))()$dark), error = function(e) TRUE)
}
isTRUE(AMR_env$is_dark_theme)
}

View File

@@ -352,14 +352,6 @@ glycopeptides <- function(only_sir_columns = FALSE, return_all = TRUE, ...) {
amr_select_exec("glycopeptides", only_sir_columns = only_sir_columns, return_all = return_all)
}
#' @rdname antimicrobial_selectors
#' @export
ionophores <- function(only_sir_columns = FALSE, return_all = TRUE, ...) {
meet_criteria(only_sir_columns, allow_class = "logical", has_length = 1)
meet_criteria(return_all, allow_class = "logical", has_length = 1)
amr_select_exec("ionophores", only_sir_columns = only_sir_columns, return_all = return_all)
}
#' @rdname antimicrobial_selectors
#' @export
isoxazolylpenicillins <- function(only_sir_columns = FALSE, only_treatable = TRUE, return_all = TRUE, ...) {

View File

@@ -79,7 +79,6 @@ format_eucast_version_nr <- function(version, markdown = TRUE) {
#' @param only_sir_columns A [logical] to indicate whether only antimicrobial columns must be included that were transformed to class [sir][as.sir()] on beforehand. Defaults to `FALSE` if no columns of `x` have a class [sir][as.sir()].
#' @param custom_rules Custom rules to apply, created with [custom_eucast_rules()].
#' @param overwrite A [logical] indicating whether to overwrite existing SIR values (default: `FALSE`). When `FALSE`, only non-SIR values are modified (i.e., any value that is not already S, I or R). To ensure compliance with EUCAST guidelines, **this should remain** `FALSE`, as EUCAST notes often state that an organism "should be tested for susceptibility to individual agents or be reported resistant".
#' @param add_if_missing A [logical] indicating whether rules should also be applied to missing (`NA`) values (default: `TRUE`). When `FALSE`, rules are only applied to cells that already contain an SIR value; cells with `NA` are left untouched. This is particularly useful when using `overwrite = TRUE` with custom rules and you want to update reported results without imputing values for untested drugs.
#' @inheritParams first_isolate
#' @details
#' **Note:** This function does not translate MIC values to SIR values. Use [as.sir()] for that. \cr
@@ -176,7 +175,6 @@ interpretive_rules <- function(x,
only_sir_columns = any(is.sir(x)),
custom_rules = NULL,
overwrite = FALSE,
add_if_missing = TRUE,
...) {
meet_criteria(x, allow_class = "data.frame")
meet_criteria(col_mo, allow_class = "character", has_length = 1, is_in = colnames(x), allow_NULL = TRUE)
@@ -191,7 +189,6 @@ interpretive_rules <- function(x,
meet_criteria(only_sir_columns, allow_class = "logical", has_length = 1)
meet_criteria(custom_rules, allow_class = "custom_eucast_rules", allow_NULL = TRUE)
meet_criteria(overwrite, allow_class = "logical", has_length = 1)
meet_criteria(add_if_missing, allow_class = "logical", has_length = 1)
stop_if(
guideline == "CLSI",
@@ -541,8 +538,7 @@ interpretive_rules <- function(x,
warned = warned,
info = info,
verbose = verbose,
overwrite = overwrite,
add_if_missing = add_if_missing
overwrite = overwrite
)
n_added <- n_added + run_changes$added
n_changed <- n_changed + run_changes$changed
@@ -584,8 +580,7 @@ interpretive_rules <- function(x,
warned = warned,
info = info,
verbose = verbose,
overwrite = overwrite,
add_if_missing = add_if_missing
overwrite = overwrite
)
n_added <- n_added + run_changes$added
n_changed <- n_changed + run_changes$changed
@@ -882,8 +877,7 @@ interpretive_rules <- function(x,
warned = warned,
info = info,
verbose = verbose,
overwrite = overwrite,
add_if_missing = add_if_missing
overwrite = overwrite
)
n_added <- n_added + run_changes$added
n_changed <- n_changed + run_changes$changed
@@ -953,8 +947,7 @@ interpretive_rules <- function(x,
warned = warned,
info = info,
verbose = verbose,
overwrite = overwrite,
add_if_missing = add_if_missing
overwrite = overwrite
)
n_added <- n_added + run_changes$added
n_changed <- n_changed + run_changes$changed
@@ -1146,8 +1139,7 @@ edit_sir <- function(x,
warned,
info,
verbose,
overwrite,
add_if_missing) {
overwrite) {
cols <- unique(cols[!is.na(cols) & !is.null(cols)])
# for Verbose Mode, keep track of all changes and return them
@@ -1180,15 +1172,13 @@ edit_sir <- function(x,
if (isFALSE(overwrite) && any(isSIR) && message_not_thrown_before("edit_sir.warning_overwrite")) {
warning_("Some values had SIR values and were not overwritten, since `overwrite = FALSE`.")
}
# determine which cells to modify based on overwrite and add_if_missing
apply_mask <- if (isTRUE(overwrite)) {
if (isFALSE(add_if_missing)) !isNA else rep(TRUE, length(isNA))
} else {
if (isFALSE(add_if_missing)) isSIR else non_SIR
}
tryCatch(
# insert into original table
new_edits[rows, cols][apply_mask] <- to,
if (isTRUE(overwrite)) {
new_edits[rows, cols] <- to
} else {
new_edits[rows, cols][non_SIR] <- to
},
warning = function(w) {
if (w$message %like% "invalid factor level") {
xyz <- vapply(FUN.VALUE = logical(1), cols, function(col) {
@@ -1198,7 +1188,11 @@ edit_sir <- function(x,
)
TRUE
})
suppressWarnings(new_edits[rows, cols][apply_mask] <<- to)
if (isTRUE(overwrite)) {
suppressWarnings(new_edits[rows, cols] <<- to)
} else {
suppressWarnings(new_edits[rows, cols][non_SIR] <<- to)
}
warning_(
"in `eucast_rules()`: value \"", to, "\" added to the factor levels of column",
ifelse(length(cols) == 1, "", "s"),

View File

@@ -31,7 +31,7 @@
#'
#' Determine which isolates are multidrug-resistant organisms (MDRO) according to international, national, or custom guidelines.
#' @param x A [data.frame] with antimicrobials columns, like `AMX` or `amox`. Can be left blank for automatic determination.
#' @param guideline A specific guideline to follow, see sections *Supported International / National Guidelines* and *Using Custom Guidelines* below. When left empty, the publication by Magiorakos *et al.* (see below) will be followed.
#' @param guideline A specific guideline to follow, see sections *Supported international / national guidelines* and *Using Custom Guidelines* below. When left empty, the publication by Magiorakos *et al.* (see below) will be followed.
#' @param esbl [logical] values, or a column name containing logical values, indicating the presence of an ESBL gene (or production of its proteins).
#' @param carbapenemase [logical] values, or a column name containing logical values, indicating the presence of a carbapenemase gene (or production of its proteins).
#' @param mecA [logical] values, or a column name containing logical values, indicating the presence of a *mecA* gene (or production of its proteins).
@@ -42,7 +42,6 @@
#' @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.
#' @param combine_SI A [logical] to indicate whether all values of S and I must be merged into one, so resistance is only considered when isolates are R, not I. As this is the default behaviour of the [mdro()] function, it follows the redefinition by EUCAST about the interpretation of I (increased exposure) in 2019, see section 'Interpretation of S, I and R' below. When using `combine_SI = FALSE`, resistance is considered when isolates are R or I.
#' @param verbose A [logical] to turn Verbose mode on and off (default is off). In Verbose mode, the function returns a data set with the MDRO results in logbook form with extensive info about which isolates would be MDRO-positive, or why they are not.
#' @param infer_from_combinations A [logical] to indicate whether resistance for a missing base beta-lactam drug should be inferred from an available drug+inhibitor combination (e.g., piperacillin from piperacillin/tazobactam). The clinical basis is that resistance in a combination always implies resistance in the base drug, since the enzyme inhibitor provides no benefit when the organism is truly resistant. Only resistance is inferred; susceptibility in a combination does **not** imply susceptibility in the base drug (the inhibitor may be responsible). Defaults to `TRUE`.
#' @details
#' These functions are context-aware. This means that the `x` argument can be left blank if used inside a [data.frame] call, see *Examples*.
#'
@@ -144,7 +143,6 @@ mdro <- function(x = NULL,
combine_SI = TRUE,
verbose = FALSE,
only_sir_columns = any(is.sir(x)),
infer_from_combinations = TRUE,
...) {
if (is_null_or_grouped_tbl(x)) {
# when `x` is left blank, auto determine it (get_current_data() searches underlying data within call)
@@ -167,7 +165,7 @@ mdro <- function(x = NULL,
meet_criteria(combine_SI, allow_class = "logical", has_length = 1)
meet_criteria(verbose, allow_class = "logical", has_length = 1)
meet_criteria(only_sir_columns, allow_class = "logical", has_length = 1)
meet_criteria(infer_from_combinations, allow_class = "logical", has_length = 1)
if (isTRUE(only_sir_columns) && !any(is.sir(x))) {
stop_("There were no SIR columns found in the data set, despite `only_sir_columns` being `TRUE`. Transform columns with `as.sir()` for valid antimicrobial interpretations.")
@@ -482,51 +480,49 @@ mdro <- function(x = NULL,
}
cols_ab <- cols_ab[!duplicated(cols_ab)]
# Infer resistance for missing base drugs ----
if (isTRUE(infer_from_combinations)) {
.combos_in_data <- AB_BETALACTAMS_WITH_INHIBITOR[AB_BETALACTAMS_WITH_INHIBITOR %in% names(cols_ab)]
if (length(.combos_in_data) > 0) {
.base_drugs <- suppressMessages(
as.ab(gsub("/.*", "", ab_name(as.character(.combos_in_data), language = NULL)))
)
.unique_bases <- unique(.base_drugs[!is.na(.base_drugs)])
for (.base in .unique_bases) {
.base_code <- as.character(.base)
if (!.base_code %in% names(cols_ab)) {
# Base drug column absent; find all available combo columns for this base drug
.combos <- .combos_in_data[!is.na(.base_drugs) & as.character(.base_drugs) == .base_code]
.combo_cols <- unname(cols_ab[as.character(.combos)])
.combo_cols <- .combo_cols[!is.na(.combo_cols)]
if (length(.combo_cols) > 0) {
# Vectorised: if ANY combination is R, infer base drug as R; otherwise NA
.sir_chars <- as.data.frame(
lapply(x[, .combo_cols, drop = FALSE], function(col) as.character(as.sir(col))),
stringsAsFactors = FALSE
# Infer resistance for missing base drugs from available drug+inhibitor combination columns.
# Clinical principle: resistance in drug+inhibitor (e.g., piperacillin/tazobactam = R)
# always implies resistance in the base drug (e.g., piperacillin = R), because the
# enzyme inhibitor adds nothing when the organism is truly resistant to the base drug.
# NOTE: susceptibility in a combination does NOT imply susceptibility in the base drug
# (the inhibitor may be responsible), so synthetic proxy columns only propagate R, not S/I.
.combos_in_data <- AB_BETALACTAMS_WITH_INHIBITOR[AB_BETALACTAMS_WITH_INHIBITOR %in% names(cols_ab)]
if (length(.combos_in_data) > 0) {
.base_drugs <- suppressMessages(
as.ab(gsub("/.*", "", ab_name(as.character(.combos_in_data), language = NULL)))
)
.unique_bases <- unique(.base_drugs[!is.na(.base_drugs)])
for (.base in .unique_bases) {
.base_code <- as.character(.base)
if (!.base_code %in% names(cols_ab)) {
# Base drug column absent; find all available combo columns for this base drug
.combos <- .combos_in_data[!is.na(.base_drugs) & as.character(.base_drugs) == .base_code]
.combo_cols <- unname(cols_ab[as.character(.combos)])
.combo_cols <- .combo_cols[!is.na(.combo_cols)]
if (length(.combo_cols) > 0) {
# Vectorised: if ANY combination is R, infer base drug as R; otherwise NA
.sir_chars <- as.data.frame(
lapply(x[, .combo_cols, drop = FALSE], function(col) as.character(as.sir(col))),
stringsAsFactors = FALSE
)
.new_col <- paste0(".sir_proxy_", .base_code)
x[[.new_col]] <- ifelse(rowSums(.sir_chars == "R", na.rm = TRUE) > 0L, "R", NA_character_)
cols_ab <- c(cols_ab, setNames(.new_col, .base_code))
if (isTRUE(verbose)) {
message_(
"Inferring resistance for ", ab_name(.base_code, language = NULL),
" from available drug+inhibitor combination(s): ",
paste(ab_name(as.character(.combos), language = NULL), collapse = ", "),
" (resistance in a combination always implies resistance in the base drug)",
add_fn = font_blue
)
.new_col <- paste0(.base_code, ".inferred_sir_proxy_from#", paste0(.combos, collapse = "/"), "#")
x[[.new_col]] <- ifelse(rowSums(.sir_chars == "R", na.rm = TRUE) > 0L, "R", NA_character_)
cols_ab <- c(cols_ab, stats::setNames(.new_col, .base_code))
if (isTRUE(info.bak)) {
message_(
"Inferring resistance for ",
ab_name(.base_code, language = NULL, tolower = TRUE),
" (", font_bold(.base_code, collapse = NULL), ", ", font_italic("missing"), ") from ",
vector_or(
quotes = FALSE,
last_sep = " and/or ",
paste0(
ab_name(.combos, language = NULL, tolower = TRUE),
" (", font_bold(.combos, collapse = NULL), ", ", font_italic("available"), ")"
)
)
)
}
}
}
}
cols_ab <- cols_ab[!duplicated(names(cols_ab))]
}
cols_ab <- cols_ab[!duplicated(names(cols_ab))]
}
rm(list = intersect(ls(), c(".combos_in_data", ".base_drugs", ".unique_bases", ".base", ".base_code", ".combos", ".combo_cols", ".sir_chars", ".new_col")))
# nolint start
AMC <- cols_ab["AMC"]
@@ -1941,8 +1937,7 @@ mdro <- function(x = NULL,
# format data set
colnames(x)[colnames(x) == col_mo] <- "microorganism"
x$microorganism <- mo_name(x$microorganism, language = NULL)
x$guideline <- paste0(guideline$author, " - ", guideline$name, ifelse(is.na(guideline$version), "", paste0(" (", guideline$version, ")")))
x$all_nonsusceptible_columns <- gsub(".inferred_sir_proxy_from#(.*?)#", " (inferred from \\1)", x$all_nonsusceptible_columns, perl = TRUE)
x$guideline <- paste0(guideline$author, " - ", guideline$name, ", ", guideline$version, ")")
x[, c(
"row_number",
"microorganism",

Binary file not shown.

View File

@@ -369,9 +369,6 @@ pre_commit_lst$AB_AMINOGLYCOSIDES <- antimicrobials %>%
filter(group %like% "aminoglycoside|paromomycin|spectinomycin") %>%
pull(ab)
pre_commit_lst$AB_AMINOPENICILLINS <- as.ab(c("AMP", "AMX", "AMC"))
pre_commit_lst$AB_AMINOCOUMARINS <- antimicrobials %>%
filter(name %like% "novobiocin|clorobiocin") %>%
pull(ab)
pre_commit_lst$AB_ANTIFUNGALS <- antimicrobials %>%
filter(group %like% "antifungal") %>%
pull(ab)
@@ -489,18 +486,6 @@ pre_commit_lst$AB_BETALACTAMS_WITH_INHIBITOR <- antimicrobials %>%
# this will be used for documentation:
pre_commit_lst$DEFINED_AB_GROUPS <- sort(names(pre_commit_lst)[names(pre_commit_lst) %like% "^AB_" & names(pre_commit_lst) != "AB_LOOKUP"])
# Check that all AB_* groups with >= 4 members have a corresponding function
for (grp in pre_commit_lst$DEFINED_AB_GROUPS[pre_commit_lst$DEFINED_AB_GROUPS %unlike% "BETALACTAMASE_INHIBITORS|EXCEPT"]) {
if (length(pre_commit_lst[[grp]]) >= 4) {
fn_name <- tolower(gsub("^AB_", "", grp))
if (!fn_name %in% ls(envir = asNamespace("AMR"))) {
stop("Group '", grp, "' has ", length(pre_commit_lst[[grp]]),
" members (", toString(ab_name(pre_commit_lst[[grp]], tolower = T)), ") but no corresponding function '", fn_name, "()' exists in the AMR namespace.",
call. = FALSE)
}
}
}
# Update the antimicrobials$group column
usethis::ui_info("Updating 'group' column in antimicrobials data set from AB_* vectors")
prettify_group_name <- function(name) {
@@ -572,7 +557,6 @@ pre_commit_lst$ABX_PRIORITY_LIST <- c("Aminopenicillins",
"Beta-lactams",
"Beta-lactamase inhibitors",
"Pleuromutilins",
"Aminocoumarins",
"Other")
if (!all(unlist(antimicrobials$group) %in% pre_commit_lst$ABX_PRIORITY_LIST)) {
stop("Missing group(s) in priority list: ", paste(setdiff(unlist(antimicrobials$group), pre_commit_lst$ABX_PRIORITY_LIST), collapse = ", "))

View File

@@ -972,17 +972,6 @@ antimicrobials <- antimicrobials |>
select(1:4),
)
antimicrobials <- antimicrobials |>
mutate(ab = as.character(ab)) |>
bind_rows(
antimicrobials |>
filter(ab == "NOV") |>
mutate(ab = "CLB",
cid = 54706138,
name = "Clorobiocin") |>
select(1:4),
)
# update ATC codes from WHOCC website -------------------------------------
library(rvest)
@@ -1182,11 +1171,6 @@ for (i in 1:nrow(antimicrobials)) {
antimicrobials[i, "loinc"][[1]] <- ifelse(length(loinc) == 0, list(NA_character_), list(loinc))
}
}
antimicrobials$group <- unname(antimicrobials$group)
antimicrobials$atc <- unname(antimicrobials$atc)
antimicrobials$abbreviations <- unname(antimicrobials$abbreviations)
antimicrobials$synonyms <- unname(antimicrobials$synonyms)
antimicrobials$loinc <- unname(antimicrobials$loinc)
usethis::use_data(antimicrobials, overwrite = TRUE, version = 2, compress = "xz")

View File

@@ -1 +1 @@
11aade8a39bfdff02d01fb52b04eacdc
147709d2fb1b31b013c6ffb387f4d3ba

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -157,7 +157,6 @@
"CLF1" 2799 "Clofoctol" "Other" "J01XX03,QJ01XX03" "Other antibacterials" "Other antibacterials" "NA" "clofoctolo,clofoctolum,gramplus,octofene,phenol" "NA"
"CLM" 71807 "Clometocillin" "Penicillins,Beta-lactams" "J01CE07,QJ01CE07" "Beta-lactam antibacterials, penicillins" "Beta-lactamase sensitive penicillins" "NA" "chlomethocillin,clometacillin,clomethacillin,clomethocillin,clometocilina,clometocilline,clometocillinsalt,clometocillinum,penicilline,rixapen" 1 "g" "NA"
"CLM1" 54680675 "Clomocycline" "Tetracyclines" "J01AA11,QJ01AA11" "Tetracyclines" "Tetracyclines" "NA" "clomociclina,clomocyclinum,megaclor" 1 "g" "NA"
"CLB" 54706138 "Clorobiocin" "Aminocoumarins" "NA" "NA" "chlorobiocin" "NA"
"CTR" 2812 "Clotrimazole" "Antifungals" "A01AB18,D01AC01,G01AF02,QA01AB18,QD01AC01,QG01AF02,QJ02AB90" "clot" "alevazol,bisphenyl,canesten,canestene,canestine,canifug,chlotrimazole,clomatin,clotrimaderm,clotrimazol,clotrimazolum,coltrimazole,cutistad,diphenylmethane,empecid,esparol,femmesil,footlogix,fortinia,gynix,imidazole,jidesheng,klotrimazole,lakesia,lombazol,lombazole,lombazolum,lotrimax,lotrimin,monobaycuten,mycelax,mycelex,mycofug,mycosporin,mykosporin,nalbix,otomax,pedesil,pedisafe,ringworm,stiemazol,tibatin,trimysten,trivagizole" "10653-4,10654-2,18909-2,54177-1,55663-9"
"CLO" 6098 "Cloxacillin" "Isoxazolylpenicillins,Penicillins,Beta-lactams" "J01CF02,QJ01CF02,QJ51CF02,QS01AA90" "Beta-lactam antibacterials, penicillins" "Beta-lactamase resistant penicillins" "clox,cloxac" "ankerbin,austrastaph,biocloxin,brispen,chloroxacillin,ciclex,clocil,clossacillina,cloxacilina,cloxacillinanhydrous,cloxacilline,cloxacillinsalt,cloxacillinum,cloxapen,constaphyl,dariclox,dichlorstapenor,diclocil,dicloxacillinhydrate,diflor,digloxilline,dynapen,ekvacillin,gelstaph,novapen,noxaben,orbenin,pathocil,stampen,staphybiotic,syntarpen,syntarpensalt,tegopen" 2 "g" 2 "g" "16628-0,18910-0,196-6,197-4,198-2,199-0,25250-2,55664-7"
"COL" 5311054 "Colistin" "Polymyxins" "A07AA10,J01XB01,QA07AA10,QJ01XB01,QJ51XB01" "Other antibacterials" "Polymyxins" "cl,coli,colist,cs,cst,ct" "colimycin,colisticin,colisticina,colistina,colistine,colistinum,colobreathe,colomycin,kangdisu,kolimitsin,kolimycin,promixin,sogecoli,totazina" 9 "MU" 9 "MU" "16645-4,18912-6,204-8,205-5,206-3,207-1,29493-4,33333-6"
@@ -308,7 +307,7 @@
"NME" "Norfloxacin/metronidazole" "Fluoroquinolones,Quinolones" "J01RA14,QJ01RA14" "Combinations of antibacterials" "Combinations of antibacterials" "NA" "NA" "NA"
"NTI" "Norfloxacin/tinidazole" "Fluoroquinolones,Quinolones" "J01RA13,QJ01RA13" "Combinations of antibacterials" "Combinations of antibacterials" "NA" "NA" "NA"
"NVA" 10419027 "Norvancomycin" "Glycopeptides,Peptides" "NA" "NA" "NA" "NA"
"NOV" 54675769 "Novobiocin" "Aminocoumarins" "QJ01XX95" "novo,novobi" "albadry,albamix,albamycin,biotexin,cardelmycin,cardelmycinsalt,cathocin,cathomycin,inabiocin,novobiocina,novobiocine,novobiocinsalt,novobiocinum,robiocina,sirbiocina,spheromycin,stilbiocina,streptonivicin,streptonivicinsalt,vulcamicina,vulcamycin,vulkamycin" "17378-1,18957-1,370-7,371-5,372-3,373-1,41706-3"
"NOV" 54675769 "Novobiocin" "Other" "QJ01XX95" "novo,novobi" "albadry,albamix,albamycin,biotexin,cardelmycin,cardelmycinsalt,cathocin,cathomycin,inabiocin,novobiocina,novobiocine,novobiocinsalt,novobiocinum,robiocina,sirbiocina,spheromycin,stilbiocina,streptonivicin,streptonivicinsalt,vulcamicina,vulcamycin,vulkamycin" "17378-1,18957-1,370-7,371-5,372-3,373-1,41706-3"
"NYS" 6433272 "Nystatin" "Ionophores,Antifungals" "A07AA02,D01AA01,G01AA01,QA07AA02,QD01AA01,QG01AA01" "nyst,nystan" "biofanal,diastatin,herniocid,moronal,myconystatin,mycostatin,mykostatyna,nilstat,nistatin,nistatina,nyotran,nystan,nystatyna,nystavescent,nystex" 1.5 "MU" "10697-1,10698-9,18958-9,35824-2,55689-4"
"OFX" 4583 "Ofloxacin" "Fluoroquinolones,Quinolones" "J01MA01,QJ01MA01,QS01AE01,QS02AA16,S01AE01,S02AA16" "Quinolone antibacterials" "Fluoroquinolones" "of,ofl,oflo,ofloxa,ofx" "exocin,exocine,flobacin,floxil,floxin,monoflocet,oflocet,ofloxacina,ofloxacine,ofloxacino,ofloxacinum,ofloxaxin,oxaldin,tarivid,visiren,zanocin" 0.4 "g" 0.4 "g" "18959-7,20384-4,23948-3,25264-3,374-9,375-6,376-4,377-2,3877-8,41408-6,41409-4,41410-2,42653-6,7038-3,72168-8"
"OOR" "Ofloxacin/ornidazole" "Fluoroquinolones,Quinolones" "J01RA09,QJ01RA09" "Combinations of antibacterials" "Combinations of antibacterials" "NA" "NA" "NA"
@@ -333,7 +332,7 @@
"PEF" 51081 "Pefloxacin" "Fluoroquinolones,Quinolones" "J01MA03,QJ01MA03" "Quinolone antibacterials" "Fluoroquinolones" "pefl,perflo" "labocton,pefbid,pefloxacine,pefloxacinium,pefloxacino,pefloxacinum,pefocin,pefran,pelox" 0.8 "g" 0.8 "g" "18963-9,35828-3,390-5,3906-5,7040-9"
"PEF-S" "Pefloxacin screening test" "Fluoroquinolones,Quinolones" "NA" "pef screen" "NA" "NA"
"PNM" 10250769 "Penamecillin" "Penicillins,Beta-lactams" "J01CE06,QJ01CE06" "Beta-lactam antibacterials, penicillins" "Beta-lactamase sensitive penicillins" "NA" "havapen,hydroxymethyl,penamecilina,penamecillina,penamecilline,penamecillinum" 1.05 "g" "NA"
"PNO" "Penicillin/novobiocin" "Penicillins,Beta-lactams,Aminocoumarins" "NA" "pennov" "NA" "35872-1,35873-9,35874-7"
"PNO" "Penicillin/novobiocin" "Penicillins,Beta-lactams" "NA" "pennov" "NA" "35872-1,35873-9,35874-7"
"PSU" "Penicillin/sulbactam" "Penicillins,Beta-lactams,Beta-lactamase inhibitors" "NA" "NA" "NA" "NA"
"PNM1" 54686187 "Penimepicycline" "Tetracyclines" "J01AA10,QJ01AA10" "Tetracyclines" "Tetracyclines" "NA" "criseocil,duamine,geotricyn,hydrocycline,penetracyne,penimepiciclina,penimepicyclinum" "NA"
"PIM" 65453 "Pentisomicin" "Aminoglycosides" "NA" "NA" "mutamicin,mutamycin,pentisomicina,pentisomicine,pentisomicinum" "NA"

Binary file not shown.

Binary file not shown.

View File

@@ -17,7 +17,6 @@
\alias{cephalosporins_5th}
\alias{fluoroquinolones}
\alias{glycopeptides}
\alias{ionophores}
\alias{isoxazolylpenicillins}
\alias{lincosamides}
\alias{lipoglycopeptides}
@@ -82,8 +81,6 @@ fluoroquinolones(only_sir_columns = FALSE, only_treatable = TRUE,
glycopeptides(only_sir_columns = FALSE, return_all = TRUE, ...)
ionophores(only_sir_columns = FALSE, return_all = TRUE, ...)
isoxazolylpenicillins(only_sir_columns = FALSE, only_treatable = TRUE,
return_all = TRUE, ...)
@@ -205,7 +202,6 @@ The \code{\link[=not_intrinsic_resistant]{not_intrinsic_resistant()}} function c
\item \code{\link[=cephalosporins_5th]{cephalosporins_5th()}} can select: \cr ceftaroline (CPT), ceftaroline/avibactam (CPA), ceftobiprole (BPR), ceftobiprole medocaril (CFM1), and ceftolozane/tazobactam (CZT)
\item \code{\link[=fluoroquinolones]{fluoroquinolones()}} can select: \cr besifloxacin (BES), ciprofloxacin (CIP), ciprofloxacin/metronidazole (CIM), ciprofloxacin/ornidazole (CIO), ciprofloxacin/tinidazole (CIT), clinafloxacin (CLX), danofloxacin (DAN), delafloxacin (DFX), difloxacin (DIF), enoxacin (ENX), enrofloxacin (ENR), finafloxacin (FIN), fleroxacin (FLE), garenoxacin (GRN), gatifloxacin (GAT), gemifloxacin (GEM), grepafloxacin (GRX), lascufloxacin (LSC), levofloxacin (LVX), levofloxacin/ornidazole (LEO), levonadifloxacin (LND), lomefloxacin (LOM), marbofloxacin (MAR), metioxate (MXT), miloxacin (MIL), moxifloxacin (MFX), nadifloxacin (NAD), nemonoxacin (NEM), nifuroquine (NIF), nitroxoline (NTR), norfloxacin (NOR), norfloxacin screening test (NOR-S), norfloxacin/metronidazole (NME), norfloxacin/tinidazole (NTI), ofloxacin (OFX), ofloxacin/ornidazole (OOR), orbifloxacin (ORB), pazufloxacin (PAZ), pefloxacin (PEF), pefloxacin screening test (PEF-S), pradofloxacin (PRA), premafloxacin (PRX), prulifloxacin (PRU), rufloxacin (RFL), sarafloxacin (SAR), sitafloxacin (SIT), sparfloxacin (SPX), temafloxacin (TMX), tilbroquinol (TBQ), tioxacin (TXC), tosufloxacin (TFX), and trovafloxacin (TVA)
\item \code{\link[=glycopeptides]{glycopeptides()}} can select: \cr avoparcin (AVO), bleomycin (BLM), dalbavancin (DAL), norvancomycin (NVA), oritavancin (ORI), ramoplanin (RAM), teicoplanin (TEC), teicoplanin-macromethod (TCM), telavancin (TLV), vancomycin (VAN), vancomycin-macromethod (VAM), and zorbamycin (ZOR)
\item \code{\link[=ionophores]{ionophores()}} can select: \cr lasalocid (LAS), monensin sodium (MON), narasin (NAR), nystatin (NYS), and salinomycin (SAL)
\item \code{\link[=isoxazolylpenicillins]{isoxazolylpenicillins()}} can select: \cr cloxacillin (CLO), dicloxacillin (DIC), flucloxacillin (FLC), meticillin (MET), oxacillin (OXA), and oxacillin screening test (OXA-S)
\item \code{\link[=lincosamides]{lincosamides()}} can select: \cr clindamycin (CLI), clindamycin inducible screening test (CLI-S), lincomycin (LIN), and pirlimycin (PRL)
\item \code{\link[=lipoglycopeptides]{lipoglycopeptides()}} can select: \cr dalbavancin (DAL), oritavancin (ORI), and telavancin (TLV)

View File

@@ -5,9 +5,9 @@
\alias{antimicrobials}
\alias{antibiotics}
\alias{antivirals}
\title{Data Sets with 625 Antimicrobial Drugs}
\title{Data Sets with 624 Antimicrobial Drugs}
\format{
\subsection{For the \link{antimicrobials} data set: a \link[tibble:tibble]{tibble} with 505 observations and 14 variables:}{
\subsection{For the \link{antimicrobials} data set: a \link[tibble:tibble]{tibble} with 504 observations and 14 variables:}{
\itemize{
\item \code{ab}\cr antimicrobial ID as used in this package (such as \code{AMC}), using the official EARS-Net (European Antimicrobial Resistance Surveillance Network) codes where available. \emph{\strong{This is a unique identifier.}}
\item \code{cid}\cr Compound ID as found in PubChem. \emph{\strong{This is a unique identifier.}}
@@ -50,7 +50,7 @@ LOINC:
}
}
An object of class \code{deprecated_amr_dataset} (inherits from \code{tbl_df}, \code{tbl}, \code{data.frame}) with 505 rows and 14 columns.
An object of class \code{deprecated_amr_dataset} (inherits from \code{tbl_df}, \code{tbl}, \code{data.frame}) with 504 rows and 14 columns.
An object of class \code{tbl_df} (inherits from \code{tbl}, \code{data.frame}) with 120 rows and 11 columns.
}

View File

@@ -98,9 +98,8 @@ x
#> amoxicillin (AMX), ampicillin (AMP), azlocillin (AZL), mezlocillin (MEZ), piperacillin (PIP), piperacillin/tazobactam (TZP)
}\if{html}{\out{</div>}}
These 43 antimicrobial groups are allowed in the rules (case-insensitive) and can be used in any combination:
These 42 antimicrobial groups are allowed in the rules (case-insensitive) and can be used in any combination:
\itemize{
\item aminocoumarins\cr(clorobiocin, novobiocin, and penicillin/novobiocin)
\item aminoglycosides\cr(amikacin, amikacin/fosfomycin, apramycin, arbekacin, astromicin, bekanamycin, dibekacin, framycetin, gentamicin, gentamicin-high, habekacin, hygromycin, isepamicin, kanamycin, kanamycin-high, kanamycin/cephalexin, kasugamycin, micronomicin, neomycin, netilmicin, pentisomicin, plazomicin, propikacin, ribostamycin, sisomicin, streptoduocin, streptomycin, streptomycin-high, tobramycin, and tobramycin-high)
\item aminopenicillins\cr(amoxicillin, amoxicillin/clavulanic acid, and ampicillin)
\item antifungals\cr(amorolfine, amphotericin B, amphotericin B-high, anidulafungin, butoconazole, caspofungin, ciclopirox, clotrimazole, econazole, fluconazole, flucytosine, fosfluconazole, griseofulvin, hachimycin, ibrexafungerp, isavuconazole, isoconazole, itraconazole, ketoconazole, manogepix, micafungin, miconazole, nystatin, oteseconazole, pimaricin, posaconazole, rezafungin, ribociclib, sulconazole, terbinafine, terconazole, and voriconazole)

View File

@@ -94,7 +94,7 @@ You can define antimicrobial groups instead of single antimicrobials for the rul
)
}\if{html}{\out{</div>}}
All 43 antimicrobial selectors are supported for use in the rules:
All 42 antimicrobial selectors are supported for use in the rules:
\itemize{
\item \code{\link[=aminoglycosides]{aminoglycosides()}} can select: \cr amikacin, amikacin/fosfomycin, apramycin, arbekacin, astromicin, bekanamycin, dibekacin, framycetin, gentamicin, gentamicin-high, habekacin, hygromycin, isepamicin, kanamycin, kanamycin-high, kanamycin/cephalexin, kasugamycin, micronomicin, neomycin, netilmicin, pentisomicin, plazomicin, propikacin, ribostamycin, sisomicin, streptoduocin, streptomycin, streptomycin-high, tobramycin, and tobramycin-high
\item \code{\link[=aminopenicillins]{aminopenicillins()}} can select: \cr amoxicillin, amoxicillin/clavulanic acid, and ampicillin
@@ -111,7 +111,6 @@ All 43 antimicrobial selectors are supported for use in the rules:
\item \code{\link[=cephalosporins_5th]{cephalosporins_5th()}} can select: \cr ceftaroline, ceftaroline/avibactam, ceftobiprole, ceftobiprole medocaril, and ceftolozane/tazobactam
\item \code{\link[=fluoroquinolones]{fluoroquinolones()}} can select: \cr besifloxacin, ciprofloxacin, ciprofloxacin/metronidazole, ciprofloxacin/ornidazole, ciprofloxacin/tinidazole, clinafloxacin, danofloxacin, delafloxacin, difloxacin, enoxacin, enrofloxacin, finafloxacin, fleroxacin, garenoxacin, gatifloxacin, gemifloxacin, grepafloxacin, lascufloxacin, levofloxacin, levofloxacin/ornidazole, levonadifloxacin, lomefloxacin, marbofloxacin, metioxate, miloxacin, moxifloxacin, nadifloxacin, nemonoxacin, nifuroquine, nitroxoline, norfloxacin, norfloxacin screening test, norfloxacin/metronidazole, norfloxacin/tinidazole, ofloxacin, ofloxacin/ornidazole, orbifloxacin, pazufloxacin, pefloxacin, pefloxacin screening test, pradofloxacin, premafloxacin, prulifloxacin, rufloxacin, sarafloxacin, sitafloxacin, sparfloxacin, temafloxacin, tilbroquinol, tioxacin, tosufloxacin, and trovafloxacin
\item \code{\link[=glycopeptides]{glycopeptides()}} can select: \cr avoparcin, bleomycin, dalbavancin, norvancomycin, oritavancin, ramoplanin, teicoplanin, teicoplanin-macromethod, telavancin, vancomycin, vancomycin-macromethod, and zorbamycin
\item \code{\link[=ionophores]{ionophores()}} can select: \cr lasalocid, monensin sodium, narasin, nystatin, and salinomycin
\item \code{\link[=isoxazolylpenicillins]{isoxazolylpenicillins()}} can select: \cr cloxacillin, dicloxacillin, flucloxacillin, meticillin, oxacillin, and oxacillin screening test
\item \code{\link[=lincosamides]{lincosamides()}} can select: \cr clindamycin, clindamycin inducible screening test, lincomycin, and pirlimycin
\item \code{\link[=lipoglycopeptides]{lipoglycopeptides()}} can select: \cr dalbavancin, oritavancin, and telavancin

View File

@@ -18,8 +18,7 @@
mdro(x = NULL, guideline = "CMI 2012", col_mo = NULL, esbl = NA,
carbapenemase = NA, mecA = NA, mecC = NA, vanA = NA, vanB = NA,
info = interactive(), pct_required_classes = 0.5, combine_SI = TRUE,
verbose = FALSE, only_sir_columns = any(is.sir(x)),
infer_from_combinations = TRUE, ...)
verbose = FALSE, only_sir_columns = any(is.sir(x)), ...)
brmo(x = NULL, only_sir_columns = any(is.sir(x)), ...)
@@ -36,7 +35,7 @@ eucast_exceptional_phenotypes(x = NULL, only_sir_columns = any(is.sir(x)),
\arguments{
\item{x}{A \link{data.frame} with antimicrobials columns, like \code{AMX} or \code{amox}. Can be left blank for automatic determination.}
\item{guideline}{A specific guideline to follow, see sections \emph{Supported International / National Guidelines} and \emph{Using Custom Guidelines} below. When left empty, the publication by Magiorakos \emph{et al.} (see below) will be followed.}
\item{guideline}{A specific guideline to follow, see sections \emph{Supported international / national guidelines} and \emph{Using Custom Guidelines} below. When left empty, the publication by Magiorakos \emph{et al.} (see below) will be followed.}
\item{col_mo}{Column name of the names or codes of the microorganisms (see \code{\link[=as.mo]{as.mo()}}) - the default is the first column of class \code{\link{mo}}. Values will be coerced using \code{\link[=as.mo]{as.mo()}}.}
@@ -62,8 +61,6 @@ eucast_exceptional_phenotypes(x = NULL, only_sir_columns = any(is.sir(x)),
\item{only_sir_columns}{A \link{logical} to indicate whether only antimicrobial columns must be included that were transformed to class \link[=as.sir]{sir} on beforehand. Defaults to \code{FALSE} if no columns of \code{x} have a class \link[=as.sir]{sir}.}
\item{infer_from_combinations}{A \link{logical} to indicate whether resistance for a missing base beta-lactam drug should be inferred from an available drug+inhibitor combination (e.g., piperacillin from piperacillin/tazobactam). The clinical basis is that resistance in a combination always implies resistance in the base drug, since the enzyme inhibitor provides no benefit when the organism is truly resistant. Only resistance is inferred; susceptibility in a combination does \strong{not} imply susceptibility in the base drug (the inhibitor may be responsible). Defaults to \code{TRUE}.}
\item{...}{Column names of antimicrobials. To automatically detect antimicrobial column names, do not provide any named arguments; \code{\link[=guess_ab_col]{guess_ab_col()}} will then be used for detection. To manually specify a column, provide its name (case-insensitive) as an argument, e.g. \code{AMX = "amoxicillin"}. To skip a specific antimicrobial, set it to \code{NULL}, e.g. \code{TIC = NULL} to exclude ticarcillin. If a manually defined column does not exist in the data, it will be skipped with a warning.}
}
\value{

View File

@@ -35,10 +35,7 @@ test_that("test-data.R", {
expect_identical(class(microorganisms$mo), c("mo", "character"))
expect_identical(nrow(antimicrobials), length(unique(AMR::antimicrobials$ab)))
expect_identical(class(AMR::antimicrobials$ab), c("ab", "character"))
expect_identical(
nrow(antimicrobials[!is.na(antimicrobials$cid), ]),
length(unique(AMR::antimicrobials$cid[!is.na(antimicrobials$cid)]))
)
expect_identical(nrow(antimicrobials[!is.na(antimicrobials$cid), ]), length(unique(AMR::antimicrobials$cid[!is.na(antimicrobials$cid)])), label = "nr of rows with CIDs", expected.label = "unique nr of CIDs")
# check cross table reference
expect_true(all(microorganisms.codes$mo %in% microorganisms$mo))

View File

@@ -298,53 +298,51 @@ test_that("test-mdro.R", {
}
# drug+inhibitor inference for missing base drug columns (issue #209) -------
# Resistance in drug+inhibitor implies resistance in the base drug.
# MRGN guideline is used because it explicitly requires PIP=R (not PIP OR TZP)
# for Pseudomonas aeruginosa 4MRGN, making the proxy effect directly testable.
# Resistance in drug+inhibitor always implies resistance in the base drug.
# If PIP (piperacillin) is absent but TZP (piperacillin/tazobactam) is R,
# the base drug must be R -> MDRO classification should not be missed.
pseud_no_pip <- data.frame(
mo = as.mo("Pseudomonas aeruginosa"),
TZP = as.sir("R"), # piperacillin/tazobactam; no PIP column
CAZ = as.sir("R"),
mo = as.mo("Pseudomonas aeruginosa"),
TZP = as.sir("R"), # piperacillin/tazobactam present; no PIP column
IPM = as.sir("R"),
MEM = as.sir("R"),
CAZ = as.sir("R"),
FEP = as.sir("R"),
CIP = as.sir("R"),
GEN = as.sir("R"),
TOB = as.sir("R"),
AMK = as.sir("R"),
COL = as.sir("S"),
stringsAsFactors = FALSE
)
# Inference message goes to message() / stderr, not stdout
# -> must use expect_message(), NOT expect_output()
expect_message(
suppressWarnings(mdro(pseud_no_pip, guideline = "mrgn", info = TRUE)),
"Inferring resistance"
)
inferred <- suppressWarnings(mdro(pseud_no_pip, guideline = "mrgn", info = FALSE))
not_inferred <- suppressWarnings(mdro(pseud_no_pip, guideline = "mrgn", info = FALSE, infer_from_combinations = FALSE))
expect_equal(as.character(inferred), "4MRGN")
expect_equal(as.character(not_inferred), "Negative")
# With TZP=R, PIP should be inferred R; result should be XDR or PDR (integer > 2)
result_no_pip <- suppressMessages(suppressWarnings(mdro(pseud_no_pip, guideline = "EUCAST", info = FALSE)))
expect_true(as.integer(result_no_pip$MDRO) > 1L)
# Susceptibility in combo does NOT propagate: proxy = NA, not S
# -> 4MRGN criteria no longer met -> lower level than when TZP=R
# Susceptibility in combination must NOT be propagated to base drug
# (the inhibitor may be responsible; we cannot conclude PIP=S from TZP=S)
pseud_tzp_s <- pseud_no_pip
pseud_tzp_s$TZP <- as.sir("S")
result_tzp_s <- suppressMessages(suppressWarnings(
mdro(pseud_tzp_s, guideline = "mrgn", info = FALSE)
))
expect_true(as.integer(result_tzp_s) < as.integer(inferred))
result_tzp_s <- suppressMessages(suppressWarnings(mdro(pseud_tzp_s, guideline = "EUCAST", info = FALSE)))
# Proxy column is NA (not S), so the classification should be lower than when TZP=R
expect_true(as.integer(result_tzp_s$MDRO) < as.integer(result_no_pip$MDRO))
# Multiple combos for the same base drug: AMX can come from AMC (amoxi/clavulanic acid) and AXS (amoxi/sulbactam)
# verbose mode should emit an inference message when a proxy column is created
expect_output(
suppressMessages(suppressWarnings(mdro(pseud_no_pip, guideline = "EUCAST", info = FALSE, verbose = TRUE))),
regexp = "Inferring resistance"
)
# Multiple combos for the same base drug: AMX can come from AMC (amoxicillin/clavulanic acid)
ente_no_amx <- data.frame(
mo = as.mo("Enterococcus faecium"),
AMC = as.sir("R"), # amoxicillin/clavulanic acid
AXS = as.sir("R"), # amoxicillin/sulbactam
mo = as.mo("Enterococcus faecium"),
AMC = as.sir("R"), # amoxicillin/clavulanic acid; no AMX column
VAN = as.sir("R"),
TEC = as.sir("R"),
LNZ = as.sir("R"),
DAP = as.sir("R"),
stringsAsFactors = FALSE
)
# Should have multiple columns in the verbose explanation
out <- mdro(ente_no_amx, guideline = "EUCAST 3.3", info = FALSE, verbose = TRUE)
expect_identical(
out$all_nonsusceptible_columns,
"AMC, AMX (inferred from AMC/AXS), AXS, DAP, LNZ, TEC, VAN"
)
# Should run without error and return a data.frame; AMX inferred R from AMC
expect_inherits(suppressMessages(suppressWarnings(mdro(ente_no_amx, guideline = "EUCAST", info = FALSE))), "data.frame")
})

View File

@@ -178,15 +178,9 @@ test_that("test-zzz.R", {
also_load = FALSE,
min_version = if (pkg == "dplyr") "1.0.0" else NULL
)) {
if (pkg == "rstudioapi") {
expect_true(is.function(tryCatch(get(fn, envir = asNamespace(pkg)), error = function(e) NULL)),
info = paste0("Function does not exist (anymore): function `", pkg, "::", fn, "()`")
)
} else {
expect_true(!is.null(AMR:::import_fn(name = fn, pkg = pkg, error_on_fail = FALSE)),
info = paste0("Function does not exist (anymore): function `", pkg, "::", fn, "()`")
)
}
expect_true(!is.null(AMR:::import_fn(name = fn, pkg = pkg, error_on_fail = FALSE)),
info = paste0("Function does not exist (anymore): function `", pkg, "::", fn, "()`")
)
} else if (pkg != "rstudioapi") {
warning("Package '", pkg, "' not available")
}