mirror of
https://github.com/msberends/AMR.git
synced 2026-05-14 02:30:45 +02:00
* Generalise interpretive rules for multi-guideline support (#268) - Rename data-raw/eucast_rules.tsv → interpretive_rules.tsv; add rule.provider column (value: "EUCAST") to distinguish future CLSI rows - Rename EUCAST_RULES_DF → INTERPRETIVE_RULES_DF in _pre_commit_checks.R; filter by rule.provider == guideline when applying rules in interpretive_rules() - Rename custom_eucast_rules() → custom_interpretive_rules() with new S3 class "custom_interpretive_rules"; old function becomes a deprecated wrapper in zz_deprecated.R; backward-compat S3 dispatch shims added for old class - Remove stop_if(guideline == "CLSI", ...) so clsi_rules() no longer errors - Add .onLoad shim in zzz.R to create INTERPRETIVE_RULES_DF from EUCAST_RULES_DF for transitional compatibility until sysdata.rda is regenerated https://claude.ai/code/session_01D46BTsfJSPo3HnLWp3PRkP * Fix namespace load failure: remove assignInNamespace from .onLoad (#268) assignInNamespace cannot add NEW bindings to a locked package namespace (R locks namespace bindings before .onLoad runs). Replace the .onLoad shim with a runtime fallback inside interpretive_rules(): if INTERPRETIVE_RULES_DF is absent (pre-regeneration sysdata.rda), derive it from EUCAST_RULES_DF by adding the rule.provider column. This also fixes the screening_abx line to reuse the already-resolved interpretive_rules_df_total instead of a bare INTERPRETIVE_RULES_DF reference. https://claude.ai/code/session_01D46BTsfJSPo3HnLWp3PRkP * fixes * fixes --------- Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -32,4 +32,11 @@ test_that("test-_deprecated.R", {
|
||||
|
||||
expect_warning(example_isolates[, ab_class("mycobact")])
|
||||
expect_warning(example_isolates[, ab_selector(name %like% "trim")])
|
||||
|
||||
# deprecated custom_interpretive_rules() still works and emits a warning
|
||||
expect_warning(
|
||||
x_old <- custom_eucast_rules(AMC == "R" ~ aminopenicillins == "R"),
|
||||
regexp = "custom_eucast_rules"
|
||||
)
|
||||
expect_inherits(x_old, "custom_interpretive_rules")
|
||||
})
|
||||
|
||||
@@ -53,12 +53,12 @@ test_that("test-data.R", {
|
||||
expect_false(anyNA(microorganisms.codes$mo))
|
||||
expect_true(all(dosage$ab %in% AMR::antimicrobials$ab))
|
||||
expect_true(all(dosage$name %in% AMR::antimicrobials$name))
|
||||
eucast_abx <- AMR:::EUCAST_RULES_DF$and_these_antibiotics
|
||||
eucast_abx <- unique(unlist(strsplit(eucast_abx[!is.na(eucast_abx)], ", +")))
|
||||
expect_true(all(eucast_abx %in% AMR::antimicrobials$ab),
|
||||
interpretive_abx <- AMR:::INTERPRETIVE_RULES_DF$and_these_antibiotics
|
||||
interpretive_abx <- unique(unlist(strsplit(interpretive_abx[!is.na(interpretive_abx)], ", +")))
|
||||
expect_true(all(interpretive_abx %in% AMR::antimicrobials$ab),
|
||||
info = paste0(
|
||||
"Missing in `antimicrobials` data set: ",
|
||||
toString(eucast_abx[which(!eucast_abx %in% AMR::antimicrobials$ab)])
|
||||
toString(interpretive_abx[which(!interpretive_abx %in% AMR::antimicrobials$ab)])
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -27,13 +27,14 @@
|
||||
# how to conduct AMR data analysis: https://amr-for-r.org #
|
||||
# ==================================================================== #
|
||||
|
||||
test_that("test-eucast_rules.R", {
|
||||
test_that("test-interpretive_rules.R", {
|
||||
skip_on_cran()
|
||||
|
||||
# thoroughly check input table
|
||||
expect_equal(
|
||||
sort(colnames(AMR:::EUCAST_RULES_DF)),
|
||||
sort(colnames(AMR:::INTERPRETIVE_RULES_DF)),
|
||||
sort(c(
|
||||
"rule.provider",
|
||||
"if_mo_property", "like.is.one_of", "this_value",
|
||||
"and_these_antibiotics", "have_these_values",
|
||||
"then_change_these_antibiotics", "to_value",
|
||||
@@ -42,7 +43,7 @@ test_that("test-eucast_rules.R", {
|
||||
"note"
|
||||
))
|
||||
)
|
||||
MOs_mentioned <- unique(AMR:::EUCAST_RULES_DF$this_value)
|
||||
MOs_mentioned <- unique(AMR:::INTERPRETIVE_RULES_DF$this_value)
|
||||
MOs_mentioned <- sort(trimws(unlist(strsplit(MOs_mentioned[!AMR:::is_valid_regex(MOs_mentioned)], ",", fixed = TRUE))))
|
||||
MOs_test <- suppressWarnings(
|
||||
trimws(paste(
|
||||
@@ -54,19 +55,19 @@ test_that("test-eucast_rules.R", {
|
||||
MOs_test[MOs_test == ""] <- mo_fullname(MOs_mentioned[MOs_test == ""], keep_synonyms = TRUE, language = NULL)
|
||||
expect_equal(MOs_mentioned, MOs_test)
|
||||
|
||||
expect_error(suppressWarnings(eucast_rules(example_isolates, col_mo = "Non-existing")))
|
||||
expect_error(eucast_rules(x = "text"))
|
||||
expect_error(eucast_rules(data.frame(a = "test")))
|
||||
expect_error(eucast_rules(data.frame(mo = "test"), rules = "invalid rules set"))
|
||||
expect_error(suppressWarnings(interpretive_rules(example_isolates, col_mo = "Non-existing")))
|
||||
expect_error(interpretive_rules(x = "text"))
|
||||
expect_error(interpretive_rules(data.frame(a = "test")))
|
||||
expect_error(interpretive_rules(data.frame(mo = "test"), rules = "invalid rules set"))
|
||||
|
||||
# expect_warning(eucast_rules(data.frame(mo = "Escherichia coli", vancomycin = "S", stringsAsFactors = TRUE)))
|
||||
# expect_warning(interpretive_rules(data.frame(mo = "Escherichia coli", vancomycin = "S", stringsAsFactors = TRUE)))
|
||||
|
||||
expect_identical(
|
||||
colnames(example_isolates),
|
||||
colnames(suppressWarnings(eucast_rules(example_isolates, info = FALSE)))
|
||||
colnames(suppressWarnings(interpretive_rules(example_isolates, info = FALSE)))
|
||||
)
|
||||
|
||||
expect_output(suppressMessages(eucast_rules(example_isolates, info = TRUE)))
|
||||
expect_output(suppressMessages(interpretive_rules(example_isolates, info = TRUE)))
|
||||
|
||||
a <- data.frame(
|
||||
mo = c(
|
||||
@@ -86,8 +87,8 @@ test_that("test-eucast_rules.R", {
|
||||
amox = "R", # Amoxicillin
|
||||
stringsAsFactors = FALSE
|
||||
)
|
||||
expect_identical(suppressWarnings(eucast_rules(a, "mo", info = FALSE)), b)
|
||||
expect_output(suppressMessages(suppressWarnings(eucast_rules(a, "mo", info = TRUE))))
|
||||
expect_identical(suppressWarnings(interpretive_rules(a, "mo", info = FALSE)), b)
|
||||
expect_output(suppressMessages(suppressWarnings(interpretive_rules(a, "mo", info = TRUE))))
|
||||
|
||||
a <- data.frame(
|
||||
mo = c(
|
||||
@@ -105,7 +106,7 @@ test_that("test-eucast_rules.R", {
|
||||
COL = "R", # Colistin
|
||||
stringsAsFactors = FALSE
|
||||
)
|
||||
expect_equal(suppressWarnings(eucast_rules(a, "mo", info = FALSE)), b)
|
||||
expect_equal(suppressWarnings(interpretive_rules(a, "mo", info = FALSE)), b)
|
||||
|
||||
# piperacillin must be R in Enterobacteriaceae when tica is R
|
||||
if (AMR:::pkg_is_available("dplyr", min_version = "1.0.0", also_load = TRUE)) {
|
||||
@@ -117,7 +118,7 @@ test_that("test-eucast_rules.R", {
|
||||
TIC = as.sir("R"),
|
||||
PIP = as.sir("S")
|
||||
) %>%
|
||||
eucast_rules(col_mo = "mo", version_expertrules = 3.1, rules = "expert", info = FALSE, overwrite = TRUE) %>%
|
||||
interpretive_rules(col_mo = "mo", version_expertrules = 3.1, rules = "expert", info = FALSE, overwrite = TRUE) %>%
|
||||
pull(PIP) %>%
|
||||
unique() %>%
|
||||
as.character()
|
||||
@@ -127,7 +128,7 @@ test_that("test-eucast_rules.R", {
|
||||
}
|
||||
|
||||
# azithromycin and clarythromycin must be equal to Erythromycin
|
||||
a <- suppressWarnings(as.sir(eucast_rules(
|
||||
a <- suppressWarnings(as.sir(interpretive_rules(
|
||||
data.frame(
|
||||
mo = example_isolates$mo,
|
||||
ERY = example_isolates$ERY,
|
||||
@@ -149,7 +150,7 @@ test_that("test-eucast_rules.R", {
|
||||
# amox is inferred by benzylpenicillin in Kingella kingae
|
||||
expect_equal(
|
||||
suppressWarnings(
|
||||
as.list(eucast_rules(
|
||||
as.list(interpretive_rules(
|
||||
data.frame(
|
||||
mo = as.mo("Kingella kingae"),
|
||||
PEN = "S",
|
||||
@@ -164,16 +165,16 @@ test_that("test-eucast_rules.R", {
|
||||
|
||||
# also test norf
|
||||
if (AMR:::pkg_is_available("dplyr", min_version = "1.0.0", also_load = TRUE)) {
|
||||
expect_output(suppressWarnings(eucast_rules(example_isolates %>% mutate(NOR = "S", NAL = "S"), info = TRUE)))
|
||||
expect_output(suppressWarnings(interpretive_rules(example_isolates %>% mutate(NOR = "S", NAL = "S"), info = TRUE)))
|
||||
}
|
||||
|
||||
# check verbose output
|
||||
expect_output(suppressWarnings(eucast_rules(example_isolates, verbose = TRUE, rules = "all", info = TRUE)))
|
||||
expect_output(suppressWarnings(interpretive_rules(example_isolates, verbose = TRUE, rules = "all", info = TRUE)))
|
||||
|
||||
# AmpC de-repressed cephalo mutants
|
||||
|
||||
expect_identical(
|
||||
eucast_rules(
|
||||
interpretive_rules(
|
||||
data.frame(
|
||||
mo = c("Escherichia coli", "Enterobacter cloacae"),
|
||||
cefotax = as.sir(c("S", "S"))
|
||||
@@ -187,7 +188,7 @@ test_that("test-eucast_rules.R", {
|
||||
)
|
||||
|
||||
expect_identical(
|
||||
eucast_rules(
|
||||
interpretive_rules(
|
||||
data.frame(
|
||||
mo = c("Escherichia coli", "Enterobacter cloacae"),
|
||||
cefotax = as.sir(c("S", "S"))
|
||||
@@ -201,7 +202,7 @@ test_that("test-eucast_rules.R", {
|
||||
)
|
||||
|
||||
expect_identical(
|
||||
eucast_rules(
|
||||
interpretive_rules(
|
||||
data.frame(
|
||||
mo = c("Escherichia coli", "Enterobacter cloacae"),
|
||||
cefotax = as.sir(c("S", "S"))
|
||||
@@ -219,7 +220,7 @@ test_that("test-eucast_rules.R", {
|
||||
expect_inherits(eucast_dosage(c("tobra", "genta", "cipro")), "data.frame")
|
||||
|
||||
|
||||
x <- custom_eucast_rules(
|
||||
x <- custom_interpretive_rules(
|
||||
AMC == "R" & genus == "Klebsiella" ~ aminopenicillins == "R",
|
||||
AMC == "I" & genus == "Klebsiella" ~ aminopenicillins == "I",
|
||||
AMX == "S" ~ AMC == "S"
|
||||
@@ -230,7 +231,7 @@ test_that("test-eucast_rules.R", {
|
||||
|
||||
# this custom rules makes 8 changes
|
||||
expect_equal(
|
||||
nrow(eucast_rules(example_isolates,
|
||||
nrow(interpretive_rules(example_isolates,
|
||||
rules = "custom",
|
||||
custom_rules = x,
|
||||
info = FALSE,
|
||||
@@ -240,4 +241,10 @@ test_that("test-eucast_rules.R", {
|
||||
8,
|
||||
tolerance = 0.5
|
||||
)
|
||||
|
||||
# clsi_rules() no longer errors (returns data unchanged until CLSI rows are added)
|
||||
expect_identical(
|
||||
suppressWarnings(clsi_rules(example_isolates, info = FALSE)),
|
||||
example_isolates
|
||||
)
|
||||
})
|
||||
Reference in New Issue
Block a user