Include isolates of unknown species in grouped antibiograms and in wisca(), which were silently excluded with the warning 'invalid microorganism code, NA generated'

This commit is contained in:
dr. M.S. (Matthijs) Berends committed 2026-10-15 10:21:44 +02:00
1 parent 3a87075ad3
commit eb6d07e1fe
4 files changed
+28 -7

No files matched your search

+1
View File
@@ -110,6 +110,7 @@ Planned as v3.1.0, mid October 2026.
* Antibiograms (`antibiogram()` and `wisca()`)
* `wisca()` now follows Bielicki *et al.* (2016) more strictly by using $\text{Beta}(1, 9999)$ for intrinsically resistant pairs, forcing near-zero susceptibility regardless of observed data (based on EUCAST Expected Resistant Phenotypes)
* Fixed a bug where both functions failed without the `antimicrobials` argument if `tidyselect` was not available, e.g., for binary installations without `dplyr`
* Isolates of unknown species are now included in grouped antibiograms and in `wisca()`, as they already were in traditional antibiograms. They were previously excluded silently, with the warning "invalid microorganism code, NA generated". This can change WISCA coverage estimates.
* Resistance and susceptibility calculation
* New argument `guideline` (default: the `AMR_guideline` option, otherwise EUCAST) in `susceptibility()`, `resistance()`, `count_df()`, `proportion_df()`, `sir_df()`, `ggplot_sir()`, `geom_sir()`, `labels_sir_count()`, `antibiogram()`, `wisca()`, and `bug_drug_combinations()` to interpret the 'I' category correctly per guideline. Functions that return results per category also accept `guideline = NULL` to keep S, I, and R separate, while functions that return a single proportion or count give an informative error.
* When EUCAST is assumed because neither the `guideline` argument nor the `AMR_guideline` option is set, a message explains how to change this, once per session and not in R Markdown or Quarto documents
+7 -1
View File
@@ -578,7 +578,13 @@ antibiogram.default <- function(x,
x$`.mo` <- mo_property(x$`.mo`, property = mo_transform, language = language)
}
}
x$`.mo`[x$`.mo` %in% c(NA, "UNKNOWN")] <- "(??)"
# keep unknown microorganisms, so that they are also included in grouped antibiograms and WISCA
if (is.mo(x$`.mo`)) {
# the 'mo' class only allows valid codes, of which "UNKNOWN" is one
x$`.mo`[is.na(x$`.mo`)] <- "UNKNOWN"
} else {
x$`.mo`[x$`.mo` %in% c(NA, "UNKNOWN")] <- "(??)"
}
# get antimicrobials
ab_trycatch <- tryCatch(colnames(suppressWarnings(x[, antimicrobials, drop = FALSE])), error = function(e) NULL)
+4 -6
View File
@@ -220,12 +220,11 @@ the full explanation.
wisca(example_isolates,
antimicrobials = c("TZP", "TZP+TOB", "TZP+GEN"),
minimum = 10) # Recommended threshold: >=30
#> Warning: invalid microorganism code, NA generated
```
| Piperacillin/tazobactam | Piperacillin/tazobactam + Gentamicin | Piperacillin/tazobactam + Tobramycin |
|:------------------------|:-------------------------------------|:-------------------------------------|
| 69.8% (64.5-74.7%) | 93.6% (92.1-95%) | 89.9% (87-92.5%) |
| 70.2% (65-75.4%) | 93.6% (92-95.1%) | 89.9% (87-92.5%) |
WISCA supports stratification by any clinical variable, so you can
generate syndrome-specific or ward-specific coverage estimates:
@@ -235,14 +234,13 @@ wisca(example_isolates,
antimicrobials = c("TZP", "TZP+TOB", "TZP+GEN"),
syndromic_group = "ward",
minimum = 10) # Recommended threshold: >=30
#> Warning: invalid microorganism code, NA generated
```
| Syndromic Group | Piperacillin/tazobactam | Piperacillin/tazobactam + Gentamicin | Piperacillin/tazobactam + Tobramycin |
|:----------------|:------------------------|:-------------------------------------|:-------------------------------------|
| Clinical | 74.6% (69.1-80.1%) | 93.7% (92.1-95.1%) | 90.3% (87-93.1%) |
| ICU | 56.9% (48.3-66%) | 86.7% (83.5-89.8%) | 83% (77.9-87.4%) |
| Outpatient | 57.7% (46.5-69.3%) | 76.6% (70.5-82.2%) | 67.8% (56.9-77.5%) |
| Clinical | 74.8% (69-80.3%) | 93.7% (92.1-95.1%) | 90.4% (86.8-93.3%) |
| ICU | 56.7% (48.2-65.4%) | 86.6% (83.3-89.6%) | 83.1% (78.2-87.5%) |
| Outpatient | 57.6% (46-69%) | 76.4% (69.8-81.7%) | 68% (57.7-77.5%) |
**For AMR surveillance**, traditional antibiograms remain the right tool
for tracking resistance per species over time:
+16
View File
@@ -40,6 +40,22 @@ test_that("test-antibiogram.R", {
expect_identical(get_gen(combine_SI = TRUE, guideline = "CLSI"), gen_eucast)
expect_identical(get_gen(combine_SI = FALSE, guideline = "EUCAST"), gen_clsi) # identical since example_isolates contains no SDD
# isolates of unknown species must be included, also in WISCA
set.seed(1)
wisca_all <- suppressMessages(wisca(example_isolates, antimicrobials = "GEN", simulations = 100, info = FALSE, guideline = "EUCAST"))
set.seed(1)
wisca_known <- suppressMessages(wisca(example_isolates[example_isolates$mo != "UNKNOWN", ], antimicrobials = "GEN", simulations = 100, info = FALSE, guideline = "EUCAST"))
expect_true("UNKNOWN" %in% attributes(wisca_all)$wisca_parameters$mo)
expect_false(identical(as.data.frame(wisca_all), as.data.frame(wisca_known)))
if (AMR:::pkg_is_available("dplyr", min_version = "1.0.0", also_load = TRUE)) {
ab_grouped <- tryCatch(
example_isolates %>% group_by(ward) %>% antibiogram(antimicrobials = "GEN", minimum = 0, formatting_type = 1, guideline = "EUCAST"),
warning = function(w) conditionMessage(w)
)
expect_inherits(ab_grouped, "antibiogram")
expect_true("UNKNOWN" %in% as.character(ab_grouped[[2]]))
}
# Traditional antibiogram ----------------------------------------------