(v3.0.1.9123) Add method argument to sir_combine() for resistance within a group (most_resistant), and restore the AMR 3.0.1 behaviour of count_*() and proportion_*() for multiple antimicrobials (#321)

This commit is contained in:
dr. M.S. (Matthijs) Berends committed 2026-10-12 21:37:13 +02:00
1 parent 239c5a87a8
commit bf12e3abe7
13 files changed
+322 -141

No files matched your search

+1 -1
View File
@@ -1,5 +1,5 @@
Package: AMR
Version: 3.0.1.9122
Version: 3.0.1.9123
Date: 2026-10-12
Title: Antimicrobial Resistance Data Analysis
Description: Functions to simplify and standardise antimicrobial resistance (AMR)
+2 -3
View File
@@ -1,4 +1,4 @@
# AMR 3.0.1.9122
# AMR 3.0.1.9123
Planned as v3.1.0, mid October 2026.
@@ -25,7 +25,6 @@ Planned as v3.1.0, mid October 2026.
* Faster parallel computing via the `future` package for `as.sir()` and `wisca()`: a non-sequential plan (e.g. `future::plan(future::multisession)`) must be active before using `parallel = TRUE`.
* `as.mo()` no longer guesses unknown MO codes (these become `NA` with a warning), and MO codes from versions before v2.0.0 are no longer supported
* With multiple antimicrobials, `count_*()` and `proportion_*()` now follow the documented combination therapy rules: `resistance()` returns the proportion of failing combinations instead of resistance to any of the antimicrobials, and `count_all()` excludes isolates of which the combination result is unknown (#321)
### New
* EUCAST 2026 and CLSI 2026 breakpoints: over 5,700 new breakpoints added to the `clinical_breakpoints` data set; EUCAST 2026 is now the default for all MIC and disk diffusion interpretations
@@ -45,7 +44,7 @@ Planned as v3.1.0, mid October 2026.
* New `wisca_plot()` to assess the susceptibility and incidence distributions from the Monte Carlo simulations
* A registry of all microbial IDs (MO codes) since v2.0.0 now prevents existing IDs from being reused or mixed up; IDs of earlier releases are translated to the current ID of the same taxon
* `add_custom_antimicrobial_synonyms()` to add local names, such as trade names, to existing antimicrobials (#307)
* `sir_combine()` to combine SIR results of multiple antimicrobials into one variable for combination therapy, using the same rules as `antibiogram()` (#321)
* `sir_combine()` to combine SIR results of multiple antimicrobials into one variable, for combination therapy (`method = "most_susceptible"`) or resistance within a group (`method = "most_resistant"`) (#321)
### Fixed
* `as.mo()` returned *Salmonella bongori* or another subspecies for *Salmonella* serovars written with the species, such as "Salmonella enterica serovar Typhi"
+1 -1
View File
@@ -42,7 +42,7 @@
#' @inheritSection as.sir Interpretation of SIR
#' @details These functions are meant to count isolates. Use the [resistance()]/[susceptibility()] functions to calculate microbial resistance/susceptibility.
#'
#' The function [n_sir()] is an alias of [count_all()]. They can be used to count all available isolates, i.e. where the input antimicrobial has an available result (S, I or R), or for multiple antimicrobials, where the result of the combination is available (see *Combination Therapy* below). Their use is equal to `dplyr`'s `n_distinct()`. Their function is equal to `count_susceptible(...) + count_resistant(...)`.
#' The function [n_sir()] is an alias of [count_all()]. They can be used to count all available isolates, i.e. where the input antimicrobial has an available result (S, I or R). For multiple antimicrobials, these are isolates with a result for any of the antimicrobials, or with `only_all_tested = TRUE`, for all of the antimicrobials (see *Combination Therapy* below). Their use is equal to `dplyr`'s `n_distinct()`. For one antimicrobial, their function is equal to `count_susceptible(...) + count_resistant(...)`.
#'
#' The function [count_df()] takes any variable from `data` that has an [`sir`] class (created with [as.sir()]) and counts the number of S's, I's and R's. It also supports grouped variables. The function [sir_df()] works exactly like [count_df()], but adds the percentage of S, I and R.
#' @inheritSection sir_combine Combination Therapy
+17 -6
View File
@@ -132,20 +132,31 @@ sir_calc <- function(...,
}
if (ncol(x) == 1) {
x <- x[, 1, drop = TRUE]
} else {
# combination therapy: determine the result of the combination for every isolate, see ?sir_combine
x <- sir_combine_engine(as.list(x), S_values = get_susceptible_values(guideline), only_all_tested = only_all_tested)
} else if (isTRUE(only_all_tested)) {
# combination therapy of isolates tested for all antimicrobials, see ?sir_combine
x <- sir_combine_engine(as.list(x), S_values = get_susceptible_values(guideline), only_all_tested = TRUE)
}
} else if (!is.sir(x)) {
x <- as.sir(x)
print_warning <- TRUE
}
if ("SDD" %in% ab_result && "SDD" %in% x && message_not_thrown_before("sir_calc", only_count, ab_result, entire_session = TRUE)) {
if ("SDD" %in% ab_result && "SDD" %in% unlist(lapply(as.list(x), as.character)) && message_not_thrown_before("sir_calc", only_count, ab_result, entire_session = TRUE)) {
message_("Note that {.fun ", ifelse(only_count, "count", "proportion"), "_", ifelse("S" %in% ab_result, "S", ""), "I", ifelse("R" %in% ab_result, "R", ""), "} will also include dose-dependent susceptibility, {.val SDD}. This note will be shown once for this session.", as_note = FALSE)
}
numerator <- sum(x %in% ab_result, na.rm = TRUE)
denominator <- sum(x %in% denominator_vals, na.rm = TRUE)
if (is.data.frame(x)) {
# multiple antimicrobials with only_all_tested = FALSE: an isolate counts if any antimicrobial has a result in `ab_result`, and is considered tested if it has such a result or was tested for all antimicrobials, see ?sir_combine
# this equals sir_combine(method = "most_susceptible") for susceptibility and sir_combine(method = "most_resistant") for resistance
# 'NI' is a missing result
numerator_vals <- intersect(as.character(ab_result), denominator_vals)
is_counted <- Reduce(`|`, lapply(x, function(col) as.character(col) %in% numerator_vals))
is_complete <- Reduce(`&`, lapply(x, function(col) as.character(col) %in% denominator_vals))
numerator <- sum(is_counted)
denominator <- sum(is_counted | is_complete)
} else {
numerator <- sum(x %in% ab_result, na.rm = TRUE)
denominator <- sum(x %in% denominator_vals, na.rm = TRUE)
}
if (print_warning == TRUE) {
if (message_not_thrown_before("sir_calc")) {
+76 -33
View File
@@ -29,38 +29,60 @@
#' Combine SIR Results of Multiple Antimicrobials
#'
#' @description Combine the SIR results of two or more antimicrobials into one SIR result per isolate, e.g. to create a variable for the combination therapy of piperacillin/tazobactam with gentamicin. The result is the best result of the antimicrobials, as a combination therapy covers the isolate if any of its antimicrobials is active. See *Combination Therapy* below for the exact rules.
#' @description Combine the SIR results of two or more antimicrobials into one SIR result per isolate. This can answer two different questions, set with the `method` argument:
#'
#' The same rules are used by [antibiogram()] and [wisca()] for combination antibiograms, and by the [`count_*()`][count()] and [`proportion_*()`][proportion()] functions when more than one variable is used, so the result of [sir_combine()] can be used in any further analysis.
#' * `"most_susceptible"` (default): *Is at least one of these antimicrobials expected to work?* This is the result of a combination therapy, e.g. piperacillin/tazobactam with gentamicin, which covers the isolate if any of its antimicrobials is active.
#' * `"most_resistant"`: *Is resistance demonstrated to any of these antimicrobials?* This is the result for a group of antimicrobials, e.g. resistance to third-generation cephalosporins if an isolate is resistant to ceftazidime or ceftriaxone, as used in surveillance reports.
#'
#' See *Combination Therapy* below for the exact rules. The same rules are used by [antibiogram()] and [wisca()] for combination antibiograms, and by the [`count_*()`][count()] and [`proportion_*()`][proportion()] functions when more than one variable is used.
#' @param ... Two or more vectors (or columns) with antimicrobial interpretations, or a data frame with such columns. They will be transformed internally with [as.sir()] if needed. All vectors must be of the same length.
#' @param only_all_tested A [logical] to indicate that isolates must be tested for all antimicrobials. If `TRUE`, the result is `NA` for isolates with a missing result for any of the antimicrobials. If `FALSE` (default), a missing result only leads to `NA` if a result for the missing antimicrobial could have changed the result of the combination, see *Combination Therapy* below.
#' @param method Either `"most_susceptible"` (default) to return the most susceptible result, as for combination therapy, or `"most_resistant"` to return the most resistant result, as for resistance within a group of antimicrobials. See *Combination Therapy* below.
#' @param only_all_tested A [logical] to indicate that isolates must be tested for all antimicrobials. If `TRUE`, the result is `NA` for isolates with a missing result for any of the antimicrobials. If `FALSE` (default), a missing result only leads to `NA` if a result for the missing antimicrobial could have changed the result, see *Combination Therapy* below.
#' @param guideline Either `"EUCAST"` (default) or `"CLSI"`, to determine whether the 'I' category is considered susceptible. This only affects isolates with a missing result for any of the antimicrobials when `only_all_tested = FALSE`, see *Combination Therapy* below. The default can be changed with the `AMR_guideline` option, see [AMR-options].
#' @section Combination Therapy:
#' A combination of antimicrobials is considered as good as its most active antimicrobial: `"S"` is preferred over `"WT"`, and `"R"` over `"NWT"` and `"NS"`. The value `"NI"` (non-interpretable) is considered a missing result.
#' Results are ordered from susceptible to resistant: S (and WT), SDD, I, R (and NWT, NS). With `method = "most_susceptible"` (in [sir_combine()]), the most susceptible result of the antimicrobials is returned, and with `method = "most_resistant"`, the most resistant result. The value `"NI"` (non-interpretable) is considered a missing result.
#'
#' A missing result can only be ignored if the result of the combination is susceptible regardless of the missing result, which depends on the `only_all_tested` argument and on the guideline: under EUCAST, the 'I' category is considered susceptible (*susceptible, increased exposure*), and under CLSI, it is not.
#' A missing result can only be ignored if it cannot change the conclusion: a susceptible result for `"most_susceptible"`, and a non-susceptible result for `"most_resistant"`. Under EUCAST, the 'I' category is considered susceptible (*susceptible, increased exposure*), and under CLSI, it is not. With `only_all_tested = TRUE`, any missing result leads to `NA`.
#'
#' This is an example for two antimicrobials, Drug A and Drug B (the order of the antimicrobials does not matter):
#' This is an example for two antimicrobials, Drug A and Drug B, under EUCAST (the order of the antimicrobials does not matter):
#'
#' ```
#' -------------------------------------------------------------------------
#' Result of the combination
#' -----------------------------------------------------
#' Drug A Drug B only_all_tested = FALSE only_all_tested = TRUE
#' -------- -------- ---------------------------- ----------------------
#' S S, I, R S S
#' I I, R I I
#' R R R R
#' S <NA> S <NA>
#' I <NA> I (EUCAST), <NA> (CLSI) <NA>
#' R <NA> <NA> <NA>
#' <NA> <NA> <NA> <NA>
#' Result of method = Result of method =
#' "most_susceptible" "most_resistant"
#' ----------------------- -----------------------------
#' only_all_tested = only_all_tested =
#' Drug A Drug B FALSE TRUE FALSE TRUE
#' -------- -------- --------- --------- ----------- -------------
#' S S S S S S
#' S I S S I I
#' S R S S R R
#' I R I I R R
#' R R R R R R
#' S <NA> S <NA> <NA> <NA>
#' I <NA> I <NA> <NA> <NA>
#' R <NA> <NA> <NA> R <NA>
#' <NA> <NA> <NA> <NA> <NA> <NA>
#' -------------------------------------------------------------------------
#' ```
#'
#' The [`count_*()`][count()] and [`proportion_*()`][proportion()] functions, such as [susceptibility()] and [resistance()], apply exactly these rules when more than one variable is used: an isolate is considered tested if the result of the combination is not `NA`, and is then counted by the result of the combination. Consequently, [count_susceptible()] `+` [count_resistant()] `=` [count_all()], and [susceptibility()] `+` [resistance()] `= 1`, for both values of `only_all_tested`. The guideline is taken from their `guideline` argument if they have one, and otherwise from the `AMR_guideline` option.
#' Under CLSI, the combination of I with a missing result is `<NA>` for `"most_susceptible"` and I for `"most_resistant"`.
#'
#' In [antibiogram()] and [wisca()], the 'I' and 'SDD' categories are considered susceptible if `combine_SI = TRUE` (default), and the result of the combination is then reduced to S or R.
#' The [`count_*()`][count()] and [`proportion_*()`][proportion()] functions apply these rules when more than one variable is used. With `only_all_tested = FALSE` (default), the functions for susceptibility, such as [susceptibility()] and [count_susceptible()], count an isolate as susceptible if any of the antimicrobials is susceptible (`"most_susceptible"`), and the functions for resistance, such as [resistance()] and [count_resistant()], count an isolate as resistant if any of the antimicrobials is resistant (`"most_resistant"`). An isolate is considered tested if it has such a result, or if it was tested for all antimicrobials. Therefore, for combinations with `only_all_tested = FALSE`:
#'
#' ```
#' count_S() + count_I() + count_R() >= count_all()
#' proportion_S() + proportion_I() + proportion_R() >= 1
#' ```
#'
#' With `only_all_tested = TRUE`, all these functions count the result of the combination therapy (`"most_susceptible"`) of isolates tested for all antimicrobials, so that:
#'
#' ```
#' count_S() + count_I() + count_R() = count_all()
#' proportion_S() + proportion_I() + proportion_R() = 1
#' ```
#'
#' In [antibiogram()] and [wisca()], the result of the combination therapy (`"most_susceptible"`) is used, the 'I' and 'SDD' categories are considered susceptible if `combine_SI = TRUE` (default), and the result is then reduced to S or R.
#' @return A [`sir`] vector with the same length as the input.
#' @seealso [count()] and [proportion()] for counting and calculating susceptibility of (combinations of) antimicrobials, and [antibiogram()] for combination antibiograms.
#' @export
@@ -68,13 +90,19 @@
#' drug_a <- as.sir(c("S", "R", "R", "I", "I", NA, "R", "SDD"))
#' drug_b <- as.sir(c("R", "S", "R", "R", NA, NA, NA, "I"))
#'
#' # combination therapy: is at least one of them expected to work?
#' sir_combine(drug_a, drug_b)
#' sir_combine(drug_a, drug_b, guideline = "CLSI")
#' sir_combine(drug_a, drug_b, only_all_tested = TRUE)
#'
#' # resistance within a group: is resistance demonstrated to any of them?
#' sir_combine(drug_a, drug_b, method = "most_resistant")
#'
#' # the count and proportion functions use the same rules
#' susceptibility(drug_a, drug_b, minimum = 0)
#' susceptibility(sir_combine(drug_a, drug_b), minimum = 0)
#' resistance(drug_a, drug_b, minimum = 0)
#' resistance(sir_combine(drug_a, drug_b, method = "most_resistant"), minimum = 0)
#'
#' \donttest{
#' if (require("dplyr")) {
@@ -85,6 +113,12 @@
#' select(mo, TZP, GEN, TZP_GEN)
#' }
#' if (require("dplyr")) {
#' # resistance to third-generation cephalosporins
#' example_isolates %>%
#' mutate(cephalosporins_3rd = sir_combine(CAZ, CRO, method = "most_resistant")) %>%
#' count(cephalosporins_3rd)
#' }
#' if (require("dplyr")) {
#' # combine any number of antimicrobials
#' example_isolates %>%
#' mutate(any_aminoglycoside = sir_combine(GEN, TOB, AMK, KAN)) %>%
@@ -105,7 +139,8 @@
#' )
#' }
#' }
sir_combine <- function(..., only_all_tested = FALSE, guideline = getOption("AMR_guideline", "EUCAST")) {
sir_combine <- function(..., method = c("most_susceptible", "most_resistant"), only_all_tested = FALSE, guideline = getOption("AMR_guideline", "EUCAST")) {
method <- match.arg(method)
meet_criteria(only_all_tested, allow_class = "logical", has_length = 1)
meet_criteria(guideline, allow_class = "character", has_length = 1)
if (guideline %like% "EUCAST") {
@@ -129,13 +164,13 @@ sir_combine <- function(..., only_all_tested = FALSE, guideline = getOption("AMR
stop_if(length(unique(col_lengths)) > 1, "all vectors or columns must be of the same length, but they have lengths ", vector_and(sort(unique(col_lengths)), quotes = FALSE), ".")
cols <- lapply(cols, function(x) if (is.sir(x)) x else as.sir(x))
out <- sir_combine_engine(cols, S_values = get_susceptible_values(guideline), only_all_tested = only_all_tested)
out <- sir_combine_engine(cols, S_values = get_susceptible_values(guideline), only_all_tested = only_all_tested, method = method)
if (isFALSE(only_all_tested) && is.null(getOption("AMR_guideline")) && missing(guideline)) {
# only notify about the assumed guideline if it affected the result
any_missing <- Reduce(`|`, lapply(cols, function(x) is.na(x) | as.character(x) == "NI"))
if (any(any_missing & as.character(out) %in% "I") && message_not_thrown_before("sir_combine", "eucast_default", entire_session = TRUE)) {
message_("{.help [{.fun sir_combine}](AMR::sir_combine)} assumes the EUCAST guideline and thus considers the 'I' category susceptible, so a missing result does not change a combination with an 'I' result. Set the {.arg guideline} argument or the {.code AMR_guideline} option to either \"CLSI\" or \"EUCAST\", see {.topic [AMR-options](AMR::AMR-options)}.")
out_clsi <- sir_combine_engine(cols, S_values = get_susceptible_values("CLSI"), only_all_tested = only_all_tested, method = method)
if (!identical(out, out_clsi) && message_not_thrown_before("sir_combine", "eucast_default", entire_session = TRUE)) {
message_("{.help [{.fun sir_combine}](AMR::sir_combine)} assumes the EUCAST guideline and thus considers the 'I' category susceptible, which affected the result for 'I' results combined with a missing result. Set the {.arg guideline} argument or the {.code AMR_guideline} option to either \"CLSI\" or \"EUCAST\", see {.topic [AMR-options](AMR::AMR-options)}.")
message_("This message will be shown once per session.")
}
}
@@ -151,11 +186,12 @@ get_susceptible_values <- function(guideline) {
}
}
sir_combine_engine <- function(cols, S_values, only_all_tested = FALSE) {
# this is the engine for combination therapy, used by sir_combine(), sir_calc() and antibiogram()
sir_combine_engine <- function(cols, S_values, only_all_tested = FALSE, method = "most_susceptible") {
# this is the engine for combining SIR results, used by sir_combine(), sir_calc() and antibiogram()
# - cols: a list of vectors of equal length, with class 'sir' or with SIR values as character
# - S_values: the values considered susceptible, so that a missing result cannot change the result of the combination
# the order of preference: the first value is the best result, values with equal rank are resolved by this order
# - S_values: the values considered susceptible; all other values are considered non-susceptible
# - method: "most_susceptible" (combination therapy) or "most_resistant" (resistance within a group)
# the order of preference: values with equal rank are resolved by this order
preference <- c("S", "WT", "SDD", "I", "R", "NWT", "NS")
ranks <- c(1L, 1L, 2L, 3L, 4L, 4L, 4L)
cols <- lapply(cols, as.character)
@@ -164,18 +200,25 @@ sir_combine_engine <- function(cols, S_values, only_all_tested = FALSE) {
}
# 'NI' and NA get no rank, so they are missing results
col_ranks <- lapply(cols, function(x) ranks[match(x, preference)])
best <- do.call(pmin, c(col_ranks, list(na.rm = TRUE)))
out <- rep(NA_character_, length(best))
if (method == "most_susceptible") {
selected <- do.call(pmin, c(col_ranks, list(na.rm = TRUE)))
# a missing result cannot change a susceptible result
decisive_values <- S_values
} else {
selected <- do.call(pmax, c(col_ranks, list(na.rm = TRUE)))
# a missing result cannot change a non-susceptible result
decisive_values <- setdiff(preference, S_values)
}
out <- rep(NA_character_, length(selected))
for (i in seq_along(preference)) {
is_present <- Reduce(`|`, lapply(cols, function(x) x %in% preference[i]))
out[is.na(out) & best %in% ranks[i] & is_present] <- preference[i]
out[is.na(out) & selected %in% ranks[i] & is_present] <- preference[i]
}
any_missing <- Reduce(`|`, lapply(col_ranks, is.na))
if (isTRUE(only_all_tested)) {
out[any_missing] <- NA_character_
} else {
# a missing result could have been better, unless the combination is already susceptible
out[any_missing & !out %in% S_values] <- NA_character_
out[any_missing & !out %in% decisive_values] <- NA_character_
}
as_sir_structure(out)
}
+8 -4
View File
@@ -170,8 +170,10 @@ example_isolates %>%
#> ℹ Using column mo as input for `mo_fullname()`
#> ℹ Using column mo as input for `mo_is_gram_negative()`
#> ℹ Using column mo as input for `mo_is_intrinsic_resistant()`
#> ℹ Determining intrinsic resistance based on 'EUCAST Expected Resistant Phenotypes' v1.2 (2023). This note will be shown once per session.
#> ℹ For `aminoglycosides()` using columns GEN (gentamicin), TOB (tobramycin), AMK (amikacin), and KAN (kanamycin)
#> ℹ Determining intrinsic resistance based on 'EUCAST Expected Resistant Phenotypes' v1.2 (2023).
#> This note will be shown once per session.
#> ℹ For `aminoglycosides()` using columns GEN (gentamicin), TOB (tobramycin), AMK (amikacin), and KAN
#> (kanamycin)
#> ℹ For `carbapenems()` using columns IPM (imipenem) and MEM (meropenem)
#> # A tibble: 35 × 7
#> bacteria GEN TOB AMK KAN IPM MEM
@@ -364,13 +366,15 @@ out <- example_isolates %>%
# calculate AMR using resistance(), over all aminoglycosides and polymyxins:
summarise(across(c(aminoglycosides(), polymyxins()),
resistance))
#> ℹ For `aminoglycosides()` using columns GEN (gentamicin), TOB (tobramycin), AMK (amikacin), and KAN (kanamycin)
#> ℹ For `aminoglycosides()` using columns GEN (gentamicin), TOB (tobramycin), AMK (amikacin), and KAN
#> (kanamycin)
#> ℹ For `polymyxins()` using column COL (colistin)
#> Warning: There was 1 warning in `summarise()`.
#> ℹ In argument: `across(c(aminoglycosides(), polymyxins()), resistance)`.
#> ℹ In group 3: `ward = "Outpatient"`.
#> Caused by warning:
#> ! Introducing NA: only 23 results available for KAN in group: ward = "Outpatient" (whilst `minimum = 30`).
#> ! Introducing NA: only 23 results available for KAN in group: ward = "Outpatient" (whilst `minimum =
#> 30`).
out
#> # A tibble: 3 × 6
#> ward GEN TOB AMK KAN COL
+32 -16
View File
@@ -271,30 +271,46 @@ For the full mathematical derivation and worked examples, see the \href{https://
\section{Combination Therapy}{
A combination of antimicrobials is considered as good as its most active antimicrobial: \code{"S"} is preferred over \code{"WT"}, and \code{"R"} over \code{"NWT"} and \code{"NS"}. The value \code{"NI"} (non-interpretable) is considered a missing result.
Results are ordered from susceptible to resistant: S (and WT), SDD, I, R (and NWT, NS). With \code{method = "most_susceptible"} (in \code{\link[=sir_combine]{sir_combine()}}), the most susceptible result of the antimicrobials is returned, and with \code{method = "most_resistant"}, the most resistant result. The value \code{"NI"} (non-interpretable) is considered a missing result.
A missing result can only be ignored if the result of the combination is susceptible regardless of the missing result, which depends on the \code{only_all_tested} argument and on the guideline: under EUCAST, the 'I' category is considered susceptible (\emph{susceptible, increased exposure}), and under CLSI, it is not.
A missing result can only be ignored if it cannot change the conclusion: a susceptible result for \code{"most_susceptible"}, and a non-susceptible result for \code{"most_resistant"}. Under EUCAST, the 'I' category is considered susceptible (\emph{susceptible, increased exposure}), and under CLSI, it is not. With \code{only_all_tested = TRUE}, any missing result leads to \code{NA}.
This is an example for two antimicrobials, Drug A and Drug B (the order of the antimicrobials does not matter):
This is an example for two antimicrobials, Drug A and Drug B, under EUCAST (the order of the antimicrobials does not matter):
\if{html}{\out{<div class="sourceCode">}}\preformatted{-------------------------------------------------------------------------
Result of the combination
-----------------------------------------------------
Drug A Drug B only_all_tested = FALSE only_all_tested = TRUE
-------- -------- ---------------------------- ----------------------
S S, I, R S S
I I, R I I
R R R R
S <NA> S <NA>
I <NA> I (EUCAST), <NA> (CLSI) <NA>
R <NA> <NA> <NA>
<NA> <NA> <NA> <NA>
Result of method = Result of method =
"most_susceptible" "most_resistant"
----------------------- -----------------------------
only_all_tested = only_all_tested =
Drug A Drug B FALSE TRUE FALSE TRUE
-------- -------- --------- --------- ----------- -------------
S S S S S S
S I S S I I
S R S S R R
I R I I R R
R R R R R R
S <NA> S <NA> <NA> <NA>
I <NA> I <NA> <NA> <NA>
R <NA> <NA> <NA> R <NA>
<NA> <NA> <NA> <NA> <NA> <NA>
-------------------------------------------------------------------------
}\if{html}{\out{</div>}}
The \code{\link[=count]{count_*()}} and \code{\link[=proportion]{proportion_*()}} functions, such as \code{\link[=susceptibility]{susceptibility()}} and \code{\link[=resistance]{resistance()}}, apply exactly these rules when more than one variable is used: an isolate is considered tested if the result of the combination is not \code{NA}, and is then counted by the result of the combination. Consequently, \code{\link[=count_susceptible]{count_susceptible()}} \code{+} \code{\link[=count_resistant]{count_resistant()}} \code{=} \code{\link[=count_all]{count_all()}}, and \code{\link[=susceptibility]{susceptibility()}} \code{+} \code{\link[=resistance]{resistance()}} \verb{= 1}, for both values of \code{only_all_tested}. The guideline is taken from their \code{guideline} argument if they have one, and otherwise from the \code{AMR_guideline} option.
Under CLSI, the combination of I with a missing result is \verb{<NA>} for \code{"most_susceptible"} and I for \code{"most_resistant"}.
In \code{\link[=antibiogram]{antibiogram()}} and \code{\link[=wisca]{wisca()}}, the 'I' and 'SDD' categories are considered susceptible if \code{combine_SI = TRUE} (default), and the result of the combination is then reduced to S or R.
The \code{\link[=count]{count_*()}} and \code{\link[=proportion]{proportion_*()}} functions apply these rules when more than one variable is used. With \code{only_all_tested = FALSE} (default), the functions for susceptibility, such as \code{\link[=susceptibility]{susceptibility()}} and \code{\link[=count_susceptible]{count_susceptible()}}, count an isolate as susceptible if any of the antimicrobials is susceptible (\code{"most_susceptible"}), and the functions for resistance, such as \code{\link[=resistance]{resistance()}} and \code{\link[=count_resistant]{count_resistant()}}, count an isolate as resistant if any of the antimicrobials is resistant (\code{"most_resistant"}). An isolate is considered tested if it has such a result, or if it was tested for all antimicrobials. Therefore, for combinations with \code{only_all_tested = FALSE}:
\if{html}{\out{<div class="sourceCode">}}\preformatted{ count_S() + count_I() + count_R() >= count_all()
proportion_S() + proportion_I() + proportion_R() >= 1
}\if{html}{\out{</div>}}
With \code{only_all_tested = TRUE}, all these functions count the result of the combination therapy (\code{"most_susceptible"}) of isolates tested for all antimicrobials, so that:
\if{html}{\out{<div class="sourceCode">}}\preformatted{ count_S() + count_I() + count_R() = count_all()
proportion_S() + proportion_I() + proportion_R() = 1
}\if{html}{\out{</div>}}
In \code{\link[=antibiogram]{antibiogram()}} and \code{\link[=wisca]{wisca()}}, the result of the combination therapy (\code{"most_susceptible"}) is used, the 'I' and 'SDD' categories are considered susceptible if \code{combine_SI = TRUE} (default), and the result is then reduced to S or R.
}
\examples{
+33 -17
View File
@@ -79,7 +79,7 @@ These functions can be used to count resistant/susceptible microbial isolates. A
\details{
These functions are meant to count isolates. Use the \code{\link[=resistance]{resistance()}}/\code{\link[=susceptibility]{susceptibility()}} functions to calculate microbial resistance/susceptibility.
The function \code{\link[=n_sir]{n_sir()}} is an alias of \code{\link[=count_all]{count_all()}}. They can be used to count all available isolates, i.e. where the input antimicrobial has an available result (S, I or R), or for multiple antimicrobials, where the result of the combination is available (see \emph{Combination Therapy} below). Their use is equal to \code{dplyr}'s \code{n_distinct()}. Their function is equal to \code{count_susceptible(...) + count_resistant(...)}.
The function \code{\link[=n_sir]{n_sir()}} is an alias of \code{\link[=count_all]{count_all()}}. They can be used to count all available isolates, i.e. where the input antimicrobial has an available result (S, I or R). For multiple antimicrobials, these are isolates with a result for any of the antimicrobials, or with \code{only_all_tested = TRUE}, for all of the antimicrobials (see \emph{Combination Therapy} below). Their use is equal to \code{dplyr}'s \code{n_distinct()}. For one antimicrobial, their function is equal to \code{count_susceptible(...) + count_resistant(...)}.
The function \code{\link[=count_df]{count_df()}} takes any variable from \code{data} that has an \code{\link{sir}} class (created with \code{\link[=as.sir]{as.sir()}}) and counts the number of S's, I's and R's. It also supports grouped variables. The function \code{\link[=sir_df]{sir_df()}} works exactly like \code{\link[=count_df]{count_df()}}, but adds the percentage of S, I and R.
}
@@ -92,30 +92,46 @@ This AMR package follows insight; use \code{\link[=susceptibility]{susceptibilit
\section{Combination Therapy}{
A combination of antimicrobials is considered as good as its most active antimicrobial: \code{"S"} is preferred over \code{"WT"}, and \code{"R"} over \code{"NWT"} and \code{"NS"}. The value \code{"NI"} (non-interpretable) is considered a missing result.
Results are ordered from susceptible to resistant: S (and WT), SDD, I, R (and NWT, NS). With \code{method = "most_susceptible"} (in \code{\link[=sir_combine]{sir_combine()}}), the most susceptible result of the antimicrobials is returned, and with \code{method = "most_resistant"}, the most resistant result. The value \code{"NI"} (non-interpretable) is considered a missing result.
A missing result can only be ignored if the result of the combination is susceptible regardless of the missing result, which depends on the \code{only_all_tested} argument and on the guideline: under EUCAST, the 'I' category is considered susceptible (\emph{susceptible, increased exposure}), and under CLSI, it is not.
A missing result can only be ignored if it cannot change the conclusion: a susceptible result for \code{"most_susceptible"}, and a non-susceptible result for \code{"most_resistant"}. Under EUCAST, the 'I' category is considered susceptible (\emph{susceptible, increased exposure}), and under CLSI, it is not. With \code{only_all_tested = TRUE}, any missing result leads to \code{NA}.
This is an example for two antimicrobials, Drug A and Drug B (the order of the antimicrobials does not matter):
This is an example for two antimicrobials, Drug A and Drug B, under EUCAST (the order of the antimicrobials does not matter):
\if{html}{\out{<div class="sourceCode">}}\preformatted{-------------------------------------------------------------------------
Result of the combination
-----------------------------------------------------
Drug A Drug B only_all_tested = FALSE only_all_tested = TRUE
-------- -------- ---------------------------- ----------------------
S S, I, R S S
I I, R I I
R R R R
S <NA> S <NA>
I <NA> I (EUCAST), <NA> (CLSI) <NA>
R <NA> <NA> <NA>
<NA> <NA> <NA> <NA>
Result of method = Result of method =
"most_susceptible" "most_resistant"
----------------------- -----------------------------
only_all_tested = only_all_tested =
Drug A Drug B FALSE TRUE FALSE TRUE
-------- -------- --------- --------- ----------- -------------
S S S S S S
S I S S I I
S R S S R R
I R I I R R
R R R R R R
S <NA> S <NA> <NA> <NA>
I <NA> I <NA> <NA> <NA>
R <NA> <NA> <NA> R <NA>
<NA> <NA> <NA> <NA> <NA> <NA>
-------------------------------------------------------------------------
}\if{html}{\out{</div>}}
The \code{\link[=count]{count_*()}} and \code{\link[=proportion]{proportion_*()}} functions, such as \code{\link[=susceptibility]{susceptibility()}} and \code{\link[=resistance]{resistance()}}, apply exactly these rules when more than one variable is used: an isolate is considered tested if the result of the combination is not \code{NA}, and is then counted by the result of the combination. Consequently, \code{\link[=count_susceptible]{count_susceptible()}} \code{+} \code{\link[=count_resistant]{count_resistant()}} \code{=} \code{\link[=count_all]{count_all()}}, and \code{\link[=susceptibility]{susceptibility()}} \code{+} \code{\link[=resistance]{resistance()}} \verb{= 1}, for both values of \code{only_all_tested}. The guideline is taken from their \code{guideline} argument if they have one, and otherwise from the \code{AMR_guideline} option.
Under CLSI, the combination of I with a missing result is \verb{<NA>} for \code{"most_susceptible"} and I for \code{"most_resistant"}.
In \code{\link[=antibiogram]{antibiogram()}} and \code{\link[=wisca]{wisca()}}, the 'I' and 'SDD' categories are considered susceptible if \code{combine_SI = TRUE} (default), and the result of the combination is then reduced to S or R.
The \code{\link[=count]{count_*()}} and \code{\link[=proportion]{proportion_*()}} functions apply these rules when more than one variable is used. With \code{only_all_tested = FALSE} (default), the functions for susceptibility, such as \code{\link[=susceptibility]{susceptibility()}} and \code{\link[=count_susceptible]{count_susceptible()}}, count an isolate as susceptible if any of the antimicrobials is susceptible (\code{"most_susceptible"}), and the functions for resistance, such as \code{\link[=resistance]{resistance()}} and \code{\link[=count_resistant]{count_resistant()}}, count an isolate as resistant if any of the antimicrobials is resistant (\code{"most_resistant"}). An isolate is considered tested if it has such a result, or if it was tested for all antimicrobials. Therefore, for combinations with \code{only_all_tested = FALSE}:
\if{html}{\out{<div class="sourceCode">}}\preformatted{ count_S() + count_I() + count_R() >= count_all()
proportion_S() + proportion_I() + proportion_R() >= 1
}\if{html}{\out{</div>}}
With \code{only_all_tested = TRUE}, all these functions count the result of the combination therapy (\code{"most_susceptible"}) of isolates tested for all antimicrobials, so that:
\if{html}{\out{<div class="sourceCode">}}\preformatted{ count_S() + count_I() + count_R() = count_all()
proportion_S() + proportion_I() + proportion_R() = 1
}\if{html}{\out{</div>}}
In \code{\link[=antibiogram]{antibiogram()}} and \code{\link[=wisca]{wisca()}}, the result of the combination therapy (\code{"most_susceptible"}) is used, the 'I' and 'SDD' categories are considered susceptible if \code{combine_SI = TRUE} (default), and the result is then reduced to S or R.
}
\examples{
+32 -16
View File
@@ -135,30 +135,46 @@ This AMR package follows insight; use \code{\link[=susceptibility]{susceptibilit
\section{Combination Therapy}{
A combination of antimicrobials is considered as good as its most active antimicrobial: \code{"S"} is preferred over \code{"WT"}, and \code{"R"} over \code{"NWT"} and \code{"NS"}. The value \code{"NI"} (non-interpretable) is considered a missing result.
Results are ordered from susceptible to resistant: S (and WT), SDD, I, R (and NWT, NS). With \code{method = "most_susceptible"} (in \code{\link[=sir_combine]{sir_combine()}}), the most susceptible result of the antimicrobials is returned, and with \code{method = "most_resistant"}, the most resistant result. The value \code{"NI"} (non-interpretable) is considered a missing result.
A missing result can only be ignored if the result of the combination is susceptible regardless of the missing result, which depends on the \code{only_all_tested} argument and on the guideline: under EUCAST, the 'I' category is considered susceptible (\emph{susceptible, increased exposure}), and under CLSI, it is not.
A missing result can only be ignored if it cannot change the conclusion: a susceptible result for \code{"most_susceptible"}, and a non-susceptible result for \code{"most_resistant"}. Under EUCAST, the 'I' category is considered susceptible (\emph{susceptible, increased exposure}), and under CLSI, it is not. With \code{only_all_tested = TRUE}, any missing result leads to \code{NA}.
This is an example for two antimicrobials, Drug A and Drug B (the order of the antimicrobials does not matter):
This is an example for two antimicrobials, Drug A and Drug B, under EUCAST (the order of the antimicrobials does not matter):
\if{html}{\out{<div class="sourceCode">}}\preformatted{-------------------------------------------------------------------------
Result of the combination
-----------------------------------------------------
Drug A Drug B only_all_tested = FALSE only_all_tested = TRUE
-------- -------- ---------------------------- ----------------------
S S, I, R S S
I I, R I I
R R R R
S <NA> S <NA>
I <NA> I (EUCAST), <NA> (CLSI) <NA>
R <NA> <NA> <NA>
<NA> <NA> <NA> <NA>
Result of method = Result of method =
"most_susceptible" "most_resistant"
----------------------- -----------------------------
only_all_tested = only_all_tested =
Drug A Drug B FALSE TRUE FALSE TRUE
-------- -------- --------- --------- ----------- -------------
S S S S S S
S I S S I I
S R S S R R
I R I I R R
R R R R R R
S <NA> S <NA> <NA> <NA>
I <NA> I <NA> <NA> <NA>
R <NA> <NA> <NA> R <NA>
<NA> <NA> <NA> <NA> <NA> <NA>
-------------------------------------------------------------------------
}\if{html}{\out{</div>}}
The \code{\link[=count]{count_*()}} and \code{\link[=proportion]{proportion_*()}} functions, such as \code{\link[=susceptibility]{susceptibility()}} and \code{\link[=resistance]{resistance()}}, apply exactly these rules when more than one variable is used: an isolate is considered tested if the result of the combination is not \code{NA}, and is then counted by the result of the combination. Consequently, \code{\link[=count_susceptible]{count_susceptible()}} \code{+} \code{\link[=count_resistant]{count_resistant()}} \code{=} \code{\link[=count_all]{count_all()}}, and \code{\link[=susceptibility]{susceptibility()}} \code{+} \code{\link[=resistance]{resistance()}} \verb{= 1}, for both values of \code{only_all_tested}. The guideline is taken from their \code{guideline} argument if they have one, and otherwise from the \code{AMR_guideline} option.
Under CLSI, the combination of I with a missing result is \verb{<NA>} for \code{"most_susceptible"} and I for \code{"most_resistant"}.
In \code{\link[=antibiogram]{antibiogram()}} and \code{\link[=wisca]{wisca()}}, the 'I' and 'SDD' categories are considered susceptible if \code{combine_SI = TRUE} (default), and the result of the combination is then reduced to S or R.
The \code{\link[=count]{count_*()}} and \code{\link[=proportion]{proportion_*()}} functions apply these rules when more than one variable is used. With \code{only_all_tested = FALSE} (default), the functions for susceptibility, such as \code{\link[=susceptibility]{susceptibility()}} and \code{\link[=count_susceptible]{count_susceptible()}}, count an isolate as susceptible if any of the antimicrobials is susceptible (\code{"most_susceptible"}), and the functions for resistance, such as \code{\link[=resistance]{resistance()}} and \code{\link[=count_resistant]{count_resistant()}}, count an isolate as resistant if any of the antimicrobials is resistant (\code{"most_resistant"}). An isolate is considered tested if it has such a result, or if it was tested for all antimicrobials. Therefore, for combinations with \code{only_all_tested = FALSE}:
\if{html}{\out{<div class="sourceCode">}}\preformatted{ count_S() + count_I() + count_R() >= count_all()
proportion_S() + proportion_I() + proportion_R() >= 1
}\if{html}{\out{</div>}}
With \code{only_all_tested = TRUE}, all these functions count the result of the combination therapy (\code{"most_susceptible"}) of isolates tested for all antimicrobials, so that:
\if{html}{\out{<div class="sourceCode">}}\preformatted{ count_S() + count_I() + count_R() = count_all()
proportion_S() + proportion_I() + proportion_R() = 1
}\if{html}{\out{</div>}}
In \code{\link[=antibiogram]{antibiogram()}} and \code{\link[=wisca]{wisca()}}, the result of the combination therapy (\code{"most_susceptible"}) is used, the 'I' and 'SDD' categories are considered susceptible if \code{combine_SI = TRUE} (default), and the result is then reduced to S or R.
}
\examples{
+54 -19
View File
@@ -6,6 +6,7 @@
\usage{
sir_combine(
...,
method = c("most_susceptible", "most_resistant"),
only_all_tested = FALSE,
guideline = getOption("AMR_guideline", "EUCAST")
)
@@ -13,7 +14,9 @@ sir_combine(
\arguments{
\item{...}{Two or more vectors (or columns) with antimicrobial interpretations, or a data frame with such columns. They will be transformed internally with \code{\link[=as.sir]{as.sir()}} if needed. All vectors must be of the same length.}
\item{only_all_tested}{A \link{logical} to indicate that isolates must be tested for all antimicrobials. If \code{TRUE}, the result is \code{NA} for isolates with a missing result for any of the antimicrobials. If \code{FALSE} (default), a missing result only leads to \code{NA} if a result for the missing antimicrobial could have changed the result of the combination, see \emph{Combination Therapy} below.}
\item{method}{Either \code{"most_susceptible"} (default) to return the most susceptible result, as for combination therapy, or \code{"most_resistant"} to return the most resistant result, as for resistance within a group of antimicrobials. See \emph{Combination Therapy} below.}
\item{only_all_tested}{A \link{logical} to indicate that isolates must be tested for all antimicrobials. If \code{TRUE}, the result is \code{NA} for isolates with a missing result for any of the antimicrobials. If \code{FALSE} (default), a missing result only leads to \code{NA} if a result for the missing antimicrobial could have changed the result, see \emph{Combination Therapy} below.}
\item{guideline}{Either \code{"EUCAST"} (default) or \code{"CLSI"}, to determine whether the 'I' category is considered susceptible. This only affects isolates with a missing result for any of the antimicrobials when \code{only_all_tested = FALSE}, see \emph{Combination Therapy} below. The default can be changed with the \code{AMR_guideline} option, see \link{AMR-options}.}
}
@@ -21,49 +24,75 @@ sir_combine(
A \code{\link{sir}} vector with the same length as the input.
}
\description{
Combine the SIR results of two or more antimicrobials into one SIR result per isolate, e.g. to create a variable for the combination therapy of piperacillin/tazobactam with gentamicin. The result is the best result of the antimicrobials, as a combination therapy covers the isolate if any of its antimicrobials is active. See \emph{Combination Therapy} below for the exact rules.
Combine the SIR results of two or more antimicrobials into one SIR result per isolate. This can answer two different questions, set with the \code{method} argument:
\itemize{
\item \code{"most_susceptible"} (default): \emph{Is at least one of these antimicrobials expected to work?} This is the result of a combination therapy, e.g. piperacillin/tazobactam with gentamicin, which covers the isolate if any of its antimicrobials is active.
\item \code{"most_resistant"}: \emph{Is resistance demonstrated to any of these antimicrobials?} This is the result for a group of antimicrobials, e.g. resistance to third-generation cephalosporins if an isolate is resistant to ceftazidime or ceftriaxone, as used in surveillance reports.
}
The same rules are used by \code{\link[=antibiogram]{antibiogram()}} and \code{\link[=wisca]{wisca()}} for combination antibiograms, and by the \code{\link[=count]{count_*()}} and \code{\link[=proportion]{proportion_*()}} functions when more than one variable is used, so the result of \code{\link[=sir_combine]{sir_combine()}} can be used in any further analysis.
See \emph{Combination Therapy} below for the exact rules. The same rules are used by \code{\link[=antibiogram]{antibiogram()}} and \code{\link[=wisca]{wisca()}} for combination antibiograms, and by the \code{\link[=count]{count_*()}} and \code{\link[=proportion]{proportion_*()}} functions when more than one variable is used.
}
\section{Combination Therapy}{
A combination of antimicrobials is considered as good as its most active antimicrobial: \code{"S"} is preferred over \code{"WT"}, and \code{"R"} over \code{"NWT"} and \code{"NS"}. The value \code{"NI"} (non-interpretable) is considered a missing result.
Results are ordered from susceptible to resistant: S (and WT), SDD, I, R (and NWT, NS). With \code{method = "most_susceptible"} (in \code{\link[=sir_combine]{sir_combine()}}), the most susceptible result of the antimicrobials is returned, and with \code{method = "most_resistant"}, the most resistant result. The value \code{"NI"} (non-interpretable) is considered a missing result.
A missing result can only be ignored if the result of the combination is susceptible regardless of the missing result, which depends on the \code{only_all_tested} argument and on the guideline: under EUCAST, the 'I' category is considered susceptible (\emph{susceptible, increased exposure}), and under CLSI, it is not.
A missing result can only be ignored if it cannot change the conclusion: a susceptible result for \code{"most_susceptible"}, and a non-susceptible result for \code{"most_resistant"}. Under EUCAST, the 'I' category is considered susceptible (\emph{susceptible, increased exposure}), and under CLSI, it is not. With \code{only_all_tested = TRUE}, any missing result leads to \code{NA}.
This is an example for two antimicrobials, Drug A and Drug B (the order of the antimicrobials does not matter):
This is an example for two antimicrobials, Drug A and Drug B, under EUCAST (the order of the antimicrobials does not matter):
\if{html}{\out{<div class="sourceCode">}}\preformatted{-------------------------------------------------------------------------
Result of the combination
-----------------------------------------------------
Drug A Drug B only_all_tested = FALSE only_all_tested = TRUE
-------- -------- ---------------------------- ----------------------
S S, I, R S S
I I, R I I
R R R R
S <NA> S <NA>
I <NA> I (EUCAST), <NA> (CLSI) <NA>
R <NA> <NA> <NA>
<NA> <NA> <NA> <NA>
Result of method = Result of method =
"most_susceptible" "most_resistant"
----------------------- -----------------------------
only_all_tested = only_all_tested =
Drug A Drug B FALSE TRUE FALSE TRUE
-------- -------- --------- --------- ----------- -------------
S S S S S S
S I S S I I
S R S S R R
I R I I R R
R R R R R R
S <NA> S <NA> <NA> <NA>
I <NA> I <NA> <NA> <NA>
R <NA> <NA> <NA> R <NA>
<NA> <NA> <NA> <NA> <NA> <NA>
-------------------------------------------------------------------------
}\if{html}{\out{</div>}}
The \code{\link[=count]{count_*()}} and \code{\link[=proportion]{proportion_*()}} functions, such as \code{\link[=susceptibility]{susceptibility()}} and \code{\link[=resistance]{resistance()}}, apply exactly these rules when more than one variable is used: an isolate is considered tested if the result of the combination is not \code{NA}, and is then counted by the result of the combination. Consequently, \code{\link[=count_susceptible]{count_susceptible()}} \code{+} \code{\link[=count_resistant]{count_resistant()}} \code{=} \code{\link[=count_all]{count_all()}}, and \code{\link[=susceptibility]{susceptibility()}} \code{+} \code{\link[=resistance]{resistance()}} \verb{= 1}, for both values of \code{only_all_tested}. The guideline is taken from their \code{guideline} argument if they have one, and otherwise from the \code{AMR_guideline} option.
Under CLSI, the combination of I with a missing result is \verb{<NA>} for \code{"most_susceptible"} and I for \code{"most_resistant"}.
In \code{\link[=antibiogram]{antibiogram()}} and \code{\link[=wisca]{wisca()}}, the 'I' and 'SDD' categories are considered susceptible if \code{combine_SI = TRUE} (default), and the result of the combination is then reduced to S or R.
The \code{\link[=count]{count_*()}} and \code{\link[=proportion]{proportion_*()}} functions apply these rules when more than one variable is used. With \code{only_all_tested = FALSE} (default), the functions for susceptibility, such as \code{\link[=susceptibility]{susceptibility()}} and \code{\link[=count_susceptible]{count_susceptible()}}, count an isolate as susceptible if any of the antimicrobials is susceptible (\code{"most_susceptible"}), and the functions for resistance, such as \code{\link[=resistance]{resistance()}} and \code{\link[=count_resistant]{count_resistant()}}, count an isolate as resistant if any of the antimicrobials is resistant (\code{"most_resistant"}). An isolate is considered tested if it has such a result, or if it was tested for all antimicrobials. Therefore, for combinations with \code{only_all_tested = FALSE}:
\if{html}{\out{<div class="sourceCode">}}\preformatted{ count_S() + count_I() + count_R() >= count_all()
proportion_S() + proportion_I() + proportion_R() >= 1
}\if{html}{\out{</div>}}
With \code{only_all_tested = TRUE}, all these functions count the result of the combination therapy (\code{"most_susceptible"}) of isolates tested for all antimicrobials, so that:
\if{html}{\out{<div class="sourceCode">}}\preformatted{ count_S() + count_I() + count_R() = count_all()
proportion_S() + proportion_I() + proportion_R() = 1
}\if{html}{\out{</div>}}
In \code{\link[=antibiogram]{antibiogram()}} and \code{\link[=wisca]{wisca()}}, the result of the combination therapy (\code{"most_susceptible"}) is used, the 'I' and 'SDD' categories are considered susceptible if \code{combine_SI = TRUE} (default), and the result is then reduced to S or R.
}
\examples{
drug_a <- as.sir(c("S", "R", "R", "I", "I", NA, "R", "SDD"))
drug_b <- as.sir(c("R", "S", "R", "R", NA, NA, NA, "I"))
# combination therapy: is at least one of them expected to work?
sir_combine(drug_a, drug_b)
sir_combine(drug_a, drug_b, guideline = "CLSI")
sir_combine(drug_a, drug_b, only_all_tested = TRUE)
# resistance within a group: is resistance demonstrated to any of them?
sir_combine(drug_a, drug_b, method = "most_resistant")
# the count and proportion functions use the same rules
susceptibility(drug_a, drug_b, minimum = 0)
susceptibility(sir_combine(drug_a, drug_b), minimum = 0)
resistance(drug_a, drug_b, minimum = 0)
resistance(sir_combine(drug_a, drug_b, method = "most_resistant"), minimum = 0)
\donttest{
if (require("dplyr")) {
@@ -73,6 +102,12 @@ if (require("dplyr")) {
mutate(TZP_GEN = sir_combine(TZP, GEN)) \%>\%
select(mo, TZP, GEN, TZP_GEN)
}
if (require("dplyr")) {
# resistance to third-generation cephalosporins
example_isolates \%>\%
mutate(cephalosporins_3rd = sir_combine(CAZ, CRO, method = "most_resistant")) \%>\%
count(cephalosporins_3rd)
}
if (require("dplyr")) {
# combine any number of antimicrobials
example_isolates \%>\%
+1 -6
View File
@@ -68,17 +68,12 @@ test_that("test-count.R", {
expect_equal(example_isolates %>% count_susceptible(AMC, GEN, only_all_tested = TRUE), 1687)
expect_equal(example_isolates %>% count_susceptible(AMC, GEN, only_all_tested = FALSE), 1764)
expect_equal(example_isolates %>% count_all(AMC, GEN, only_all_tested = TRUE), 1798)
expect_equal(example_isolates %>% count_all(AMC, GEN, only_all_tested = FALSE), 1875)
expect_equal(example_isolates %>% count_all(AMC, GEN, only_all_tested = FALSE), 1936)
expect_identical(
example_isolates %>% count_all(AMC, GEN, only_all_tested = TRUE),
example_isolates %>% count_susceptible(AMC, GEN, only_all_tested = TRUE) +
example_isolates %>% count_resistant(AMC, GEN, only_all_tested = TRUE)
)
expect_identical(
example_isolates %>% count_all(AMC, GEN, only_all_tested = FALSE),
example_isolates %>% count_susceptible(AMC, GEN, only_all_tested = FALSE) +
example_isolates %>% count_resistant(AMC, GEN, only_all_tested = FALSE)
)
# count of cases
expect_equal(
+1 -1
View File
@@ -95,7 +95,7 @@ test_that("test-proportion.R", {
combination_n = n_sir(CIP, GEN)
) %>%
pull(combination_n),
c(979, 462, 101)
c(1181, 577, 116)
)
# proportion_df
+64 -18
View File
@@ -69,6 +69,36 @@ test_that("test-sir_combine.R", {
expect_identical(sir_combine(a, b, guideline = "CLSI"), sir_combine(b, a, guideline = "CLSI"))
}
# most resistant result of two non-missing values, written by hand
worst <- matrix(
c(
"S", "SDD", "I", "R", "S", "NWT", "NS",
"SDD", "SDD", "I", "R", "SDD", "NWT", "NS",
"I", "I", "I", "R", "I", "NWT", "NS",
"R", "R", "R", "R", "R", "R", "R",
"S", "SDD", "I", "R", "WT", "NWT", "NS",
"NWT", "NWT", "NWT", "R", "NWT", "NWT", "NWT",
"NS", "NS", "NS", "R", "NS", "NWT", "NS"
),
nrow = 7, byrow = TRUE, dimnames = list(vals, vals)
)
expect_identical(worst, t(worst))
worst_missing_eucast <- c(S = NA, SDD = NA, I = NA, R = "R", WT = NA, NWT = "NWT", NS = "NS")
worst_missing_clsi <- c(S = NA, SDD = NA, I = "I", R = "R", WT = NA, NWT = "NWT", NS = "NS")
for (missing_val in c(NA, "NI")) {
a <- c(rep(vals, each = length(vals)), vals, rep(missing_val, length(vals)), missing_val)
b <- c(rep(vals, times = length(vals)), rep(missing_val, length(vals)), vals, missing_val)
expected_complete <- worst[cbind(rep(vals, each = length(vals)), rep(vals, times = length(vals)))]
a <- as.sir(a)
b <- as.sir(b)
expect_identical(sir_combine(a, b, method = "most_resistant", guideline = "EUCAST"), as.sir(unname(c(expected_complete, worst_missing_eucast[vals], worst_missing_eucast[vals], NA))))
expect_identical(sir_combine(a, b, method = "most_resistant", guideline = "CLSI"), as.sir(unname(c(expected_complete, worst_missing_clsi[vals], worst_missing_clsi[vals], NA))))
expect_identical(sir_combine(a, b, method = "most_resistant", only_all_tested = TRUE), as.sir(unname(c(expected_complete, rep(NA, 2 * length(vals) + 1)))))
expect_identical(sir_combine(a, b, method = "most_resistant"), sir_combine(b, a, method = "most_resistant"))
}
expect_identical(sir_combine(as.sir("S"), as.sir("R"), method = "most_r"), as.sir("R"))
expect_error(sir_combine(as.sir("S"), as.sir("R"), method = "worst"))
# three or more antimicrobials
x1 <- as.sir(c("R", "R", "R", NA, "I", "R", "NI"))
x2 <- as.sir(c("R", "I", "R", "R", "R", NA, "R"))
@@ -101,25 +131,41 @@ test_that("test-sir_combine.R", {
r1 <- random_sir_values()
r2 <- random_sir_values()
r3 <- random_sir_values()
for (oat in c(FALSE, TRUE)) {
for (gl in c("EUCAST", "CLSI")) {
combined <- sir_combine(r1, r2, r3, only_all_tested = oat, guideline = gl)
expect_identical(count_all(r1, r2, r3, only_all_tested = oat), sum(!is.na(sir_combine(r1, r2, r3, only_all_tested = oat, guideline = "EUCAST"))))
expect_identical(count_susceptible(r1, r2, r3, only_all_tested = oat, guideline = gl), count_susceptible(combined, guideline = gl))
expect_identical(count_resistant(r1, r2, r3, only_all_tested = oat, guideline = gl), count_resistant(combined, guideline = gl))
expect_equal(susceptibility(r1, r2, r3, only_all_tested = oat, guideline = gl, minimum = 0), susceptibility(combined, guideline = gl, minimum = 0))
expect_equal(resistance(r1, r2, r3, only_all_tested = oat, guideline = gl, minimum = 0), resistance(combined, guideline = gl, minimum = 0))
expect_equal(susceptibility(r1, r2, r3, only_all_tested = oat, guideline = gl, minimum = 0) + resistance(r1, r2, r3, only_all_tested = oat, guideline = gl, minimum = 0), 1)
expect_identical(count_susceptible(combined, guideline = gl) + count_resistant(combined, guideline = gl), sum(!is.na(combined)))
}
combined <- sir_combine(r1, r2, only_all_tested = oat, guideline = "EUCAST")
expect_identical(count_SI(r1, r2, only_all_tested = oat) + count_R(r1, r2, only_all_tested = oat), count_all(r1, r2, only_all_tested = oat))
expect_identical(count_S(r1, r2, only_all_tested = oat), sum(combined %in% "S"))
expect_identical(count_I(r1, r2, only_all_tested = oat), sum(combined %in% c("I", "SDD")))
expect_identical(count_all(r1, r2, only_all_tested = oat), sum(!is.na(combined)))
expect_identical(count_R(r1, r2, only_all_tested = oat), sum(combined %in% c("R", "NWT", "NS")))
expect_equal(proportion_SI(r1, r2, only_all_tested = oat, minimum = 0) + proportion_R(r1, r2, only_all_tested = oat, minimum = 0), 1)
for (gl in c("EUCAST", "CLSI")) {
# only_all_tested = FALSE: susceptibility follows "most_susceptible" and resistance follows "most_resistant", as in AMR 3.0.1
most_s <- sir_combine(r1, r2, r3, guideline = gl)
most_r <- sir_combine(r1, r2, r3, method = "most_resistant", guideline = gl)
expect_identical(count_susceptible(r1, r2, r3, guideline = gl), count_susceptible(most_s, guideline = gl))
expect_identical(count_resistant(r1, r2, r3, guideline = gl), count_resistant(most_r, guideline = gl))
expect_equal(susceptibility(r1, r2, r3, guideline = gl, minimum = 0), susceptibility(most_s, guideline = gl, minimum = 0))
expect_equal(resistance(r1, r2, r3, guideline = gl, minimum = 0), resistance(most_r, guideline = gl, minimum = 0))
expect_true(susceptibility(r1, r2, r3, guideline = gl, minimum = 0) + resistance(r1, r2, r3, guideline = gl, minimum = 0) >= 1)
# only_all_tested = TRUE: all functions follow "most_susceptible" of isolates tested for all antimicrobials
combined <- sir_combine(r1, r2, r3, only_all_tested = TRUE, guideline = gl)
expect_identical(count_all(r1, r2, r3, only_all_tested = TRUE), sum(!is.na(combined)))
expect_identical(count_susceptible(r1, r2, r3, only_all_tested = TRUE, guideline = gl), count_susceptible(combined, guideline = gl))
expect_identical(count_resistant(r1, r2, r3, only_all_tested = TRUE, guideline = gl), count_resistant(combined, guideline = gl))
expect_equal(susceptibility(r1, r2, r3, only_all_tested = TRUE, guideline = gl, minimum = 0) + resistance(r1, r2, r3, only_all_tested = TRUE, guideline = gl, minimum = 0), 1)
}
# count_all() with only_all_tested = FALSE counts isolates with any result, 'NI' is a missing result
is_tested <- function(x) !is.na(x) & x != "NI"
expect_identical(count_all(r1, r2, r3), sum(is_tested(r1) | is_tested(r2) | is_tested(r3)))
combined <- sir_combine(r1, r2, only_all_tested = TRUE)
expect_identical(count_S(r1, r2, only_all_tested = TRUE), sum(combined %in% "S"))
expect_identical(count_I(r1, r2, only_all_tested = TRUE), sum(combined %in% c("I", "SDD")))
expect_identical(count_R(r1, r2, only_all_tested = TRUE), sum(combined %in% c("R", "NWT", "NS")))
expect_identical(count_SI(r1, r2, only_all_tested = TRUE) + count_R(r1, r2, only_all_tested = TRUE), count_all(r1, r2, only_all_tested = TRUE))
# behaviour of AMR 3.0.1 for all nine combinations of S, R and NA
a <- as.sir(c("S", "R", NA, "S", "R", NA, "S", "R", NA))
b <- as.sir(c("S", "S", "S", "R", "R", "R", NA, NA, NA))
expect_identical(count_all(a, b), 8L)
expect_identical(count_susceptible(a, b), 5L)
expect_identical(count_resistant(a, b), 5L)
expect_equal(susceptibility(a, b, minimum = 0), 5 / 6)
expect_equal(resistance(a, b, minimum = 0), 5 / 6)
expect_identical(count_all(a, b, only_all_tested = TRUE), 4L)
expect_identical(count_susceptible(a, b, only_all_tested = TRUE), 3L)
expect_identical(count_resistant(a, b, only_all_tested = TRUE), 1L)
# antibiogram() gives the same result as the frozen implementation from before sir_combine() existed
old_combination <- function(df, S_values, only_all_tested) {