# Calculate Antimicrobial Resistance
These functions can be used to calculate the (co-)resistance or
susceptibility of microbial isolates (i.e. percentage of S, SI, I, IR or
R). All functions support quasiquotation with pipes, can be used in
[`summarise()`](https://dplyr.tidyverse.org/reference/summarise.html)
from the `dplyr` package and also support grouped variables, see
*Examples*.
`resistance()` should be used to calculate resistance,
`susceptibility()` should be used to calculate susceptibility.
## Usage
``` r
resistance(..., minimum = 30, as_percent = FALSE,
only_all_tested = FALSE)
susceptibility(..., minimum = 30, as_percent = FALSE,
only_all_tested = FALSE)
sir_confidence_interval(..., ab_result = "R", minimum = 30,
as_percent = FALSE, only_all_tested = FALSE, confidence_level = 0.95,
side = "both", collapse = FALSE)
proportion_R(..., minimum = 30, as_percent = FALSE,
only_all_tested = FALSE)
proportion_IR(..., minimum = 30, as_percent = FALSE,
only_all_tested = FALSE)
proportion_I(..., minimum = 30, as_percent = FALSE,
only_all_tested = FALSE)
proportion_SI(..., minimum = 30, as_percent = FALSE,
only_all_tested = FALSE)
proportion_S(..., minimum = 30, as_percent = FALSE,
only_all_tested = FALSE)
proportion_df(data, translate_ab = "name", language = get_AMR_locale(),
minimum = 30, as_percent = FALSE, combine_SI = TRUE,
confidence_level = 0.95)
sir_df(data, translate_ab = "name", language = get_AMR_locale(),
minimum = 30, as_percent = FALSE, combine_SI = TRUE,
confidence_level = 0.95)
```
## Source
**M39 Analysis and Presentation of Cumulative Antimicrobial
Susceptibility Test Data, 5th Edition**, 2022, *Clinical and Laboratory
Standards Institute (CLSI)*.
.
## Arguments
- ...:
One or more vectors (or columns) with antibiotic interpretations. They
will be transformed internally with
[`as.sir()`](https://amr-for-r.org/reference/as.sir.md) if needed. Use
multiple columns to calculate (the lack of) co-resistance: the
probability where one of two drugs have a resistant or susceptible
result. See *Examples*.
- minimum:
The minimum allowed number of available (tested) isolates. Any isolate
count lower than `minimum` will return `NA` with a warning. The
default number of `30` isolates is advised by the Clinical and
Laboratory Standards Institute (CLSI) as best practice, see *Source*.
- as_percent:
A [logical](https://rdrr.io/r/base/logical.html) to indicate whether
the output must be returned as a hundred fold with % sign (a
character). A value of `0.123456` will then be returned as `"12.3%"`.
- only_all_tested:
(for combination therapies, i.e. using more than one variable for
`...`): a [logical](https://rdrr.io/r/base/logical.html) to indicate
that isolates must be tested for all antimicrobials, see section
*Combination Therapy* below.
- ab_result:
Antibiotic results to test against, must be one or more values of "S",
"SDD", "I", or "R".
- confidence_level:
The confidence level for the returned confidence interval. For the
calculation, the number of S or SI isolates, and R isolates are
compared with the total number of available isolates with R, S, or I
by using [`binom.test()`](https://rdrr.io/r/stats/binom.test.html),
i.e., the Clopper-Pearson method.
- side:
The side of the confidence interval to return. The default is `"both"`
for a length 2 vector, but can also be (abbreviated as)
`"min"`/`"left"`/`"lower"`/`"less"` or
`"max"`/`"right"`/`"higher"`/`"greater"`.
- collapse:
A [logical](https://rdrr.io/r/base/logical.html) to indicate whether
the output values should be 'collapsed', i.e. be merged together into
one value, or a character value to use for collapsing.
- data:
A [data.frame](https://rdrr.io/r/base/data.frame.html) containing
columns with class [`sir`](https://amr-for-r.org/reference/as.sir.md)
(see [`as.sir()`](https://amr-for-r.org/reference/as.sir.md)).
- translate_ab:
A column name of the
[antimicrobials](https://amr-for-r.org/reference/antimicrobials.md)
data set to translate the antibiotic abbreviations to, using
[`ab_property()`](https://amr-for-r.org/reference/ab_property.md).
- language:
Language of the returned text - the default is the current system
language (see
[`get_AMR_locale()`](https://amr-for-r.org/reference/translate.md))
and can also be set with the package option
[`AMR_locale`](https://amr-for-r.org/reference/AMR-options.md). Use
`language = NULL` or `language = ""` to prevent translation.
- combine_SI:
A [logical](https://rdrr.io/r/base/logical.html) to indicate whether
all values of S, SDD, and I must be merged into one, so the output
only consists of S+SDD+I vs. R (susceptible vs. resistant) - the
default is `TRUE`.
## Value
A [double](https://rdrr.io/r/base/double.html) or, when
`as_percent = TRUE`, a
[character](https://rdrr.io/r/base/character.html).
## Details
For a more automated and comprehensive analysis, consider using
[`antibiogram()`](https://amr-for-r.org/reference/antibiogram.md) or
[`wisca()`](https://amr-for-r.org/reference/antibiogram.md), which
streamline many aspects of susceptibility reporting and, importantly,
also support WISCA. The functions described here offer a more hands-on,
manual approach for greater customisation.
**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()`](https://amr-for-r.org/reference/first_isolate.md) to
determine them in your data set with one of the four available
algorithms.
The function `resistance()` is equal to the function `proportion_R()`.
The function `susceptibility()` is equal to the function
`proportion_SI()`. Since AMR v3.0, `proportion_SI()` and
`proportion_I()` include dose-dependent susceptibility ('SDD').
Use `sir_confidence_interval()` to calculate the confidence interval,
which relies on
[`binom.test()`](https://rdrr.io/r/stats/binom.test.html), i.e., the
Clopper-Pearson method. This function returns a vector of length 2 at
default for antimicrobial *resistance*. Change the `side` argument to
"left"/"min" or "right"/"max" to return a single value, and change the
`ab_result` argument to e.g. `c("S", "I")` to test for antimicrobial
*susceptibility*, see Examples.
These functions are not meant to count isolates, but to calculate the
proportion of resistance/susceptibility. Use the
[`count_*()`](https://amr-for-r.org/reference/count.md) functions to
count isolates. The function `susceptibility()` is essentially equal to
[`count_susceptible()`](https://amr-for-r.org/reference/count.md)`/`[`count_all()`](https://amr-for-r.org/reference/count.md).
*Low counts can influence the outcome - the `proportion_*()` functions
may camouflage this, since they only return the proportion (albeit
dependent on the `minimum` argument).*
The function `proportion_df()` takes any variable from `data` that has
an [`sir`](https://amr-for-r.org/reference/as.sir.md) class (created
with [`as.sir()`](https://amr-for-r.org/reference/as.sir.md)) and
calculates the proportions S, I, and R. It also supports grouped
variables. The function `sir_df()` works exactly like `proportion_df()`,
but adds the number of isolates.
## Combination Therapy
When using more than one variable for `...` (= combination therapy), use
`only_all_tested` to only count isolates that are tested for all
antimicrobials/variables that you test them for. See this example for
two antimicrobials, Drug A and Drug B, about how `susceptibility()`
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
S or I X X - -
S or I R X X X X
R R - X - X
R - - - -
S or I X X - -
R - - - -
- - - -
--------------------------------------------------------------------
Please note that, in combination therapies, for `only_all_tested = TRUE`
applies that:
count_S() + count_I() + count_R() = count_all()
proportion_S() + proportion_I() + proportion_R() = 1
and that, in combination therapies, for `only_all_tested = FALSE`
applies that:
count_S() + count_I() + count_R() >= count_all()
proportion_S() + proportion_I() + proportion_R() >= 1
Using `only_all_tested` has no impact when only using one antibiotic as
input.
## Interpretation of SIR
In 2019, the European Committee on Antimicrobial Susceptibility Testing
(EUCAST) has decided to change the definitions of susceptibility testing
categories S, I, and R ().
This AMR package follows insight; use `susceptibility()` (equal to
`proportion_SI()`) to determine antimicrobial susceptibility and
[`count_susceptible()`](https://amr-for-r.org/reference/count.md) (equal
to [`count_SI()`](https://amr-for-r.org/reference/count.md)) to count
susceptible isolates.
## See also
[`count()`](https://amr-for-r.org/reference/count.md) to count resistant
and susceptible isolates.
## Examples
``` r
# example_isolates is a data set available in the AMR package.
# run ?example_isolates for more info.
example_isolates
#> # A tibble: 2,000 × 46
#> date patient age gender ward mo PEN OXA FLC AMX
#>
#> 1 2002-01-02 A77334 65 F Clinical B_ESCHR_COLI R NA NA NA
#> 2 2002-01-03 A77334 65 F Clinical B_ESCHR_COLI R NA NA NA
#> 3 2002-01-07 067927 45 F ICU B_STPHY_EPDR R NA R NA
#> 4 2002-01-07 067927 45 F ICU B_STPHY_EPDR R NA R NA
#> 5 2002-01-13 067927 45 F ICU B_STPHY_EPDR R NA R NA
#> 6 2002-01-13 067927 45 F ICU B_STPHY_EPDR R NA R NA
#> 7 2002-01-14 462729 78 M Clinical B_STPHY_AURS R NA S R
#> 8 2002-01-14 462729 78 M Clinical B_STPHY_AURS R NA S R
#> 9 2002-01-16 067927 45 F ICU B_STPHY_EPDR R NA R NA
#> 10 2002-01-17 858515 79 F ICU B_STPHY_EPDR R NA S NA
#> # ℹ 1,990 more rows
#> # ℹ 36 more variables: AMC , AMP , TZP , CZO , FEP ,
#> # CXM , FOX , CTX , CAZ , CRO , GEN ,
#> # TOB , AMK , KAN , TMP , SXT , NIT ,
#> # FOS , LNZ , CIP , MFX , VAN , TEC ,
#> # TCY , TGC , DOX , ERY , CLI , AZM ,
#> # IPM , MEM , MTR , CHL , COL , MUP , …
# base R ------------------------------------------------------------
# determines %R
resistance(example_isolates$AMX)
#> [1] 0.5955556
sir_confidence_interval(example_isolates$AMX)
#> [1] 0.5688204 0.6218738
sir_confidence_interval(example_isolates$AMX,
confidence_level = 0.975
)
#> [1] 0.5650148 0.6255670
sir_confidence_interval(example_isolates$AMX,
confidence_level = 0.975,
collapse = ", "
)
#> [1] "0.565, 0.626"
# determines %S+I:
susceptibility(example_isolates$AMX)
#> [1] 0.4044444
sir_confidence_interval(example_isolates$AMX,
ab_result = c("S", "I")
)
#> [1] 0.3781262 0.4311796
# be more specific
proportion_S(example_isolates$AMX)
#> [1] 0.4022222
proportion_SI(example_isolates$AMX)
#> [1] 0.4044444
proportion_I(example_isolates$AMX)
#> [1] 0.002222222
proportion_IR(example_isolates$AMX)
#> [1] 0.5977778
proportion_R(example_isolates$AMX)
#> [1] 0.5955556
# dplyr -------------------------------------------------------------
# \donttest{
if (require("dplyr")) {
example_isolates %>%
group_by(ward) %>%
summarise(
r = resistance(CIP),
n = n_sir(CIP)
) # n_sir works like n_distinct in dplyr, see ?n_sir
}
#> # A tibble: 3 × 3
#> ward r n
#>
#> 1 Clinical 0.147 869
#> 2 ICU 0.190 447
#> 3 Outpatient 0.161 93
if (require("dplyr")) {
example_isolates %>%
group_by(ward) %>%
summarise(
cipro_R = resistance(CIP),
ci_min = sir_confidence_interval(CIP, side = "min"),
ci_max = sir_confidence_interval(CIP, side = "max"),
)
}
#> # A tibble: 3 × 4
#> ward cipro_R ci_min ci_max
#>
#> 1 Clinical 0.147 0.124 0.173
#> 2 ICU 0.190 0.155 0.230
#> 3 Outpatient 0.161 0.0932 0.252
if (require("dplyr")) {
# scoped dplyr verbs with antimicrobial selectors
# (you could also use across() of course)
example_isolates %>%
group_by(ward) %>%
summarise_at(
c(aminoglycosides(), carbapenems()),
resistance
)
}
#> ℹ For `aminoglycosides()` using columns 'GEN' (gentamicin), 'TOB'
#> (tobramycin), 'AMK' (amikacin), and 'KAN' (kanamycin)
#> ℹ For `carbapenems()` using columns 'IPM' (imipenem) and 'MEM' (meropenem)
#> Warning: There was 1 warning in `summarise()`.
#> ℹ In argument: `KAN = (function (..., minimum = 30, as_percent = FALSE,
#> only_all_tested = FALSE) ...`.
#> ℹ In group 3: `ward = "Outpatient"`.
#> Caused by warning:
#> ! Introducing NA: only 23 results available for KAN in group: ward =
#> "Outpatient" (`minimum` = 30).
#> # A tibble: 3 × 7
#> ward GEN TOB AMK KAN IPM MEM
#>
#> 1 Clinical 0.229 0.315 0.626 1 0.0498 0.0458
#> 2 ICU 0.290 0.400 0.662 1 0.0862 0.0894
#> 3 Outpatient 0.2 0.368 0.605 NA 0.0541 0.0541
if (require("dplyr")) {
example_isolates %>%
group_by(ward) %>%
summarise(
R = resistance(CIP, as_percent = TRUE),
SI = susceptibility(CIP, as_percent = TRUE),
n1 = count_all(CIP), # the actual total; sum of all three
n2 = n_sir(CIP), # same - analogous to n_distinct
total = n()
) # NOT the number of tested isolates!
# Calculate co-resistance between amoxicillin/clav acid and gentamicin,
# so we can see that combination therapy does a lot more than mono therapy:
example_isolates %>% susceptibility(AMC) # %SI = 76.3%
example_isolates %>% count_all(AMC) # n = 1879
example_isolates %>% susceptibility(GEN) # %SI = 75.4%
example_isolates %>% count_all(GEN) # n = 1855
example_isolates %>% susceptibility(AMC, GEN) # %SI = 94.1%
example_isolates %>% count_all(AMC, GEN) # n = 1939
# See Details on how `only_all_tested` works. Example:
example_isolates %>%
summarise(
numerator = count_susceptible(AMC, GEN),
denominator = count_all(AMC, GEN),
proportion = susceptibility(AMC, GEN)
)
example_isolates %>%
summarise(
numerator = count_susceptible(AMC, GEN, only_all_tested = TRUE),
denominator = count_all(AMC, GEN, only_all_tested = TRUE),
proportion = susceptibility(AMC, GEN, only_all_tested = TRUE)
)
example_isolates %>%
group_by(ward) %>%
summarise(
cipro_p = susceptibility(CIP, as_percent = TRUE),
cipro_n = count_all(CIP),
genta_p = susceptibility(GEN, as_percent = TRUE),
genta_n = count_all(GEN),
combination_p = susceptibility(CIP, GEN, as_percent = TRUE),
combination_n = count_all(CIP, GEN)
)
# Get proportions S/I/R immediately of all sir columns
example_isolates %>%
select(AMX, CIP) %>%
proportion_df(translate = FALSE)
# It also supports grouping variables
# (use sir_df to also include the count)
example_isolates %>%
select(ward, AMX, CIP) %>%
group_by(ward) %>%
sir_df(translate = FALSE)
}
#> # A tibble: 12 × 7
#> ward antibiotic interpretation value ci_min ci_max isolates
#>
#> 1 Clinical AMX SI 0.423 0.389 0.457 357
#> 2 Clinical AMX R 0.577 0.543 0.611 487
#> 3 Clinical CIP SI 0.853 0.827 0.876 741
#> 4 Clinical CIP R 0.147 0.124 0.173 128
#> 5 ICU AMX SI 0.369 0.323 0.417 158
#> 6 ICU AMX R 0.631 0.583 0.677 270
#> 7 ICU CIP SI 0.810 0.770 0.845 362
#> 8 ICU CIP R 0.190 0.155 0.230 85
#> 9 Outpatient AMX SI 0.397 0.288 0.515 31
#> 10 Outpatient AMX R 0.603 0.485 0.712 47
#> 11 Outpatient CIP SI 0.839 0.748 0.907 78
#> 12 Outpatient CIP R 0.161 0.0932 0.252 15
# }
```