antibiogram | R Documentation |
Create detailed antibiograms with options for traditional, combination, syndromic, and Bayesian WISCA methods.
Adhering to previously described approaches (see Source) and especially the Bayesian WISCA model (Weighted-Incidence Syndromic Combination Antibiogram) by Bielicki et al., these functions provide flexible output formats including plots and tables, ideal for integration with R Markdown and Quarto reports.
antibiogram(x, antibiotics = where(is.sir), mo_transform = "shortname",
ab_transform = "name", syndromic_group = NULL, add_total_n = FALSE,
only_all_tested = FALSE, digits = ifelse(wisca, 1, 0),
formatting_type = getOption("AMR_antibiogram_formatting_type", 14),
col_mo = NULL, language = get_AMR_locale(), minimum = 30,
combine_SI = TRUE, sep = " + ", wisca = FALSE, simulations = 1000,
conf_interval = 0.95, interval_side = "two-tailed",
info = interactive())
wisca(x, antibiotics = where(is.sir), ab_transform = "name",
syndromic_group = NULL, add_total_n = FALSE, only_all_tested = FALSE,
digits = 1,
formatting_type = getOption("AMR_antibiogram_formatting_type", 14),
col_mo = NULL, language = get_AMR_locale(), minimum = 30,
combine_SI = TRUE, sep = " + ", simulations = 1000,
conf_interval = 0.95, interval_side = "two-tailed",
info = interactive())
retrieve_wisca_parameters(wisca_model, ...)
## S3 method for class 'antibiogram'
plot(x, ...)
## S3 method for class 'antibiogram'
autoplot(object, ...)
## S3 method for class 'antibiogram'
knit_print(x, italicise = TRUE,
na = getOption("knitr.kable.NA", default = ""), ...)
x |
a data.frame containing at least a column with microorganisms and columns with antimicrobial results (class 'sir', see |
antibiotics |
vector of any antimicrobial name or code (will be evaluated with |
mo_transform |
a character to transform microorganism input - must be |
ab_transform |
a character to transform antimicrobial input - must be one of the column names of the antibiotics data set (defaults to |
syndromic_group |
a column name of |
add_total_n |
a logical to indicate whether |
only_all_tested |
(for combination antibiograms): a logical to indicate that isolates must be tested for all antimicrobials, see Details |
digits |
number of digits to use for rounding the antimicrobial coverage, defaults to 1 for WISCA and 0 otherwise |
formatting_type |
numeric value (1–22 for WISCA, 1-12 for non-WISCA) indicating how the 'cells' of the antibiogram table should be formatted. See Details > Formatting Type for a list of options. |
col_mo |
column name of the names or codes of the microorganisms (see |
language |
language to translate text, which defaults to the system language (see |
minimum |
the minimum allowed number of available (tested) isolates. Any isolate count lower than |
combine_SI |
a logical to indicate whether all susceptibility should be determined by results of either S, SDD, or I, instead of only S (default is |
sep |
a separating character for antimicrobial columns in combination antibiograms |
wisca |
a logical to indicate whether a Weighted-Incidence Syndromic Combination Antibiogram (WISCA) must be generated (default is |
simulations |
(for WISCA) a numerical value to set the number of Monte Carlo simulations |
conf_interval |
(for WISCA) a numerical value to set confidence interval (default is |
interval_side |
(for WISCA) the side of the confidence interval, either |
info |
a logical to indicate info should be printed - the default is |
wisca_model |
the outcome of |
... |
when used in R Markdown or Quarto: arguments passed on to |
object |
an |
italicise |
a logical to indicate whether the microorganism names in the knitr table should be made italic, using |
na |
character to use for showing |
These functions return a table with values between 0 and 100 for susceptibility, not resistance.
Remember that you should filter your data to let it contain only first isolates! This is needed to exclude duplicates and to reduce selection bias. Use first_isolate()
to determine them with one of the four available algorithms: isolate-based, patient-based, episode-based, or phenotype-based.
For estimating antimicrobial coverage, especially when creating a WISCA, the outcome might become more reliable by only including the top n species encountered in the data. You can filter on this top n using top_n_microorganisms()
. For example, use top_n_microorganisms(your_data, n = 10)
as a pre-processing step to only include the top 10 species in the data.
The numeric values of an antibiogram are stored in a long format as the attribute long_numeric
. You can retrieve them using attributes(x)$long_numeric
, where x
is the outcome of antibiogram()
or wisca()
. This is ideal for e.g. advanced plotting.
The formatting of the 'cells' of the table can be set with the argument formatting_type
. In these examples, 5
is the antimicrobial coverage (4-6
indicates the confidence level), 15
the number of susceptible isolates, and 300
the number of tested (i.e., available) isolates:
5
15
300
15/300
5 (300)
5% (300)
5 (N=300)
5% (N=300)
5 (15/300)
5% (15/300)
5 (N=15/300)
5% (N=15/300)
5 (4-6)
5% (4-6%) - default
5 (4-6,300)
5% (4-6%,300)
5 (4-6,N=300)
5% (4-6%,N=300)
5 (4-6,15/300)
5% (4-6%,15/300)
5 (4-6,N=15/300)
5% (4-6%,N=15/300)
The default is 14
, which can be set globally with the package option AMR_antibiogram_formatting_type
, e.g. options(AMR_antibiogram_formatting_type = 5)
. Do note that for WISCA, the total numbers of tested and susceptible isolates are less useful to report, since these are included in the Bayesian model and apparent from the susceptibility and its confidence level.
Set digits
(defaults to 0
) to alter the rounding of the susceptibility percentages.
There are various antibiogram types, as summarised by Klinker et al. (2021, \Sexpr[results=rd]{tools:::Rd_expr_doi("10.1177/20499361211011373")}), and they are all supported by antibiogram()
.
For clinical coverage estimations, use WISCA whenever possible, since it provides more precise coverage estimates by accounting for pathogen incidence and antimicrobial susceptibility, as has been shown by Bielicki et al. (2020, \Sexpr[results=rd]{tools:::Rd_expr_doi("10.1001.jamanetworkopen.2019.21124")}). See the section Explaining WISCA on this page. Do note that WISCA is pathogen-agnostic, meaning that the outcome is not stratied by pathogen, but rather by syndrome.
Traditional Antibiogram
Case example: Susceptibility of Pseudomonas aeruginosa to piperacillin/tazobactam (TZP)
Code example:
antibiogram(your_data, antibiotics = "TZP")
Combination Antibiogram
Case example: Additional susceptibility of Pseudomonas aeruginosa to TZP + tobramycin versus TZP alone
Code example:
antibiogram(your_data, antibiotics = c("TZP", "TZP+TOB", "TZP+GEN"))
Syndromic Antibiogram
Case example: Susceptibility of Pseudomonas aeruginosa to TZP among respiratory specimens (obtained among ICU patients only)
Code example:
antibiogram(your_data, antibiotics = penicillins(), syndromic_group = "ward")
Weighted-Incidence Syndromic Combination Antibiogram (WISCA)
WISCA can be applied to any antibiogram, see the section Explaining WISCA on this page for more information.
Code example:
antibiogram(your_data, antibiotics = c("TZP", "TZP+TOB", "TZP+GEN"), wisca = TRUE) # this is equal to: wisca(your_data, antibiotics = c("TZP", "TZP+TOB", "TZP+GEN"))
WISCA uses a sophisticated Bayesian decision model to combine both local and pooled antimicrobial resistance data. This approach not only evaluates local patterns but can also draw on multi-centre datasets to improve regimen accuracy, even in low-incidence infections like paediatric bloodstream infections (BSIs).
For any type of antibiogram, grouped tibbles can also be used to calculate susceptibilities over various groups.
Code example:
library(dplyr) your_data %>% group_by(has_sepsis, is_neonate, sex) %>% wisca(antibiotics = c("TZP", "TZP+TOB", "TZP+GEN"))
In clinical practice, antimicrobial coverage decisions evolve as more microbiological data becomes available. This theoretical stepped approach ensures empirical coverage can continuously assessed to improve patient outcomes:
Initial Empirical Therapy (Admission / Pre-Culture Data)
At admission, no pathogen information is available.
Action: broad-spectrum coverage is based on local resistance patterns and syndromic antibiograms. Using the pathogen-agnostic yet incidence-weighted WISCA is preferred.
Code example:
antibiogram(your_data, antibiotics = selected_regimens, mo_transform = NA) # all pathogens set to `NA` # preferred: use WISCA wisca(your_data, antibiotics = selected_regimens)
Refinement with Gram Stain Results
When a blood culture becomes positive, the Gram stain provides an initial and crucial first stratification (Gram-positive vs. Gram-negative).
Action: narrow coverage based on Gram stain-specific resistance patterns.
Code example:
antibiogram(your_data, antibiotics = selected_regimens, mo_transform = "gramstain") # all pathogens set to Gram-pos/Gram-neg
Definitive Therapy Based on Species Identification
After cultivation of the pathogen, full pathogen identification allows precise targeting of therapy.
Action: adjust treatment to pathogen-specific antibiograms, minimizing resistance risks.
Code example:
antibiogram(your_data, antibiotics = selected_regimens, mo_transform = "shortname") # all pathogens set to 'G. species', e.g., E. coli
By structuring antibiograms around this stepped approach, clinicians can make data-driven adjustments at each stage, ensuring optimal empirical and targeted therapy while reducing unnecessary broad-spectrum antimicrobial use.
Note that for combination antibiograms, it is important to realise that susceptibility can be calculated in two ways, which can be set with the only_all_tested
argument (default is FALSE
). See this example for two antimicrobials, Drug A and Drug B, about how antibiogram()
works to calculate the %SI:
-------------------------------------------------------------------- only_all_tested = FALSE only_all_tested = TRUE ----------------------- ----------------------- Drug A Drug B considered considered considered considered susceptible tested susceptible tested -------- -------- ----------- ---------- ----------- ---------- S or I S or I X X X X R S or I X X X X <NA> S or I X X - - S or I R X X X X R R - X - X <NA> R - - - - S or I <NA> X X - - R <NA> - - - - <NA> <NA> - - - - --------------------------------------------------------------------
All types of antibiograms as listed above can be plotted (using ggplot2::autoplot()
or base R's plot()
and barplot()
). As mentioned above, the numeric values of an antibiogram are stored in a long format as the attribute long_numeric
. You can retrieve them using attributes(x)$long_numeric
, where x
is the outcome of antibiogram()
or wisca()
.
The outcome of antibiogram()
can also be used directly in R Markdown / Quarto (i.e., knitr
) for reports. In this case, knitr::kable()
will be applied automatically and microorganism names will even be printed in italics at default (see argument italicise
).
You can also use functions from specific 'table reporting' packages to transform the output of antibiogram()
to your needs, e.g. with flextable::as_flextable()
or gt::gt()
.
WISCA, as outlined by Bielicki et al. (\Sexpr[results=rd]{tools:::Rd_expr_doi("10.1093/jac/dkv397")}), stands for Weighted-Incidence Syndromic Combination Antibiogram, which estimates the probability of adequate empirical antimicrobial regimen coverage for specific infection syndromes. This method leverages a Bayesian decision model with random effects for pathogen incidence and susceptibility, enabling robust estimates in the presence of sparse data.
The Bayesian model assumes conjugate priors for parameter estimation. For example, the coverage probability \theta
for a given antimicrobial regimen is modelled using a Beta distribution as a prior:
\theta \sim \text{Beta}(\alpha_0, \beta_0)
where \alpha_0
and \beta_0
represent prior successes and failures, respectively, informed by expert knowledge or weakly informative priors (e.g., \alpha_0 = 1, \beta_0 = 1
). The likelihood function is constructed based on observed data, where the number of covered cases for a regimen follows a binomial distribution:
y \sim \text{Binomial}(n, \theta)
Posterior parameter estimates are obtained by combining the prior and likelihood using Bayes' theorem. The posterior distribution of \theta
is also a Beta distribution:
\theta | y \sim \text{Beta}(\alpha_0 + y, \beta_0 + n - y)
Pathogen incidence, representing the proportion of infections caused by different pathogens, is modelled using a Dirichlet distribution, which is the natural conjugate prior for multinomial outcomes. The Dirichlet distribution is parameterised by a vector of concentration parameters \alpha
, where each \alpha_i
corresponds to a specific pathogen. The prior is typically chosen to be uniform (\alpha_i = 1
), reflecting an assumption of equal prior probability across pathogens.
The posterior distribution of pathogen incidence is then given by:
\text{Dirichlet}(\alpha_1 + n_1, \alpha_2 + n_2, \dots, \alpha_K + n_K)
where n_i
is the number of infections caused by pathogen i
observed in the data. For practical implementation, pathogen incidences are sampled from their posterior using normalised Gamma-distributed random variables:
x_i \sim \text{Gamma}(\alpha_i + n_i, 1)
p_i = \frac{x_i}{\sum_{j=1}^K x_j}
where x_i
represents unnormalised pathogen counts, and p_i
is the normalised proportion for pathogen i
.
For hierarchical modelling, pathogen-level effects (e.g., differences in resistance patterns) and regimen-level effects are modelled using Gaussian priors on log-odds. This hierarchical structure ensures partial pooling of estimates across groups, improving stability in strata with small sample sizes. The model is implemented using Hamiltonian Monte Carlo (HMC) sampling.
Stratified results can be provided based on covariates such as age, sex, and clinical complexity (e.g., prior antimicrobial treatments or renal/urological comorbidities) using dplyr
's group_by()
as a pre-processing step before running wisca()
. Posterior odds ratios (ORs) are derived to quantify the effect of these covariates on coverage probabilities:
\text{OR}_{\text{covariate}} = \frac{\exp(\beta_{\text{covariate}})}{\exp(\beta_0)}
By combining empirical data with prior knowledge, WISCA overcomes the limitations of traditional combination antibiograms, offering disease-specific, patient-stratified estimates with robust uncertainty quantification. This tool is invaluable for antimicrobial stewardship programs and empirical treatment guideline refinement.
Note: WISCA never gives an output on the pathogen/species level, as all incidences and susceptibilities are already weighted for all species.
Implementation: Dr. Larisse Bolton and Dr. Matthijs Berends
Bielicki JA et al. (2016). Selecting appropriate empirical antibiotic regimens for paediatric bloodstream infections: application of a Bayesian decision model to local and pooled antimicrobial resistance surveillance data Journal of Antimicrobial Chemotherapy 71(3); \Sexpr[results=rd]{tools:::Rd_expr_doi("10.1093/jac/dkv397")}
Bielicki JA et al. (2020). Evaluation of the coverage of 3 antibiotic regimens for neonatal sepsis in the hospital setting across Asian countries JAMA Netw Open. 3(2):e1921124; \Sexpr[results=rd]{tools:::Rd_expr_doi("10.1001.jamanetworkopen.2019.21124")}
Klinker KP et al. (2021). Antimicrobial stewardship and antibiograms: importance of moving beyond traditional antibiograms. Therapeutic Advances in Infectious Disease, May 5;8:20499361211011373; \Sexpr[results=rd]{tools:::Rd_expr_doi("10.1177/20499361211011373")}
Barbieri E et al. (2021). Development of a Weighted-Incidence Syndromic Combination Antibiogram (WISCA) to guide the choice of the empiric antibiotic treatment for urinary tract infection in paediatric patients: a Bayesian approach Antimicrobial Resistance & Infection Control May 1;10(1):74; \Sexpr[results=rd]{tools:::Rd_expr_doi("10.1186/s13756-021-00939-2")}
M39 Analysis and Presentation of Cumulative Antimicrobial Susceptibility Test Data, 5th Edition, 2022, Clinical and Laboratory Standards Institute (CLSI). https://clsi.org/standards/products/microbiology/documents/m39/.
# example_isolates is a data set available in the AMR package.
# run ?example_isolates for more info.
example_isolates
# Traditional antibiogram ----------------------------------------------
antibiogram(example_isolates,
antibiotics = c(aminoglycosides(), carbapenems())
)
antibiogram(example_isolates,
antibiotics = aminoglycosides(),
ab_transform = "atc",
mo_transform = "gramstain"
)
antibiogram(example_isolates,
antibiotics = carbapenems(),
ab_transform = "name",
mo_transform = "name"
)
# Combined antibiogram -------------------------------------------------
# combined antibiotics yield higher empiric coverage
antibiogram(example_isolates,
antibiotics = c("TZP", "TZP+TOB", "TZP+GEN"),
mo_transform = "gramstain"
)
# names of antibiotics do not need to resemble columns exactly:
antibiogram(example_isolates,
antibiotics = c("Cipro", "cipro + genta"),
mo_transform = "gramstain",
ab_transform = "name",
sep = " & "
)
# Syndromic antibiogram ------------------------------------------------
# the data set could contain a filter for e.g. respiratory specimens
antibiogram(example_isolates,
antibiotics = c(aminoglycosides(), carbapenems()),
syndromic_group = "ward"
)
# now define a data set with only E. coli
ex1 <- example_isolates[which(mo_genus() == "Escherichia"), ]
# with a custom language, though this will be determined automatically
# (i.e., this table will be in Spanish on Spanish systems)
antibiogram(ex1,
antibiotics = aminoglycosides(),
ab_transform = "name",
syndromic_group = ifelse(ex1$ward == "ICU",
"UCI", "No UCI"
),
language = "es"
)
# WISCA antibiogram ----------------------------------------------------
# WISCA are not stratified by species, but rather on syndromes
antibiogram(example_isolates,
antibiotics = c("TZP", "TZP+TOB", "TZP+GEN"),
syndromic_group = "ward",
wisca = TRUE
)
# Print the output for R Markdown / Quarto -----------------------------
ureido <- antibiogram(example_isolates,
antibiotics = ureidopenicillins(),
syndromic_group = "ward",
wisca = TRUE
)
# in an Rmd file, you would just need to return `ureido` in a chunk,
# but to be explicit here:
if (requireNamespace("knitr")) {
cat(knitr::knit_print(ureido))
}
# Generate plots with ggplot2 or base R --------------------------------
ab1 <- antibiogram(example_isolates,
antibiotics = c("AMC", "CIP", "TZP", "TZP+TOB"),
mo_transform = "gramstain"
)
ab2 <- antibiogram(example_isolates,
antibiotics = c("AMC", "CIP", "TZP", "TZP+TOB"),
mo_transform = "gramstain",
syndromic_group = "ward"
)
if (requireNamespace("ggplot2")) {
ggplot2::autoplot(ab1)
}
if (requireNamespace("ggplot2")) {
ggplot2::autoplot(ab2)
}
plot(ab1)
plot(ab2)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.