(v3.1.0.9011) Use top_n_microorganisms() in the WISCA examples of the index, manual and vignette, and reword the WISCA prior weight warning to also cover small groups (#337)

This commit is contained in:
dr. M.S. (Matthijs) Berends committed 2026-10-30 12:45:56 +01:00
1 parent fdfdadae14
commit 944078c4bc
7 files changed
+33 -30

No files matched your search

+1 -1
View File
@@ -1,5 +1,5 @@
Package: AMR
Version: 3.1.0.9010
Version: 3.1.0.9011
Date: 2026-10-30
Title: Antimicrobial Resistance Data Analysis
Description: Functions to simplify and standardise antimicrobial resistance (AMR)
+2 -2
View File
@@ -1,4 +1,4 @@
# AMR 3.1.0.9010
# AMR 3.1.0.9011
This version fixes a critical bug in WISCA that biased all coverage estimates of `wisca()` and `antibiogram(..., wisca = TRUE)` downwards since AMR 3.0.0. Users are strongly advised to re-run their WISCA analyses.
@@ -6,7 +6,7 @@ This version fixes a critical bug in WISCA that biased all coverage estimates of
* WISCA (`wisca()` and `antibiogram(..., wisca = TRUE)`)
* Fixed a critical bug that systematically underestimated the coverage of every WISCA since AMR 3.0.0. Pathogens absent from a syndromic group, and pathogens without any test result for a regimen, were still included in the model with only prior information: each added a prior weight of 1 to the pathogen incidence, and untested pathogens kept their full incidence weight while counting as about 50% susceptible. The bias was largest for stratified analyses (e.g., up to 14 percentage points for meropenem in random strata of `example_isolates`). Now, only pathogens that occur in a group and have at least one test result for the regimen are included. Please re-run all WISCA analyses (#337)
* `retrieve_wisca_parameters()` now returns only the parameters actually used in the model, and `n_total` in the `long_numeric` attribute now counts only isolates of the pathogens included for that regimen
* A new warning is given when the prior weight of 1 per pathogen (Bielicki *et al.*, 2016) accounts for more than 5% of the pathogen incidence, as many rare pathogens can then strongly lower the estimated coverage; consider `top_n_microorganisms()` in that case
* A new warning is given when the prior weight of 1 per pathogen (Bielicki *et al.*, 2016) accounts for more than 5% of the pathogen incidence, i.e., with rare pathogens or small groups, as this can strongly lower the estimated coverage; consider `top_n_microorganisms()` or fewer and larger groups in that case
* Microorganism coercion (`as.mo()`)
* Fixed the misaligned arrows in the message on taxonomically renamed microorganisms in colour-supporting consoles, for old names whose author reference lacks "*et al.*" (#336)
+9 -8
View File
@@ -158,7 +158,7 @@
#'
#' **Pathogens included in the model:** For each regimen (and group), only pathogens that occur in the data and have at least one test result for the regimen are included. Pathogens without any test result for a regimen do not contribute to its coverage, nor to its `n_total` in `long_numeric`. Use [retrieve_wisca_parameters()] to get the parameters that were used.
#'
#' **Rare pathogens:** Since every pathogen receives a prior weight of 1 in the Dirichlet distribution, pathogens found only once or a few times are given relatively much weight, which pulls the incidence towards a uniform distribution. Their very uncertain susceptibility can then strongly lower the estimated coverage, without reflecting the clinical expectation. A warning is therefore given when this prior weight accounts for more than 5% of the pathogen incidence in any regimen (or group). Consider limiting the analysis to the most common pathogens using [top_n_microorganisms()], or grouping rare pathogens before running WISCA.
#' **Rare pathogens and small groups:** Since every pathogen receives a prior weight of 1 in the Dirichlet distribution, the prior weighs heavily when there are few isolates relative to the number of pathogens, i.e., with pathogens found only once or a few times, or in small groups. This pulls the incidence towards a uniform distribution, and the very uncertain susceptibility of rare pathogens can then strongly lower the estimated coverage, without reflecting the clinical expectation. A warning is therefore given when this prior weight accounts for more than 5% of the pathogen incidence in any regimen (or group). Consider limiting the analysis to the most common pathogens using [top_n_microorganisms()], or using fewer and larger groups.
#'
#' **Interpreting the output:** Overlapping credible intervals between regimens indicate no significant difference in coverage; if a narrower-spectrum regimen overlaps with a broader one, the narrower-spectrum option may be preferred on stewardship grounds. Non-overlapping intervals indicate a clinically meaningful difference. For small sample sizes, consider pooling data from multiple sites to improve precision, provided pathogen distributions are sufficiently similar (Bielicki *et al.*, 2016).
#'
@@ -186,12 +186,13 @@
#'
#' # basic WISCA: empirical coverage per regimen, weighted by pathogen
#' # incidence, with 95% credible intervals
#' wisca(example_isolates,
#' # (10 most common species, since rare species can distort coverage estimates)
#' wisca(top_n_microorganisms(example_isolates, n = 10),
#' antimicrobials = c("AMC", "AMC+CIP", "AMC+GEN")
#' )
#'
#' # equivalent using antibiogram():
#' antibiogram(example_isolates,
#' antibiogram(top_n_microorganisms(example_isolates, n = 10),
#' antimicrobials = c("AMC", "AMC+CIP", "AMC+GEN"),
#' wisca = TRUE
#' )
@@ -276,7 +277,7 @@
#'
#' # Print the output for R Markdown / Quarto -----------------------------
#'
#' ureido <- wisca(example_isolates,
#' ureido <- wisca(top_n_microorganisms(example_isolates, n = 10),
#' antimicrobials = ureidopenicillins(),
#' syndromic_group = "ward"
#' )
@@ -294,7 +295,7 @@
#' antimicrobials = c("AMC", "CIP", "TZP", "TZP+TOB"),
#' mo_transform = "gramstain"
#' )
#' ab2 <- wisca(example_isolates,
#' ab2 <- wisca(top_n_microorganisms(example_isolates, n = 10),
#' antimicrobials = c("AMC", "CIP", "TZP", "TZP+TOB"),
#' syndromic_group = "ward"
#' )
@@ -777,9 +778,9 @@ antibiogram.default <- function(x,
)
if (any(prior_share > 0.05)) {
warning_(
"In ", sum(prior_share > 0.05), " of ", length(prior_share), " WISCA regimen(s) or group(s), the prior weight of 1 per pathogen accounts for more than 5% of the pathogen incidence (up to ", round(max(prior_share) * 100, 1), "%), since many pathogens occur only rarely. ",
"Because WISCA gives every pathogen a prior weight of 1 (Bielicki et al., 2016), such rare pathogens can strongly lower the estimated coverage without reflecting the clinical expectation. ",
"Consider limiting the analysis to the most common pathogens with {.help [{.fun top_n_microorganisms}](AMR::top_n_microorganisms)}, or grouping rare pathogens before running WISCA.",
"In ", sum(prior_share > 0.05), " of ", length(prior_share), " WISCA regimen(s) or group(s), the prior weight of 1 per pathogen accounts for more than 5% of the pathogen incidence (up to ", round(max(prior_share) * 100, 1), "%), since there are few isolates relative to the number of pathogens, i.e., rare pathogens or a small group. ",
"Because WISCA gives every pathogen a prior weight of 1 (Bielicki et al., 2016), this can strongly lower the estimated coverage without reflecting the clinical expectation. ",
"Consider limiting the analysis to the most common pathogens with {.help [{.fun top_n_microorganisms}](AMR::top_n_microorganisms)}, or using fewer and larger groups.",
call = FALSE
)
}
+2 -2
View File
@@ -94,7 +94,7 @@ The `AMR` package supports four types of antibiograms, with support for `r lengt
**For empirical therapy guidance (i.e., coverage estimates), use WISCA** (Weighted-Incidence Syndromic Combination Antibiogram). When a clinician starts empirical treatment, the causative pathogen is unknown. The relevant question is not *"what percentage of E. coli is susceptible?"* but *"what is the probability that this regimen will cover whatever pathogen is causing the infection?"*. WISCA answers that question directly, weighting susceptibility by pathogen incidence and providing credible intervals via Bayesian simulation. See `vignette("WISCA")` for the full explanation.
```{r}
wisca(example_isolates,
wisca(top_n_microorganisms(example_isolates, n = 10), # 10 most common species
antimicrobials = c("TZP", "TZP+TOB", "TZP+GEN"),
minimum = 10) # Recommended threshold: >=30
```
@@ -102,7 +102,7 @@ wisca(example_isolates,
WISCA supports stratification by any clinical variable, so you can generate syndrome-specific or ward-specific coverage estimates:
```{r}
wisca(example_isolates,
wisca(top_n_microorganisms(example_isolates, n = 10),
antimicrobials = c("TZP", "TZP+TOB", "TZP+GEN"),
syndromic_group = "ward",
minimum = 10) # Recommended threshold: >=30
+12 -12
View File
@@ -217,36 +217,36 @@ credible intervals via Bayesian simulation. See `vignette("WISCA")` for
the full explanation.
``` r
wisca(example_isolates,
wisca(top_n_microorganisms(example_isolates, n = 10), # 10 most common species
antimicrobials = c("TZP", "TZP+TOB", "TZP+GEN"),
minimum = 10) # Recommended threshold: >=30
```
| Piperacillin/tazobactam | Piperacillin/tazobactam + Gentamicin | Piperacillin/tazobactam + Tobramycin |
|:------------------------|:-------------------------------------|:-------------------------------------|
| 72.5% (67.7-77.1%) | 96% (95.1-96.9%) | 92.1% (89.3-94.4%) |
| 73% (67.7-79%) | 98.7% (98-99.2%) | 93.8% (90.5-96.6%) |
WISCA supports stratification by any clinical variable, so you can
generate syndrome-specific or ward-specific coverage estimates:
``` r
wisca(example_isolates,
wisca(top_n_microorganisms(example_isolates, n = 10),
antimicrobials = c("TZP", "TZP+TOB", "TZP+GEN"),
syndromic_group = "ward",
minimum = 10) # Recommended threshold: >=30
#> Warning: In 6 of 9 WISCA regimen(s) or group(s), the prior weight of 1 per pathogen accounts for more than
#> 5% of the pathogen incidence (up to 13.3%), since many pathogens occur only rarely. Because WISCA
#> gives every pathogen a prior weight of 1 (Bielicki et al., 2016), such rare pathogens can strongly
#> lower the estimated coverage without reflecting the clinical expectation. Consider limiting the
#> analysis to the most common pathogens with `top_n_microorganisms()`, or grouping rare pathogens
#> before running WISCA.
#> Warning: In 3 of 9 WISCA regimen(s) or group(s), the prior weight of 1 per pathogen accounts for more than
#> 5% of the pathogen incidence (up to 6.4%), since there are few isolates relative to the number of
#> pathogens, i.e., rare pathogens or a small group. Because WISCA gives every pathogen a prior weight
#> of 1 (Bielicki et al., 2016), this can strongly lower the estimated coverage without reflecting the
#> clinical expectation. Consider limiting the analysis to the most common pathogens with
#> `top_n_microorganisms()`, or using fewer and larger groups.
```
| Syndromic Group | Piperacillin/tazobactam | Piperacillin/tazobactam + Gentamicin | Piperacillin/tazobactam + Tobramycin |
|:----------------|:------------------------|:-------------------------------------|:-------------------------------------|
| Clinical | 78% (72.7-83.4%) | 96.3% (95.1-97.3%) | 93% (89.4-95.7%) |
| ICU | 59.7% (53.5-67.9%) | 92.2% (90-94.3%) | 88.2% (83.4-92.2%) |
| Outpatient | 67.9% (51.9-84.7%) | 92.8% (88.2-96.6%) | 79.8% (64.9-92.9%) |
| Clinical | 78.9% (72.8-85.6%) | 98.7% (97.8-99.3%) | 94.5% (90.3-97.6%) |
| ICU | 57.3% (48.9-69.5%) | 97.5% (95.7-98.8%) | 91.7% (85.8-96.3%) |
| Outpatient | 68% (49.4-88.5%) | 95.7% (90.7-98.7%) | 79.3% (62.7-93.8%) |
**For AMR surveillance**, traditional antibiograms remain the right tool
for tracking resistance per species over time:
+6 -5
View File
@@ -270,7 +270,7 @@ It does so by combining two quantities: the relative incidence of each pathogen
\strong{Pathogens included in the model:} For each regimen (and group), only pathogens that occur in the data and have at least one test result for the regimen are included. Pathogens without any test result for a regimen do not contribute to its coverage, nor to its \code{n_total} in \code{long_numeric}. Use \code{\link[=retrieve_wisca_parameters]{retrieve_wisca_parameters()}} to get the parameters that were used.
\strong{Rare pathogens:} Since every pathogen receives a prior weight of 1 in the Dirichlet distribution, pathogens found only once or a few times are given relatively much weight, which pulls the incidence towards a uniform distribution. Their very uncertain susceptibility can then strongly lower the estimated coverage, without reflecting the clinical expectation. A warning is therefore given when this prior weight accounts for more than 5\% of the pathogen incidence in any regimen (or group). Consider limiting the analysis to the most common pathogens using \code{\link[=top_n_microorganisms]{top_n_microorganisms()}}, or grouping rare pathogens before running WISCA.
\strong{Rare pathogens and small groups:} Since every pathogen receives a prior weight of 1 in the Dirichlet distribution, the prior weighs heavily when there are few isolates relative to the number of pathogens, i.e., with pathogens found only once or a few times, or in small groups. This pulls the incidence towards a uniform distribution, and the very uncertain susceptibility of rare pathogens can then strongly lower the estimated coverage, without reflecting the clinical expectation. A warning is therefore given when this prior weight accounts for more than 5\% of the pathogen incidence in any regimen (or group). Consider limiting the analysis to the most common pathogens using \code{\link[=top_n_microorganisms]{top_n_microorganisms()}}, or using fewer and larger groups.
\strong{Interpreting the output:} Overlapping credible intervals between regimens indicate no significant difference in coverage; if a narrower-spectrum regimen overlaps with a broader one, the narrower-spectrum option may be preferred on stewardship grounds. Non-overlapping intervals indicate a clinically meaningful difference. For small sample sizes, consider pooling data from multiple sites to improve precision, provided pathogen distributions are sufficiently similar (Bielicki \emph{et al.}, 2016).
@@ -357,12 +357,13 @@ example_isolates
# basic WISCA: empirical coverage per regimen, weighted by pathogen
# incidence, with 95\% credible intervals
wisca(example_isolates,
# (10 most common species, since rare species can distort coverage estimates)
wisca(top_n_microorganisms(example_isolates, n = 10),
antimicrobials = c("AMC", "AMC+CIP", "AMC+GEN")
)
# equivalent using antibiogram():
antibiogram(example_isolates,
antibiogram(top_n_microorganisms(example_isolates, n = 10),
antimicrobials = c("AMC", "AMC+CIP", "AMC+GEN"),
wisca = TRUE
)
@@ -447,7 +448,7 @@ antibiogram(ex1,
# Print the output for R Markdown / Quarto -----------------------------
ureido <- wisca(example_isolates,
ureido <- wisca(top_n_microorganisms(example_isolates, n = 10),
antimicrobials = ureidopenicillins(),
syndromic_group = "ward"
)
@@ -465,7 +466,7 @@ ab1 <- antibiogram(example_isolates,
antimicrobials = c("AMC", "CIP", "TZP", "TZP+TOB"),
mo_transform = "gramstain"
)
ab2 <- wisca(example_isolates,
ab2 <- wisca(top_n_microorganisms(example_isolates, n = 10),
antimicrobials = c("AMC", "CIP", "TZP", "TZP+TOB"),
syndromic_group = "ward"
)
+1
View File
@@ -270,6 +270,7 @@ Use the `wisca()` function, or equivalently `antibiogram(..., wisca = TRUE)`. WI
```{r wisca}
wisca_result <- example_isolates %>%
top_n_microorganisms(n = 10) %>%
wisca(
antimicrobials = c("TZP", "TZP+TOB", "TZP+GEN"),
minimum = 10