1
0
mirror of https://github.com/msberends/AMR.git synced 2025-09-02 23:44:09 +02:00

20 Commits

Author SHA1 Message Date
60bd631e1a (v3.0.0.9019) Fixes #229, #230, #227, #225 2025-09-01 16:56:55 +02:00
9b07a8573a (v3.0.0.9018) keep all reasons in mdro(), fixed #227 2025-08-07 16:23:47 +02:00
fc72cf9324 (v3.0.0.9017) semantic versioning only on branch main 2025-07-28 12:24:52 +02:00
2f866985c9 (v3.0.0.9016) fix for plotting 2025-07-23 22:05:20 +02:00
6cb724a208 (v3.0.0.9015) plotting fix 2025-07-19 14:06:36 +02:00
49274f010b (v3.0.0.9014) fix plot colours 2025-07-18 15:57:48 +02:00
8da0f525b5 set lang for R<3.5 2025-07-17 22:58:34 +02:00
Nick Thomson
68442f3042 (v3.0.0.9012) Python wrapper fix 2025-07-17 19:43:07 +02:00
39ea5f6597 (v3.0.0.9011) allow names for age_groups() 2025-07-17 19:32:46 +02:00
65ec098acf (v3.0.0.9010) in as.sir(), add note when higher taxonomic levels are used 2025-07-17 19:06:12 +02:00
Nick Thomson
e9e3de4469 (v3.0.0.9009) fix as.sir when uti = FALSE 2025-07-17 17:15:52 +02:00
d94bdd2c6a (v3.0.0.9008) fix ggplot_sir(), support lighter green for SDD 2025-07-17 17:05:41 +02:00
8dab0a3730 (v3.0.0.9007) allow any tidyselect language in as.sir() 2025-07-17 14:29:35 +02:00
Matthijs Berends
0138e33ce9 Update 1-bug-report.yml 2025-06-22 20:47:31 +02:00
Matthijs Berends
1013ef6086 Update _pkgdown.yml 2025-06-13 17:05:51 +02:00
8fd8ee508f (v3.0.0.9004) random mic fix 2025-06-13 16:12:28 +02:00
72db2b2562 (v3.0.0.9003) eucast_rules fix, new tidymodels integration 2025-06-13 14:03:21 +02:00
3742e9e994 (v3.0.0.9002) website version nr 2025-06-06 09:37:25 +02:00
753f0e1ef9 (v3.0.0.9001) the first fixes 2025-06-04 13:10:20 +02:00
1710e220dd AMR v3.0\! 2025-06-02 12:11:00 +02:00
77 changed files with 1462 additions and 616 deletions

View File

@@ -42,7 +42,7 @@ body:
multiple: false multiple: false
options: options:
- '' - ''
- Latest CRAN version (2.1.1) - Latest CRAN version (3.0.0)
- One of the latest GitHub versions (2.1.1.9xxx) - One of the latest GitHub versions (3.0.0.9xxx)
validations: validations:
required: true required: true

View File

@@ -68,6 +68,12 @@ echo ""
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
echo "Updating semantic versioning and date..." echo "Updating semantic versioning and date..."
current_branch=$(git rev-parse --abbrev-ref HEAD)
if [ "$current_branch" != "main" ]; then
echo "- Current branch is '$current_branch'; skipping version/date update (only runs on 'main')"
else
# Version update logic begins here
# Get tags from remote and remove tags not on remote # Get tags from remote and remove tags not on remote
git fetch origin --prune --prune-tags --quiet git fetch origin --prune --prune-tags --quiet
currenttagfull=$(git describe --tags --abbrev=0) currenttagfull=$(git describe --tags --abbrev=0)
@@ -111,6 +117,7 @@ echo ""
# Save the version number for use in the commit-msg hook # Save the version number for use in the commit-msg hook
echo "${currentversion}" > .git/commit_version.tmp echo "${currentversion}" > .git/commit_version.tmp
fi
git add data-raw/* git add data-raw/*
git add data/* git add data/*

View File

@@ -59,8 +59,15 @@ jobs:
env: env:
R_REMOTES_NO_ERRORS_FROM_WARNINGS: true R_REMOTES_NO_ERRORS_FROM_WARNINGS: true
LANG: en_US.UTF-8
LC_ALL: en_US.UTF-8
steps: steps:
- name: Set up locales
run: |
sudo locale-gen en_US.UTF-8
sudo update-locale LANG=en_US.UTF-8
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: r-lib/actions/setup-r@v2 - uses: r-lib/actions/setup-r@v2

View File

@@ -1,3 +1,3 @@
Version: 2.1.1 Version: 3.0.0
Date: 2023-10-20 16:05:16 UTC Date: 2025-06-01 16:52:53 UTC
SHA: ca72a646d041f7f096c4e196e8ae2fb2b176019c SHA: 79038fed2169a25a7fc067c80bb25d9d78be21d9

View File

@@ -1,6 +1,6 @@
Package: AMR Package: AMR
Version: 2.1.1.9290 Version: 3.0.0.9019
Date: 2025-06-01 Date: 2025-09-01
Title: Antimicrobial Resistance Data Analysis Title: Antimicrobial Resistance Data Analysis
Description: Functions to simplify and standardise antimicrobial resistance (AMR) Description: Functions to simplify and standardise antimicrobial resistance (AMR)
data analysis and to work with microbial and antimicrobial properties by data analysis and to work with microbial and antimicrobial properties by
@@ -51,6 +51,8 @@ Suggests:
pillar, pillar,
progress, progress,
readxl, readxl,
recipes,
rlang,
rmarkdown, rmarkdown,
rstudioapi, rstudioapi,
rvest, rvest,

View File

@@ -106,6 +106,8 @@ S3method(print,mo_uncertainties)
S3method(print,pca) S3method(print,pca)
S3method(print,sir) S3method(print,sir)
S3method(print,sir_log) S3method(print,sir_log)
S3method(print,step_mic_log2)
S3method(print,step_sir_numeric)
S3method(quantile,mic) S3method(quantile,mic)
S3method(rep,ab) S3method(rep,ab)
S3method(rep,av) S3method(rep,av)
@@ -159,6 +161,10 @@ export(administrable_per_os)
export(age) export(age)
export(age_groups) export(age_groups)
export(all_antimicrobials) export(all_antimicrobials)
export(all_mic)
export(all_mic_predictors)
export(all_sir)
export(all_sir_predictors)
export(aminoglycosides) export(aminoglycosides)
export(aminopenicillins) export(aminopenicillins)
export(amr_class) export(amr_class)
@@ -352,6 +358,8 @@ export(sir_df)
export(sir_interpretation_history) export(sir_interpretation_history)
export(sir_predict) export(sir_predict)
export(skewness) export(skewness)
export(step_mic_log2)
export(step_sir_numeric)
export(streptogramins) export(streptogramins)
export(sulfonamides) export(sulfonamides)
export(susceptibility) export(susceptibility)
@@ -388,6 +396,12 @@ if(getRversion() >= "3.0.0") S3method(pillar::type_sum, av)
if(getRversion() >= "3.0.0") S3method(pillar::type_sum, mic) if(getRversion() >= "3.0.0") S3method(pillar::type_sum, mic)
if(getRversion() >= "3.0.0") S3method(pillar::type_sum, mo) if(getRversion() >= "3.0.0") S3method(pillar::type_sum, mo)
if(getRversion() >= "3.0.0") S3method(pillar::type_sum, sir) if(getRversion() >= "3.0.0") S3method(pillar::type_sum, sir)
if(getRversion() >= "3.0.0") S3method(recipes::bake, step_mic_log2)
if(getRversion() >= "3.0.0") S3method(recipes::bake, step_sir_numeric)
if(getRversion() >= "3.0.0") S3method(recipes::prep, step_mic_log2)
if(getRversion() >= "3.0.0") S3method(recipes::prep, step_sir_numeric)
if(getRversion() >= "3.0.0") S3method(recipes::tidy, step_mic_log2)
if(getRversion() >= "3.0.0") S3method(recipes::tidy, step_sir_numeric)
if(getRversion() >= "3.0.0") S3method(skimr::get_skimmers, disk) if(getRversion() >= "3.0.0") S3method(skimr::get_skimmers, disk)
if(getRversion() >= "3.0.0") S3method(skimr::get_skimmers, mic) if(getRversion() >= "3.0.0") S3method(skimr::get_skimmers, mic)
if(getRversion() >= "3.0.0") S3method(skimr::get_skimmers, mo) if(getRversion() >= "3.0.0") S3method(skimr::get_skimmers, mo)

34
NEWS.md
View File

@@ -1,6 +1,34 @@
# AMR 2.1.1.9290 # AMR 3.0.0.9019
*(this beta version will eventually become v3.0. We're happy to reach a new major milestone soon, which will be all about the new One Health support! Install this beta using [the instructions here](https://amr-for-r.org/#get-this-package).)* This is primarily a bugfix release, though we added one nice feature too.
### New
* Integration with the **tidymodels** framework to allow seamless use of MIC and SIR data in modelling pipelines via `recipes`
- `step_mic_log2()` to transform `<mic>` columns with log2, and `step_sir_numeric()` to convert `<sir>` columns to numeric
- New `tidyselect` helpers: `all_mic()`, `all_mic_predictors()`, `all_sir()`, `all_sir_predictors()`
### Changed
* Fixed a bug in `antibiogram()` for when no antimicrobials are set
* Fixed a bug in `antibiogram()` to allow column names containing the `+` character (#222)
* Fixed a bug in `as.ab()` for antimicrobial codes with a number in it if they are preceded by a space
* Fixed a bug in `eucast_rules()` for using specific custom rules
* Fixed a bug in `as.sir()` to allow any tidyselect language (#220)
* Fixed a bug in `as.sir()` to pick right breakpoint when `uti = FALSE` (#216)
* Fixed a bug in `ggplot_sir()` when using `combine_SI = FALSE` (#213)
* Fixed a bug the `antimicrobials` data set to remove statins (#229)
* Fixed a bug in `mdro()` to make sure all genes specified in arguments are acknowledges
* Fixed ATC J01CR05 to map to piperacillin/tazobactam rather than piperacillin/sulbactam (#230)
* Fixed all plotting to contain a separate colour for SDD (susceptible dose-dependent) (#223)
* Fixed some specific Dutch translations for antimicrobials
* Added all reasons in verbose output of `mdro()` (#227)
* Added `names` to `age_groups()` so that custom names can be given (#215)
* Added note to `as.sir()` to make it explicit when higher-level taxonomic breakpoints are used (#218)
* Added antibiotic codes from the Comprehensive Antibiotic Resistance Database (CARD) to the `antimicrobials` data set (#225)
* Updated Fosfomycin to be of antibiotic class 'Phosphonics' (#225)
* Updated `random_mic()` and `random_disk()` to set skewedness of the distribution and allow multiple microorganisms
# AMR 3.0.0
This package now supports not only tools for AMR data analysis in clinical settings, but also for veterinary and environmental microbiology. This was made possible through a collaboration with the [University of Prince Edward Island's Atlantic Veterinary College](https://www.upei.ca/avc), Canada. To celebrate this great improvement of the package, we also updated the package logo to reflect this change. This package now supports not only tools for AMR data analysis in clinical settings, but also for veterinary and environmental microbiology. This was made possible through a collaboration with the [University of Prince Edward Island's Atlantic Veterinary College](https://www.upei.ca/avc), Canada. To celebrate this great improvement of the package, we also updated the package logo to reflect this change.
@@ -124,7 +152,7 @@ This package now supports not only tools for AMR data analysis in clinical setti
## Older Versions ## Older Versions
This changelog only contains changes from AMR v3.0 (March 2025) and later. This changelog only contains changes from AMR v3.0 (June 2025) and later.
* For prior v2 versions, please see [our v2 archive](https://github.com/msberends/AMR/blob/v2.1.1/NEWS.md). * For prior v2 versions, please see [our v2 archive](https://github.com/msberends/AMR/blob/v2.1.1/NEWS.md).
* For prior v1 versions, please see [our v1 archive](https://github.com/msberends/AMR/blob/v1.8.2/NEWS.md). * For prior v1 versions, please see [our v1 archive](https://github.com/msberends/AMR/blob/v1.8.2/NEWS.md).

View File

@@ -63,31 +63,6 @@ pm_left_join <- function(x, y, by = NULL, suffix = c(".x", ".y")) {
merged merged
} }
# support where() like tidyverse (this function will also be used when running `antibiogram()`):
where <- function(fn) {
# based on https://github.com/nathaneastwood/poorman/blob/52eb6947e0b4430cd588976ed8820013eddf955f/R/where.R#L17-L32
if (!is.function(fn)) {
stop_("`", deparse(substitute(fn)), "()` is not a valid predicate function.")
}
df <- pm_select_env$.data
cols <- pm_select_env$get_colnames()
if (is.null(df)) {
df <- get_current_data("where", call = FALSE)
cols <- colnames(df)
}
preds <- unlist(lapply(
df,
function(x, fn) {
do.call("fn", list(x))
},
fn
))
if (!is.logical(preds)) stop_("`where()` must be used with functions that return `TRUE` or `FALSE`.")
data_cols <- cols
cols <- data_cols[preds]
which(data_cols %in% cols)
}
# copied and slightly rewritten from {poorman} under permissive license (2021-10-15) # copied and slightly rewritten from {poorman} under permissive license (2021-10-15)
# https://github.com/nathaneastwood/poorman, MIT licensed, Nathan Eastwood, 2020 # https://github.com/nathaneastwood/poorman, MIT licensed, Nathan Eastwood, 2020
case_when_AMR <- function(...) { case_when_AMR <- function(...) {
@@ -544,7 +519,7 @@ word_wrap <- function(...,
) )
msg <- paste0(parts, collapse = "`") msg <- paste0(parts, collapse = "`")
} }
msg <- gsub("`(.+?)`", font_grey_bg("\\1"), msg) msg <- gsub("`(.+?)`", font_grey_bg("`\\1`"), msg)
# clean introduced whitespace in between fullstops # clean introduced whitespace in between fullstops
msg <- gsub("[.] +[.]", "..", msg) msg <- gsub("[.] +[.]", "..", msg)
@@ -814,7 +789,7 @@ meet_criteria <- function(object, # can be literally `list(...)` for `allow_argu
# if object is missing, or another error: # if object is missing, or another error:
tryCatch(invisible(object), tryCatch(invisible(object),
error = function(e) AMR_env$meet_criteria_error_txt <- e$message error = function(e) AMR_env$meet_criteria_error_txt <- conditionMessage(e)
) )
if (!is.null(AMR_env$meet_criteria_error_txt)) { if (!is.null(AMR_env$meet_criteria_error_txt)) {
error_txt <- AMR_env$meet_criteria_error_txt error_txt <- AMR_env$meet_criteria_error_txt
@@ -1244,7 +1219,9 @@ try_colour <- function(..., before, after, collapse = " ") {
} }
} }
is_dark <- function() { is_dark <- function() {
if (is.null(AMR_env$is_dark_theme)) { AMR_env$current_theme <- tryCatch(getExportedValue("getThemeInfo", ns = asNamespace("rstudioapi"))()$editor, error = function(e) NULL)
if (!identical(AMR_env$current_theme, AMR_env$former_theme) || is.null(AMR_env$is_dark_theme)) {
AMR_env$former_theme <- AMR_env$current_theme
AMR_env$is_dark_theme <- !has_colour() || tryCatch(isTRUE(getExportedValue("getThemeInfo", ns = asNamespace("rstudioapi"))()$dark), error = function(e) FALSE) AMR_env$is_dark_theme <- !has_colour() || tryCatch(isTRUE(getExportedValue("getThemeInfo", ns = asNamespace("rstudioapi"))()$dark), error = function(e) FALSE)
} }
isTRUE(AMR_env$is_dark_theme) isTRUE(AMR_env$is_dark_theme)
@@ -1317,6 +1294,10 @@ font_green_bg <- function(..., collapse = " ") {
# this is #3caea3 (picked to be colourblind-safe with other SIR colours) # this is #3caea3 (picked to be colourblind-safe with other SIR colours)
try_colour(font_black(..., collapse = collapse, adapt = FALSE), before = "\033[48;5;79m", after = "\033[49m", collapse = collapse) try_colour(font_black(..., collapse = collapse, adapt = FALSE), before = "\033[48;5;79m", after = "\033[49m", collapse = collapse)
} }
font_green_lighter_bg <- function(..., collapse = " ") {
# this is #8FD6C4 (picked to be colourblind-safe with other SIR colours)
try_colour(font_black(..., collapse = collapse, adapt = FALSE), before = "\033[48;5;158m", after = "\033[49m", collapse = collapse)
}
font_purple_bg <- function(..., collapse = " ") { font_purple_bg <- function(..., collapse = " ") {
try_colour(font_black(..., collapse = collapse, adapt = FALSE), before = "\033[48;5;89m", after = "\033[49m", collapse = collapse) try_colour(font_black(..., collapse = collapse, adapt = FALSE), before = "\033[48;5;89m", after = "\033[49m", collapse = collapse)
} }
@@ -1634,6 +1615,36 @@ get_n_cores <- function(max_cores = Inf) {
n_cores n_cores
} }
# Support `where()` if tidyselect not installed ----
if (!is.null(import_fn("where", "tidyselect", error_on_fail = FALSE))) {
# tidyselect::where() exists, load the namespace to make `where()`s work across the package in default arguments
loadNamespace("tidyselect")
} else {
where <- function(fn) {
# based on https://github.com/nathaneastwood/poorman/blob/52eb6947e0b4430cd588976ed8820013eddf955f/R/where.R#L17-L32
if (!is.function(fn)) {
stop_("`", deparse(substitute(fn)), "()` is not a valid predicate function.")
}
df <- pm_select_env$.data
cols <- pm_select_env$get_colnames()
if (is.null(df)) {
df <- get_current_data("where", call = FALSE)
cols <- colnames(df)
}
preds <- unlist(lapply(
df,
function(x, fn) {
do.call("fn", list(x))
},
fn
))
if (!is.logical(preds)) stop_("`where()` must be used with functions that return `TRUE` or `FALSE`.")
data_cols <- cols
cols <- data_cols[preds]
which(data_cols %in% cols)
}
}
# Faster data.table implementations ---- # Faster data.table implementations ----
match <- function(x, table, ...) { match <- function(x, table, ...) {
@@ -1653,52 +1664,6 @@ match <- function(x, table, ...) {
} }
} }
# nolint start
# Register S3 methods ----
# copied from vctrs::s3_register by their permission:
# https://github.com/r-lib/vctrs/blob/05968ce8e669f73213e3e894b5f4424af4f46316/R/register-s3.R
s3_register <- function(generic, class, method = NULL) {
stopifnot(is.character(generic), length(generic) == 1)
stopifnot(is.character(class), length(class) == 1)
pieces <- strsplit(generic, "::")[[1]]
stopifnot(length(pieces) == 2)
package <- pieces[[1]]
generic <- pieces[[2]]
caller <- parent.frame()
get_method_env <- function() {
top <- topenv(caller)
if (isNamespace(top)) {
asNamespace(environmentName(top))
} else {
caller
}
}
get_method <- function(method, env) {
if (is.null(method)) {
get(paste0(generic, ".", class), envir = get_method_env())
} else {
method
}
}
method_fn <- get_method(method)
stopifnot(is.function(method_fn))
setHook(packageEvent(package, "onLoad"), function(...) {
ns <- asNamespace(package)
method_fn <- get_method(method)
registerS3method(generic, class, method_fn, envir = ns)
})
if (!isNamespaceLoaded(package)) {
return(invisible())
}
envir <- asNamespace(package)
if (exists(generic, envir)) {
registerS3method(generic, class, method_fn, envir = envir)
}
invisible()
}
# Support old R versions ---- # Support old R versions ----
# these functions were not available in previous versions of R # these functions were not available in previous versions of R
# see here for the full list: https://github.com/r-lib/backports # see here for the full list: https://github.com/r-lib/backports

View File

@@ -952,7 +952,19 @@ pm_select_env$get_nrow <- function() nrow(pm_select_env$.data)
pm_select_env$get_ncol <- function() ncol(pm_select_env$.data) pm_select_env$get_ncol <- function() ncol(pm_select_env$.data)
pm_select <- function(.data, ...) { pm_select <- function(.data, ...) {
# col_pos <- pm_select_positions(.data, ..., .group_pos = TRUE),
col_pos <- tryCatch(pm_select_positions(.data, ..., .group_pos = TRUE), error = function(e) NULL)
if (is.null(col_pos)) {
# try with tidyverse
select_dplyr <- import_fn("select", "dplyr", error_on_fail = FALSE)
if (!is.null(select_dplyr)) {
col_pos <- which(colnames(.data) %in% colnames(select_dplyr(.data, ...)))
} else {
# this will throw an error as it did, but dplyr is not available, so no other option
col_pos <- pm_select_positions(.data, ..., .group_pos = TRUE) col_pos <- pm_select_positions(.data, ..., .group_pos = TRUE)
}
}
map_names <- names(col_pos) map_names <- names(col_pos)
map_names_length <- nchar(map_names) map_names_length <- nchar(map_names)
if (any(map_names_length == 0L)) { if (any(map_names_length == 0L)) {

7
R/ab.R
View File

@@ -184,7 +184,8 @@ as.ab <- function(x, flag_multiple_results = TRUE, language = get_AMR_locale(),
x_new[known_codes_cid] <- AMR_env$AB_lookup$ab[match(x[known_codes_cid], AMR_env$AB_lookup$cid)] x_new[known_codes_cid] <- AMR_env$AB_lookup$ab[match(x[known_codes_cid], AMR_env$AB_lookup$cid)]
previously_coerced <- x %in% AMR_env$ab_previously_coerced$x previously_coerced <- x %in% AMR_env$ab_previously_coerced$x
x_new[previously_coerced & is.na(x_new)] <- AMR_env$ab_previously_coerced$ab[match(x[is.na(x_new) & x %in% AMR_env$ab_previously_coerced$x], AMR_env$ab_previously_coerced$x)] x_new[previously_coerced & is.na(x_new)] <- AMR_env$ab_previously_coerced$ab[match(x[is.na(x_new) & x %in% AMR_env$ab_previously_coerced$x], AMR_env$ab_previously_coerced$x)]
if (any(previously_coerced) && isTRUE(info) && message_not_thrown_before("as.ab", entire_session = TRUE)) { previously_coerced_mention <- x %in% AMR_env$ab_previously_coerced$x & !x %in% AMR_env$AB_lookup$ab & !x %in% AMR_env$AB_lookup$generalised_name
if (any(previously_coerced_mention) && isTRUE(info) && message_not_thrown_before("as.ab", entire_session = TRUE)) {
message_( message_(
"Returning previously coerced ", "Returning previously coerced ",
ifelse(length(unique(which(x[which(previously_coerced)] %in% x_bak_clean))) > 1, "value for an antimicrobial", "values for various antimicrobials"), ifelse(length(unique(which(x[which(previously_coerced)] %in% x_bak_clean))) > 1, "value for an antimicrobial", "values for various antimicrobials"),
@@ -655,7 +656,9 @@ generalise_antibiotic_name <- function(x) {
x <- trimws(gsub(" +", " ", x, perl = TRUE)) x <- trimws(gsub(" +", " ", x, perl = TRUE))
# remove last couple of words if they numbers or units # remove last couple of words if they numbers or units
x <- gsub("( ([0-9]{3,}|U?M?C?G|L))+$", "", x, perl = TRUE) x <- gsub("( ([0-9]{3,}|U?M?C?G|L))+$", "", x, perl = TRUE)
# move HIGH to end # remove whitespace prior to numbers if preceded by A-Z
x <- gsub("([A-Z]+) +([0-9]+)", "\\1\\2", x, perl = TRUE)
# move HIGH to the end
x <- trimws(gsub("(.*) HIGH(.*)", "\\1\\2 HIGH", x, perl = TRUE)) x <- trimws(gsub("(.*) HIGH(.*)", "\\1\\2 HIGH", x, perl = TRUE))
x x
} }

View File

@@ -445,7 +445,7 @@ ab_validate <- function(x, property, ...) {
# try to catch an error when inputting an invalid argument # try to catch an error when inputting an invalid argument
# so the 'call.' can be set to FALSE # so the 'call.' can be set to FALSE
tryCatch(x[1L] %in% AMR_env$AB_lookup[1, property, drop = TRUE], tryCatch(x[1L] %in% AMR_env$AB_lookup[1, property, drop = TRUE],
error = function(e) stop(e$message, call. = FALSE) error = function(e) stop(conditionMessage(e), call. = FALSE)
) )
if (!all(x %in% AMR_env$AB_lookup[, property, drop = TRUE])) { if (!all(x %in% AMR_env$AB_lookup[, property, drop = TRUE])) {

14
R/age.R
View File

@@ -128,9 +128,10 @@ age <- function(x, reference = Sys.Date(), exact = FALSE, na.rm = FALSE, ...) {
#' Split Ages into Age Groups #' Split Ages into Age Groups
#' #'
#' Split ages into age groups defined by the `split` argument. This allows for easier demographic (antimicrobial resistance) analysis. #' Split ages into age groups defined by the `split` argument. This allows for easier demographic (antimicrobial resistance) analysis. The function returns an ordered [factor].
#' @param x Age, e.g. calculated with [age()]. #' @param x Age, e.g. calculated with [age()].
#' @param split_at Values to split `x` at - the default is age groups 0-11, 12-24, 25-54, 55-74 and 75+. See *Details*. #' @param split_at Values to split `x` at - the default is age groups 0-11, 12-24, 25-54, 55-74 and 75+. See *Details*.
#' @param names Optional names to be given to the various age groups.
#' @param na.rm A [logical] to indicate whether missing values should be removed. #' @param na.rm A [logical] to indicate whether missing values should be removed.
#' @details To split ages, the input for the `split_at` argument can be: #' @details To split ages, the input for the `split_at` argument can be:
#' #'
@@ -152,6 +153,7 @@ age <- function(x, reference = Sys.Date(), exact = FALSE, na.rm = FALSE, ...) {
#' #'
#' # split into 0-19, 20-49 and 50+ #' # split into 0-19, 20-49 and 50+
#' age_groups(ages, c(20, 50)) #' age_groups(ages, c(20, 50))
#' age_groups(ages, c(20, 50), names = c("Under 20 years", "20 to 50 years", "Over 50 years"))
#' #'
#' # split into groups of ten years #' # split into groups of ten years
#' age_groups(ages, 1:10 * 10) #' age_groups(ages, 1:10 * 10)
@@ -181,9 +183,10 @@ age <- function(x, reference = Sys.Date(), exact = FALSE, na.rm = FALSE, ...) {
#' ) #' )
#' } #' }
#' } #' }
age_groups <- function(x, split_at = c(12, 25, 55, 75), na.rm = FALSE) { age_groups <- function(x, split_at = c(0, 12, 25, 55, 75), names = NULL, na.rm = FALSE) {
meet_criteria(x, allow_class = c("numeric", "integer"), is_positive_or_zero = TRUE, is_finite = TRUE) meet_criteria(x, allow_class = c("numeric", "integer"), is_positive_or_zero = TRUE, is_finite = TRUE)
meet_criteria(split_at, allow_class = c("numeric", "integer", "character"), is_positive_or_zero = TRUE, is_finite = TRUE) meet_criteria(split_at, allow_class = c("numeric", "integer", "character"), is_positive_or_zero = TRUE, is_finite = TRUE)
meet_criteria(names, allow_class = "character", allow_NULL = TRUE)
meet_criteria(na.rm, allow_class = "logical", has_length = 1) meet_criteria(na.rm, allow_class = "logical", has_length = 1)
if (any(x < 0, na.rm = TRUE)) { if (any(x < 0, na.rm = TRUE)) {
@@ -208,7 +211,7 @@ age_groups <- function(x, split_at = c(12, 25, 55, 75), na.rm = FALSE) {
split_at <- c(0, split_at) split_at <- c(0, split_at)
} }
split_at <- split_at[!is.na(split_at)] split_at <- split_at[!is.na(split_at)]
stop_if(length(split_at) == 1, "invalid value for `split_at`") # only 0 is available stop_if(length(split_at) == 1, "invalid value for `split_at`.") # only 0 is available
# turn input values to 'split_at' indices # turn input values to 'split_at' indices
y <- x y <- x
@@ -224,6 +227,11 @@ age_groups <- function(x, split_at = c(12, 25, 55, 75), na.rm = FALSE) {
agegroups <- factor(lbls[y], levels = lbls, ordered = TRUE) agegroups <- factor(lbls[y], levels = lbls, ordered = TRUE)
if (!is.null(names)) {
stop_ifnot(length(names) == length(levels(agegroups)), "`names` must have the same length as the number of age groups (", length(levels(agegroups)), ").")
levels(agegroups) <- names
}
if (isTRUE(na.rm)) { if (isTRUE(na.rm)) {
agegroups <- agegroups[!is.na(agegroups)] agegroups <- agegroups[!is.na(agegroups)]
} }

View File

@@ -527,7 +527,7 @@ amr_selector <- function(filter,
) )
call <- substitute(filter) call <- substitute(filter)
agents <- tryCatch(AMR_env$AB_lookup[which(eval(call, envir = AMR_env$AB_lookup)), "ab", drop = TRUE], agents <- tryCatch(AMR_env$AB_lookup[which(eval(call, envir = AMR_env$AB_lookup)), "ab", drop = TRUE],
error = function(e) stop_(e$message, call = -5) error = function(e) stop_(conditionMessage(e), call = -5)
) )
agents <- ab_in_data[ab_in_data %in% agents] agents <- ab_in_data[ab_in_data %in% agents]
message_agent_names( message_agent_names(
@@ -640,7 +640,7 @@ not_intrinsic_resistant <- function(only_sir_columns = FALSE, col_mo = NULL, ver
) )
} }
), ),
error = function(e) stop_("in not_intrinsic_resistant(): ", e$message, call = FALSE) error = function(e) stop_("in not_intrinsic_resistant(): ", conditionMessage(e), call = FALSE)
) )
agents <- ab_in_data[ab_in_data %in% names(vars_df_R[which(vars_df_R)])] agents <- ab_in_data[ab_in_data %in% names(vars_df_R[which(vars_df_R)])]

View File

@@ -40,6 +40,7 @@
#' - A combination of the above, using `c()`, e.g.: #' - A combination of the above, using `c()`, e.g.:
#' - `c(aminoglycosides(), "AMP", "AMC")` #' - `c(aminoglycosides(), "AMP", "AMC")`
#' - `c(aminoglycosides(), carbapenems())` #' - `c(aminoglycosides(), carbapenems())`
#' - Column indices using numbers
#' - Combination therapy, indicated by using `"+"`, with or without [antimicrobial selectors][antimicrobial_selectors], e.g.: #' - Combination therapy, indicated by using `"+"`, with or without [antimicrobial selectors][antimicrobial_selectors], e.g.:
#' - `"cipro + genta"` #' - `"cipro + genta"`
#' - `"TZP+TOB"` #' - `"TZP+TOB"`
@@ -110,7 +111,7 @@
#' #'
#' There are various antibiogram types, as summarised by Klinker *et al.* (2021, \doi{10.1177/20499361211011373}), and they are all supported by [antibiogram()]. #' There are various antibiogram types, as summarised by Klinker *et al.* (2021, \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, \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. #' 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, \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.
#' #'
#' 1. **Traditional Antibiogram** #' 1. **Traditional Antibiogram**
#' #'
@@ -266,7 +267,7 @@
#' For more background, interpretation, and examples, see [the WISCA vignette](https://amr-for-r.org/articles/WISCA.html). #' For more background, interpretation, and examples, see [the WISCA vignette](https://amr-for-r.org/articles/WISCA.html).
#' @source #' @source
#' * 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); \doi{10.1093/jac/dkv397} #' * 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); \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; \doi{10.1001.jamanetworkopen.2019.21124} #' * 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; \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; \doi{10.1177/20499361211011373} #' * Klinker KP *et al.* (2021). **Antimicrobial stewardship and antibiograms: importance of moving beyond traditional antibiograms**. *Therapeutic Advances in Infectious Disease*, May 5;8:20499361211011373; \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; \doi{10.1186/s13756-021-00939-2} #' * 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; \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/>. #' * **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/>.
@@ -452,7 +453,7 @@ antibiogram.default <- function(x,
deprecation_warning("antibiotics", "antimicrobials", fn = "antibiogram", is_argument = TRUE) deprecation_warning("antibiotics", "antimicrobials", fn = "antibiogram", is_argument = TRUE)
antimicrobials <- list(...)$antibiotics antimicrobials <- list(...)$antibiotics
} }
meet_criteria(antimicrobials, allow_class = "character", allow_NA = FALSE, allow_NULL = FALSE) meet_criteria(antimicrobials, allow_class = c("character", "numeric", "integer"), allow_NA = FALSE, allow_NULL = FALSE)
if (!is.function(mo_transform)) { if (!is.function(mo_transform)) {
meet_criteria(mo_transform, allow_class = "character", has_length = 1, is_in = c("name", "shortname", "gramstain", colnames(AMR::microorganisms)), allow_NULL = TRUE, allow_NA = TRUE) meet_criteria(mo_transform, allow_class = "character", has_length = 1, is_in = c("name", "shortname", "gramstain", colnames(AMR::microorganisms)), allow_NULL = TRUE, allow_NA = TRUE)
} }
@@ -575,6 +576,15 @@ antibiogram.default <- function(x,
} }
antimicrobials <- unlist(antimicrobials) antimicrobials <- unlist(antimicrobials)
} else { } else {
existing_ab_combined_cols <- ab_trycatch[ab_trycatch %like% "[+]" & ab_trycatch %in% colnames(x)]
if (length(existing_ab_combined_cols) > 0 && !is.null(ab_transform)) {
ab_transform <- NULL
warning_(
"Detected column name(s) containing the '+' character, which conflicts with the expected syntax in `antibiogram()`: the '+' is used to combine separate antimicrobial agent columns (e.g., \"AMP+GEN\").\n\n",
"To avoid incorrectly guessing which antimicrobials this represents, `ab_transform` was automatically set to `NULL`.\n\n",
"If this is unintended, please rename the column(s) to avoid using '+' in the name, or set `ab_transform = NULL` explicitly to suppress this message."
)
}
antimicrobials <- ab_trycatch antimicrobials <- ab_trycatch
} }
@@ -1194,12 +1204,13 @@ retrieve_wisca_parameters <- function(wisca_model, ...) {
#' @rawNamespace if(getRversion() >= "3.0.0") S3method(pillar::tbl_sum, antibiogram) #' @rawNamespace if(getRversion() >= "3.0.0") S3method(pillar::tbl_sum, antibiogram)
tbl_sum.antibiogram <- function(x, ...) { tbl_sum.antibiogram <- function(x, ...) {
dims <- paste(format(NROW(x), big.mark = ","), AMR_env$cross_icon, format(NCOL(x), big.mark = ",")) dims <- paste(format(NROW(x), big.mark = ","), AMR_env$cross_icon, format(NCOL(x), big.mark = ","))
names(dims) <- "An Antibiogram"
if (isTRUE(attributes(x)$wisca)) { if (isTRUE(attributes(x)$wisca)) {
names(dims) <- paste0("An Antibiogram (WISCA / ", attributes(x)$conf_interval * 100, "% CI)") dims <- c(dims, Type = paste0("WISCA with ", attributes(x)$conf_interval * 100, "% CI"))
} else if (isTRUE(attributes(x)$formatting_type >= 13)) { } else if (isTRUE(attributes(x)$formatting_type >= 13)) {
names(dims) <- paste0("An Antibiogram (non-WISCA / ", attributes(x)$conf_interval * 100, "% CI)") dims <- c(dims, Type = paste0("Non-WISCA with ", attributes(x)$conf_interval * 100, "% CI"))
} else { } else {
names(dims) <- paste0("An Antibiogram (non-WISCA)") dims <- c(dims, Type = paste0("Non-WISCA without CI"))
} }
dims dims
} }

View File

@@ -264,7 +264,7 @@ av_validate <- function(x, property, ...) {
# try to catch an error when inputting an invalid argument # try to catch an error when inputting an invalid argument
# so the 'call.' can be set to FALSE # so the 'call.' can be set to FALSE
tryCatch(x[1L] %in% AMR_env$AV_lookup[1, property, drop = TRUE], tryCatch(x[1L] %in% AMR_env$AV_lookup[1, property, drop = TRUE],
error = function(e) stop(e$message, call. = FALSE) error = function(e) stop(conditionMessage(e), call. = FALSE)
) )
if (!all(x %in% AMR_env$AV_lookup[, property, drop = TRUE])) { if (!all(x %in% AMR_env$AV_lookup[, property, drop = TRUE])) {

View File

@@ -126,7 +126,7 @@ count_resistant <- function(..., only_all_tested = FALSE) {
only_all_tested = only_all_tested, only_all_tested = only_all_tested,
only_count = TRUE only_count = TRUE
), ),
error = function(e) stop_(gsub("in sir_calc(): ", "", e$message, fixed = TRUE), call = -5) error = function(e) stop_(gsub("in sir_calc(): ", "", conditionMessage(e), fixed = TRUE), call = -5)
) )
} }
@@ -139,7 +139,7 @@ count_susceptible <- function(..., only_all_tested = FALSE) {
only_all_tested = only_all_tested, only_all_tested = only_all_tested,
only_count = TRUE only_count = TRUE
), ),
error = function(e) stop_(gsub("in sir_calc(): ", "", e$message, fixed = TRUE), call = -5) error = function(e) stop_(gsub("in sir_calc(): ", "", conditionMessage(e), fixed = TRUE), call = -5)
) )
} }
@@ -152,7 +152,7 @@ count_S <- function(..., only_all_tested = FALSE) {
only_all_tested = only_all_tested, only_all_tested = only_all_tested,
only_count = TRUE only_count = TRUE
), ),
error = function(e) stop_(gsub("in sir_calc(): ", "", e$message, fixed = TRUE), call = -5) error = function(e) stop_(gsub("in sir_calc(): ", "", conditionMessage(e), fixed = TRUE), call = -5)
) )
} }
@@ -165,7 +165,7 @@ count_SI <- function(..., only_all_tested = FALSE) {
only_all_tested = only_all_tested, only_all_tested = only_all_tested,
only_count = TRUE only_count = TRUE
), ),
error = function(e) stop_(gsub("in sir_calc(): ", "", e$message, fixed = TRUE), call = -5) error = function(e) stop_(gsub("in sir_calc(): ", "", conditionMessage(e), fixed = TRUE), call = -5)
) )
} }
@@ -178,7 +178,7 @@ count_I <- function(..., only_all_tested = FALSE) {
only_all_tested = only_all_tested, only_all_tested = only_all_tested,
only_count = TRUE only_count = TRUE
), ),
error = function(e) stop_(gsub("in sir_calc(): ", "", e$message, fixed = TRUE), call = -5) error = function(e) stop_(gsub("in sir_calc(): ", "", conditionMessage(e), fixed = TRUE), call = -5)
) )
} }
@@ -191,7 +191,7 @@ count_IR <- function(..., only_all_tested = FALSE) {
only_all_tested = only_all_tested, only_all_tested = only_all_tested,
only_count = TRUE only_count = TRUE
), ),
error = function(e) stop_(gsub("in sir_calc(): ", "", e$message, fixed = TRUE), call = -5) error = function(e) stop_(gsub("in sir_calc(): ", "", conditionMessage(e), fixed = TRUE), call = -5)
) )
} }
@@ -204,7 +204,7 @@ count_R <- function(..., only_all_tested = FALSE) {
only_all_tested = only_all_tested, only_all_tested = only_all_tested,
only_count = TRUE only_count = TRUE
), ),
error = function(e) stop_(gsub("in sir_calc(): ", "", e$message, fixed = TRUE), call = -5) error = function(e) stop_(gsub("in sir_calc(): ", "", conditionMessage(e), fixed = TRUE), call = -5)
) )
} }
@@ -217,7 +217,7 @@ count_all <- function(..., only_all_tested = FALSE) {
only_all_tested = only_all_tested, only_all_tested = only_all_tested,
only_count = TRUE only_count = TRUE
), ),
error = function(e) stop_(gsub("in sir_calc(): ", "", e$message, fixed = TRUE), call = -5) error = function(e) stop_(gsub("in sir_calc(): ", "", conditionMessage(e), fixed = TRUE), call = -5)
) )
} }
@@ -240,6 +240,6 @@ count_df <- function(data,
combine_SI = combine_SI, combine_SI = combine_SI,
confidence_level = 0.95 # doesn't matter, will be removed confidence_level = 0.95 # doesn't matter, will be removed
), ),
error = function(e) stop_(gsub("in sir_calc_df(): ", "", e$message, fixed = TRUE), call = -5) error = function(e) stop_(gsub("in sir_calc_df(): ", "", conditionMessage(e), fixed = TRUE), call = -5)
) )
} }

View File

@@ -175,7 +175,7 @@ custom_mdro_guideline <- function(..., as_factor = TRUE) {
# Value # Value
val <- tryCatch(eval(dots[[i]][[3]]), error = function(e) NULL) val <- tryCatch(eval(dots[[i]][[3]]), error = function(e) NULL)
stop_if(is.null(val), "rule ", i, " must return a valid value, it now returns an error: ", tryCatch(eval(dots[[i]][[3]]), error = function(e) e$message)) stop_if(is.null(val), "rule ", i, " must return a valid value, it now returns an error: ", tryCatch(eval(dots[[i]][[3]]), error = function(e) conditionMessage(e)))
stop_if(length(val) > 1, "rule ", i, " must return a value of length 1, not ", length(val)) stop_if(length(val) > 1, "rule ", i, " must return a value of length 1, not ", length(val))
out[[i]]$value <- as.character(val) out[[i]]$value <- as.character(val)
} }
@@ -254,7 +254,7 @@ run_custom_mdro_guideline <- function(df, guideline, info) {
for (i in seq_len(n_dots)) { for (i in seq_len(n_dots)) {
qry <- tryCatch(eval(parse(text = guideline[[i]]$query), envir = df, enclos = parent.frame()), qry <- tryCatch(eval(parse(text = guideline[[i]]$query), envir = df, enclos = parent.frame()),
error = function(e) { error = function(e) {
AMR_env$err_msg <- e$message AMR_env$err_msg <- conditionMessage(e)
return("error") return("error")
} }
) )

View File

@@ -361,3 +361,15 @@
#' @examples #' @examples
#' dosage #' dosage
"dosage" "dosage"
#' Data Set with `r format(nrow(esbl_isolates), big.mark = " ")` ESBL Isolates
#'
#' A data set containing `r format(nrow(esbl_isolates), big.mark = " ")` microbial isolates with MIC values of common antibiotics and a binary `esbl` column for extended-spectrum beta-lactamase (ESBL) production. This data set contains randomised fictitious data but reflects reality and can be used to practise AMR-related machine learning, e.g., classification modelling with [tidymodels](https://amr-for-r.org/articles/AMR_with_tidymodels.html).
#' @format A [tibble][tibble::tibble] with `r format(nrow(esbl_isolates), big.mark = " ")` observations and `r ncol(esbl_isolates)` variables:
#' - `esbl`\cr Logical indicator if the isolate is ESBL-producing
#' - `genus`\cr Genus of the microorganism
#' - `AMC:COL`\cr MIC values for 17 antimicrobial agents, transformed to class [`mic`] (see [as.mic()])
#' @details See our [tidymodels integration][amr-tidymodels] for an example using this data set.
#' @examples
#' esbl_isolates
"esbl_isolates"

View File

@@ -442,7 +442,7 @@ eucast_rules <- function(x,
# big speed gain! only analyse unique rows: # big speed gain! only analyse unique rows:
pm_distinct(`.rowid`, .keep_all = TRUE) %pm>% pm_distinct(`.rowid`, .keep_all = TRUE) %pm>%
as.data.frame(stringsAsFactors = FALSE) as.data.frame(stringsAsFactors = FALSE)
x[, col_mo] <- as.mo(as.character(x[, col_mo, drop = TRUE]), info = info) x[, col_mo] <- as.mo(as.character(x[, col_mo, drop = TRUE]), info = FALSE)
# rename col_mo to prevent interference with joined columns # rename col_mo to prevent interference with joined columns
colnames(x)[colnames(x) == col_mo] <- ".col_mo" colnames(x)[colnames(x) == col_mo] <- ".col_mo"
col_mo <- ".col_mo" col_mo <- ".col_mo"
@@ -450,13 +450,20 @@ eucast_rules <- function(x,
x <- left_join_microorganisms(x, by = col_mo, suffix = c("_oldcols", "")) x <- left_join_microorganisms(x, by = col_mo, suffix = c("_oldcols", ""))
x$gramstain <- mo_gramstain(x[, col_mo, drop = TRUE], language = NULL, info = FALSE) x$gramstain <- mo_gramstain(x[, col_mo, drop = TRUE], language = NULL, info = FALSE)
x$genus_species <- trimws(paste(x$genus, x$species)) x$genus_species <- trimws(paste(x$genus, x$species))
if (isTRUE(info) && NROW(x) > 10000) { if (isTRUE(info) && NROW(x.bak) > 10000) {
message_("OK.", add_fn = list(font_green, font_bold), as_note = FALSE) message_("OK.", add_fn = list(font_green, font_bold), as_note = FALSE)
} }
n_added <- 0 n_added <- 0
n_changed <- 0 n_changed <- 0
rule_current <- ""
rule_group_current <- ""
rule_group_previous <- ""
rule_next <- ""
rule_previous <- ""
rule_text <- ""
# >>> Apply Other rules: enzyme inhibitors <<< ------------------------------------------ # >>> Apply Other rules: enzyme inhibitors <<< ------------------------------------------
if (any(c("all", "other") %in% rules)) { if (any(c("all", "other") %in% rules)) {
if (isTRUE(info)) { if (isTRUE(info)) {
@@ -617,31 +624,16 @@ eucast_rules <- function(x,
eucast_rules_df <- eucast_rules_df %pm>% eucast_rules_df <- eucast_rules_df %pm>%
rbind_AMR(eucast_rules_df_total %pm>% rbind_AMR(eucast_rules_df_total %pm>%
subset(reference.rule_group %like% "breakpoint" & reference.version == version_breakpoints)) subset(reference.rule_group %like% "breakpoint" & reference.version == version_breakpoints))
# eucast_rules_df <- subset(
# eucast_rules_df,
# reference.rule_group %unlike% "breakpoint" |
# (reference.rule_group %like% "breakpoint" & reference.version == version_breakpoints)
# )
} }
if (any(c("all", "expected_phenotypes") %in% rules)) { if (any(c("all", "expected_phenotypes") %in% rules)) {
eucast_rules_df <- eucast_rules_df %pm>% eucast_rules_df <- eucast_rules_df %pm>%
rbind_AMR(eucast_rules_df_total %pm>% rbind_AMR(eucast_rules_df_total %pm>%
subset(reference.rule_group %like% "expected" & reference.version == version_expected_phenotypes)) subset(reference.rule_group %like% "expected" & reference.version == version_expected_phenotypes))
# eucast_rules_df <- subset(
# eucast_rules_df,
# reference.rule_group %unlike% "expected" |
# (reference.rule_group %like% "expected" & reference.version == version_expected_phenotypes)
# )
} }
if (any(c("all", "expert") %in% rules)) { if (any(c("all", "expert") %in% rules)) {
eucast_rules_df <- eucast_rules_df %pm>% eucast_rules_df <- eucast_rules_df %pm>%
rbind_AMR(eucast_rules_df_total %pm>% rbind_AMR(eucast_rules_df_total %pm>%
subset(reference.rule_group %like% "expert" & reference.version == version_expertrules)) subset(reference.rule_group %like% "expert" & reference.version == version_expertrules))
# eucast_rules_df <- subset(
# eucast_rules_df,
# reference.rule_group %unlike% "expert" |
# (reference.rule_group %like% "expert" & reference.version == version_expertrules)
# )
} }
## filter out AmpC de-repressed cephalosporin-resistant mutants ---- ## filter out AmpC de-repressed cephalosporin-resistant mutants ----
# no need to filter on version number here - the rules contain these version number, so are inherently filtered # no need to filter on version number here - the rules contain these version number, so are inherently filtered
@@ -664,6 +656,9 @@ eucast_rules <- function(x,
# we only hints on remaining rows in `eucast_rules_df` # we only hints on remaining rows in `eucast_rules_df`
screening_abx <- as.character(AMR::antimicrobials$ab[which(AMR::antimicrobials$ab %like% "-S$")]) screening_abx <- as.character(AMR::antimicrobials$ab[which(AMR::antimicrobials$ab %like% "-S$")])
screening_abx <- screening_abx[screening_abx %in% unique(unlist(strsplit(EUCAST_RULES_DF$and_these_antibiotics[!is.na(EUCAST_RULES_DF$and_these_antibiotics)], ", *")))] screening_abx <- screening_abx[screening_abx %in% unique(unlist(strsplit(EUCAST_RULES_DF$and_these_antibiotics[!is.na(EUCAST_RULES_DF$and_these_antibiotics)], ", *")))]
if (isTRUE(info)) {
cat("\n")
}
for (ab_s in screening_abx) { for (ab_s in screening_abx) {
ab <- gsub("-S$", "", ab_s) ab <- gsub("-S$", "", ab_s)
if (ab %in% names(cols_ab) && !ab_s %in% names(cols_ab)) { if (ab %in% names(cols_ab) && !ab_s %in% names(cols_ab)) {
@@ -894,7 +889,9 @@ eucast_rules <- function(x,
} }
for (i in seq_len(length(custom_rules))) { for (i in seq_len(length(custom_rules))) {
rule <- custom_rules[[i]] rule <- custom_rules[[i]]
rows <- which(eval(parse(text = rule$query), envir = x)) rows <- tryCatch(which(eval(parse(text = rule$query), envir = x)),
error = function(e) stop_(paste0(conditionMessage(e), font_red(" (check available data and compare with the custom rules set)")), call = FALSE)
)
cols <- as.character(rule$result_group) cols <- as.character(rule$result_group)
cols <- c( cols <- c(
cols[cols %in% colnames(x)], # direct column names cols[cols %in% colnames(x)], # direct column names
@@ -908,9 +905,8 @@ eucast_rules <- function(x,
get_antibiotic_names(cols) get_antibiotic_names(cols)
) )
if (isTRUE(info)) { if (isTRUE(info)) {
# print rule
cat(italicise_taxonomy( cat(italicise_taxonomy(
word_wrap(format_custom_query_rule(rule$query, colours = FALSE), word_wrap(rule_text,
width = getOption("width") - 30, width = getOption("width") - 30,
extra_indent = 6 extra_indent = 6
), ),
@@ -1182,7 +1178,7 @@ edit_sir <- function(x,
ifelse(length(rows) > 10, "...", ""), ifelse(length(rows) > 10, "...", ""),
" while writing value '", to, " while writing value '", to,
"' to column(s) `", paste(cols, collapse = "`, `"), "' to column(s) `", paste(cols, collapse = "`, `"),
"`:\n", e$message "`:\n", conditionMessage(e)
), ),
call. = FALSE call. = FALSE
) )

View File

@@ -72,7 +72,7 @@
#' #'
#' If there are more than two categories and you want to find out which ones are significantly different from their null expectation, you can use the same method of testing each category vs. the sum of all categories, with the Bonferroni correction. You use *G*-tests for each category, of course. #' If there are more than two categories and you want to find out which ones are significantly different from their null expectation, you can use the same method of testing each category vs. the sum of all categories, with the Bonferroni correction. You use *G*-tests for each category, of course.
#' @seealso [chisq.test()] #' @seealso [chisq.test()]
#' @references 1. McDonald, J.H. 2014. **Handbook of Biological Statistics (3rd ed.)**. Sparky House Publishing, Baltimore, Maryland. <http://www.biostathandbook.com/gtestgof.html>. #' @references 1. McDonald, J.H. 2014. **Handbook of Biological Statistics (3rd ed.)**. Sparky House Publishing, Baltimore, Maryland.
#' @source The code for this function is identical to that of [chisq.test()], except that: #' @source The code for this function is identical to that of [chisq.test()], except that:
#' - The calculation of the statistic was changed to \eqn{2 * sum(x * log(x / E))} #' - The calculation of the statistic was changed to \eqn{2 * sum(x * log(x / E))}
#' - Yates' continuity correction was removed as it does not apply to a *G*-test #' - Yates' continuity correction was removed as it does not apply to a *G*-test

View File

@@ -177,6 +177,7 @@ ggplot_sir <- function(data,
nrow = NULL, nrow = NULL,
colours = c( colours = c(
S = "#3CAEA3", S = "#3CAEA3",
SDD = "#8FD6C4",
SI = "#3CAEA3", SI = "#3CAEA3",
I = "#F6D55C", I = "#F6D55C",
IR = "#ED553B", IR = "#ED553B",
@@ -205,7 +206,7 @@ ggplot_sir <- function(data,
meet_criteria(minimum, allow_class = c("numeric", "integer"), has_length = 1, is_positive_or_zero = TRUE, is_finite = TRUE) meet_criteria(minimum, allow_class = c("numeric", "integer"), has_length = 1, is_positive_or_zero = TRUE, is_finite = TRUE)
language <- validate_language(language) language <- validate_language(language)
meet_criteria(nrow, allow_class = c("numeric", "integer"), has_length = 1, allow_NULL = TRUE, is_positive = TRUE, is_finite = TRUE) meet_criteria(nrow, allow_class = c("numeric", "integer"), has_length = 1, allow_NULL = TRUE, is_positive = TRUE, is_finite = TRUE)
meet_criteria(colours, allow_class = c("character", "logical")) meet_criteria(colours, allow_class = c("character", "logical"), allow_NULL = TRUE)
meet_criteria(datalabels, allow_class = "logical", has_length = 1) meet_criteria(datalabels, allow_class = "logical", has_length = 1)
meet_criteria(datalabels.size, allow_class = c("numeric", "integer"), has_length = 1, is_positive = TRUE, is_finite = TRUE) meet_criteria(datalabels.size, allow_class = c("numeric", "integer"), has_length = 1, is_positive = TRUE, is_finite = TRUE)
meet_criteria(datalabels.colour, allow_class = "character", has_length = 1) meet_criteria(datalabels.colour, allow_class = "character", has_length = 1)
@@ -245,7 +246,7 @@ ggplot_sir <- function(data,
) + ) +
theme_sir() theme_sir()
if (fill == "interpretation") { if (fill == "interpretation" && !is.null(colours) && !isFALSE(colours)) {
p <- suppressWarnings(p + scale_sir_colours(aesthetics = "fill", colours = colours)) p <- suppressWarnings(p + scale_sir_colours(aesthetics = "fill", colours = colours))
} }

View File

@@ -41,7 +41,7 @@
#' @inheritParams eucast_rules #' @inheritParams eucast_rules
#' @param pct_required_classes Minimal required percentage of antimicrobial classes that must be available per isolate, rounded down. For example, with the default guideline, 17 antimicrobial classes must be available for *S. aureus*. Setting this `pct_required_classes` argument to `0.5` (default) means that for every *S. aureus* isolate at least 8 different classes must be available. Any lower number of available classes will return `NA` for that isolate. #' @param pct_required_classes Minimal required percentage of antimicrobial classes that must be available per isolate, rounded down. For example, with the default guideline, 17 antimicrobial classes must be available for *S. aureus*. Setting this `pct_required_classes` argument to `0.5` (default) means that for every *S. aureus* isolate at least 8 different classes must be available. Any lower number of available classes will return `NA` for that isolate.
#' @param combine_SI A [logical] to indicate whether all values of S and I must be merged into one, so resistance is only considered when isolates are R, not I. As this is the default behaviour of the [mdro()] function, it follows the redefinition by EUCAST about the interpretation of I (increased exposure) in 2019, see section 'Interpretation of S, I and R' below. When using `combine_SI = FALSE`, resistance is considered when isolates are R or I. #' @param combine_SI A [logical] to indicate whether all values of S and I must be merged into one, so resistance is only considered when isolates are R, not I. As this is the default behaviour of the [mdro()] function, it follows the redefinition by EUCAST about the interpretation of I (increased exposure) in 2019, see section 'Interpretation of S, I and R' below. When using `combine_SI = FALSE`, resistance is considered when isolates are R or I.
#' @param verbose A [logical] to turn Verbose mode on and off (default is off). In Verbose mode, the function does not return the MDRO results, but instead returns a data set in logbook form with extensive info about which isolates would be MDRO-positive, or why they are not. #' @param verbose A [logical] to turn Verbose mode on and off (default is off). In Verbose mode, the function returns a data set with the MDRO results in logbook form with extensive info about which isolates would be MDRO-positive, or why they are not.
#' @details #' @details
#' These functions are context-aware. This means that the `x` argument can be left blank if used inside a [data.frame] call, see *Examples*. #' These functions are context-aware. This means that the `x` argument can be left blank if used inside a [data.frame] call, see *Examples*.
#' #'
@@ -174,48 +174,23 @@ mdro <- function(x = NULL,
} }
# get gene values as TRUE/FALSE # get gene values as TRUE/FALSE
if (is.character(esbl)) { resolve_gene_var <- function(x, gene, varname) {
meet_criteria(esbl, is_in = colnames(x), allow_NA = FALSE, has_length = 1) if (is.character(gene)) {
esbl <- x[[esbl]] meet_criteria(gene, is_in = colnames(x), allow_NA = FALSE, has_length = 1)
meet_criteria(esbl, allow_class = "logical", allow_NA = TRUE) gene <- x[[gene]]
} else if (length(esbl) == 1) { meet_criteria(gene, allow_class = "logical", allow_NA = TRUE)
esbl <- rep(esbl, NROW(x)) } else if (length(gene) == 1) {
gene <- rep(gene, NROW(x))
} }
if (is.character(carbapenemase)) { x[[varname]] <- gene
meet_criteria(carbapenemase, is_in = colnames(x), allow_NA = FALSE, has_length = 1) x
carbapenemase <- x[[carbapenemase]]
meet_criteria(carbapenemase, allow_class = "logical", allow_NA = TRUE)
} else if (length(carbapenemase) == 1) {
carbapenemase <- rep(carbapenemase, NROW(x))
}
if (is.character(mecA)) {
meet_criteria(mecA, is_in = colnames(x), allow_NA = FALSE, has_length = 1)
mecA <- x[[mecA]]
meet_criteria(mecA, allow_class = "logical", allow_NA = TRUE)
} else if (length(mecA) == 1) {
mecA <- rep(mecA, NROW(x))
}
if (is.character(mecC)) {
meet_criteria(mecC, is_in = colnames(x), allow_NA = FALSE, has_length = 1)
mecC <- x[[mecC]]
meet_criteria(mecC, allow_class = "logical", allow_NA = TRUE)
} else if (length(mecC) == 1) {
mecC <- rep(mecC, NROW(x))
}
if (is.character(vanA)) {
meet_criteria(vanA, is_in = colnames(x), allow_NA = FALSE, has_length = 1)
vanA <- x[[vanA]]
meet_criteria(vanA, allow_class = "logical", allow_NA = TRUE)
} else if (length(vanA) == 1) {
vanA <- rep(vanA, NROW(x))
}
if (is.character(vanB)) {
meet_criteria(vanB, is_in = colnames(x), allow_NA = FALSE, has_length = 1)
vanB <- x[[vanB]]
meet_criteria(vanB, allow_class = "logical", allow_NA = TRUE)
} else if (length(vanB) == 1) {
vanB <- rep(vanB, NROW(x))
} }
x <- resolve_gene_var(x, esbl, "esbl")
x <- resolve_gene_var(x, carbapenemase, "carbapenemase")
x <- resolve_gene_var(x, mecA, "mecA")
x <- resolve_gene_var(x, mecC, "mecC")
x <- resolve_gene_var(x, vanA, "vanA")
x <- resolve_gene_var(x, vanB, "vanB")
info.bak <- info info.bak <- info
# don't throw info's more than once per call # don't throw info's more than once per call
@@ -772,7 +747,7 @@ mdro <- function(x = NULL,
) )
} }
x[rows_to_change, "MDRO"] <<- to x[rows_to_change, "MDRO"] <<- to
x[rows_to_change, "reason"] <<- reason x[rows_to_change, "reason"] <<- paste0(x[rows_to_change, "reason", drop = TRUE], "; ", reason)
x[rows_not_to_change, "reason"] <<- "guideline criteria not met" x[rows_not_to_change, "reason"] <<- "guideline criteria not met"
} }
} }
@@ -854,7 +829,7 @@ mdro <- function(x = NULL,
x <- left_join_microorganisms(x, by = col_mo) x <- left_join_microorganisms(x, by = col_mo)
x$MDRO <- ifelse(!is.na(x$genus), 1, NA_integer_) x$MDRO <- ifelse(!is.na(x$genus), 1, NA_integer_)
x$row_number <- seq_len(nrow(x)) x$row_number <- seq_len(nrow(x))
x$reason <- NA_character_ x$reason <- ""
x$all_nonsusceptible_columns <- "" x$all_nonsusceptible_columns <- ""
if (guideline$code == "cmi2012") { if (guideline$code == "cmi2012") {
@@ -1498,7 +1473,7 @@ mdro <- function(x = NULL,
} }
trans_tbl( trans_tbl(
3, # positive 3, # positive
rows = which(x$order == "Enterobacterales" & esbl == TRUE), rows = which(x$order == "Enterobacterales" & x$esbl == TRUE),
cols = "any", cols = "any",
any_all = "any", any_all = "any",
reason = "Enterobacterales: ESBL" reason = "Enterobacterales: ESBL"
@@ -1519,7 +1494,7 @@ mdro <- function(x = NULL,
) )
trans_tbl( trans_tbl(
3, 3,
rows = which(x$order == "Enterobacterales" & carbapenemase == TRUE), rows = which(x$order == "Enterobacterales" & x$carbapenemase == TRUE),
cols = "any", cols = "any",
any_all = "any", any_all = "any",
reason = "Enterobacterales: carbapenemase" reason = "Enterobacterales: carbapenemase"
@@ -1557,14 +1532,14 @@ mdro <- function(x = NULL,
) )
trans_tbl( trans_tbl(
2, # unconfirmed 2, # unconfirmed
rows = which(x[[col_mo]] %in% AMR::microorganisms.groups$mo[AMR::microorganisms.groups$mo_group_name == "Acinetobacter baumannii complex"] & is.na(carbapenemase)), rows = which(x[[col_mo]] %in% AMR::microorganisms.groups$mo[AMR::microorganisms.groups$mo_group_name == "Acinetobacter baumannii complex"] & is.na(x$carbapenemase)),
cols = carbapenems, cols = carbapenems,
any_all = "any", any_all = "any",
reason = "A. baumannii-calcoaceticus complex: potential carbapenemase" reason = "A. baumannii-calcoaceticus complex: potential carbapenemase"
) )
trans_tbl( trans_tbl(
3, 3,
rows = which(x[[col_mo]] %in% AMR::microorganisms.groups$mo[AMR::microorganisms.groups$mo_group_name == "Acinetobacter baumannii complex"] & carbapenemase == TRUE), rows = which(x[[col_mo]] %in% AMR::microorganisms.groups$mo[AMR::microorganisms.groups$mo_group_name == "Acinetobacter baumannii complex"] & x$carbapenemase == TRUE),
cols = carbapenems, cols = carbapenems,
any_all = "any", any_all = "any",
reason = "A. baumannii-calcoaceticus complex: carbapenemase" reason = "A. baumannii-calcoaceticus complex: carbapenemase"
@@ -1574,6 +1549,7 @@ mdro <- function(x = NULL,
x$psae <- 0 x$psae <- 0
x$psae <- x$psae + ifelse(NA_as_FALSE(col_values(x, TOB) == "R") | NA_as_FALSE(col_values(x, AMK) == "R"), 1, 0) x$psae <- x$psae + ifelse(NA_as_FALSE(col_values(x, TOB) == "R") | NA_as_FALSE(col_values(x, AMK) == "R"), 1, 0)
x$psae <- x$psae + ifelse(NA_as_FALSE(col_values(x, IPM) == "R") | NA_as_FALSE(col_values(x, MEM) == "R"), 1, 0) x$psae <- x$psae + ifelse(NA_as_FALSE(col_values(x, IPM) == "R") | NA_as_FALSE(col_values(x, MEM) == "R"), 1, 0)
x$psae <- x$psae + ifelse(NA_as_FALSE(x$carbapenemase), 1, 0)
x$psae <- x$psae + ifelse(NA_as_FALSE(col_values(x, PIP) == "R") | NA_as_FALSE(col_values(x, TZP) == "R"), 1, 0) x$psae <- x$psae + ifelse(NA_as_FALSE(col_values(x, PIP) == "R") | NA_as_FALSE(col_values(x, TZP) == "R"), 1, 0)
x$psae <- x$psae + ifelse(NA_as_FALSE(col_values(x, CAZ) == "R") | NA_as_FALSE(col_values(x, CZA) == "R"), 1, 0) x$psae <- x$psae + ifelse(NA_as_FALSE(col_values(x, CAZ) == "R") | NA_as_FALSE(col_values(x, CZA) == "R"), 1, 0)
x$psae <- x$psae + ifelse(NA_as_FALSE(col_values(x, CIP) == "R") | NA_as_FALSE(col_values(x, NOR) == "R") | NA_as_FALSE(col_values(x, LVX) == "R"), 1, 0) x$psae <- x$psae + ifelse(NA_as_FALSE(col_values(x, CIP) == "R") | NA_as_FALSE(col_values(x, NOR) == "R") | NA_as_FALSE(col_values(x, LVX) == "R"), 1, 0)
@@ -1602,7 +1578,7 @@ mdro <- function(x = NULL,
) )
trans_tbl( trans_tbl(
3, 3,
rows = which(x$genus == "Enterococcus" & x$species == "faecium" & (vanA == TRUE | vanB == TRUE)), rows = which(x$genus == "Enterococcus" & x$species == "faecium" & (x$vanA == TRUE | x$vanB == TRUE)),
cols = c(PEN, AMX, AMP, VAN), cols = c(PEN, AMX, AMP, VAN),
any_all = "any", any_all = "any",
reason = "E. faecium: vanA/vanB gene + penicillin group" reason = "E. faecium: vanA/vanB gene + penicillin group"
@@ -1611,14 +1587,14 @@ mdro <- function(x = NULL,
# Staphylococcus aureus complex (= aureus, argenteus or schweitzeri) # Staphylococcus aureus complex (= aureus, argenteus or schweitzeri)
trans_tbl( trans_tbl(
2, 2,
rows = which(x$genus == "Staphylococcus" & x$species %in% c("aureus", "argenteus", "schweitzeri") & (is.na(mecA) | is.na(mecC))), rows = which(x$genus == "Staphylococcus" & x$species %in% c("aureus", "argenteus", "schweitzeri") & (is.na(x$mecA) | is.na(x$mecC))),
cols = c(AMC, TZP, FLC, OXA, FOX, FOX1), cols = c(AMC, TZP, FLC, OXA, FOX, FOX1),
any_all = "any", any_all = "any",
reason = "S. aureus complex: potential MRSA" reason = "S. aureus complex: potential MRSA"
) )
trans_tbl( trans_tbl(
3, 3,
rows = which(x$genus == "Staphylococcus" & x$species %in% c("aureus", "argenteus", "schweitzeri") & (mecA == TRUE | mecC == TRUE)), rows = which(x$genus == "Staphylococcus" & x$species %in% c("aureus", "argenteus", "schweitzeri") & (x$mecA == TRUE | x$mecC == TRUE)),
cols = "any", cols = "any",
any_all = "any", any_all = "any",
reason = "S. aureus complex: mecA/mecC gene" reason = "S. aureus complex: mecA/mecC gene"
@@ -1899,6 +1875,10 @@ mdro <- function(x = NULL,
# fill in empty reasons # fill in empty reasons
x$reason[is.na(x$reason)] <- "not covered by guideline" x$reason[is.na(x$reason)] <- "not covered by guideline"
x[rows_empty, "reason"] <- paste(x[rows_empty, "reason"], "(note: no available test results)") x[rows_empty, "reason"] <- paste(x[rows_empty, "reason"], "(note: no available test results)")
# starting semicolons must be removed
x$reason <- trimws(gsub("^;", "", x$reason))
# if criteria were not met initially, but later they were, then they have a following semicolon; remove the initial lack of meeting criteria
x$reason <- trimws(gsub("guideline criteria not met;", "", x$reason, fixed = TRUE))
# format data set # format data set
colnames(x)[colnames(x) == col_mo] <- "microorganism" colnames(x)[colnames(x) == col_mo] <- "microorganism"
x$microorganism <- mo_name(x$microorganism, language = NULL) x$microorganism <- mo_name(x$microorganism, language = NULL)

View File

@@ -31,7 +31,7 @@
#' #'
#' Calculates a normalised mean for antimicrobial resistance between multiple observations, to help to identify similar isolates without comparing antibiograms by hand. #' Calculates a normalised mean for antimicrobial resistance between multiple observations, to help to identify similar isolates without comparing antibiograms by hand.
#' @param x A vector of class [sir][as.sir()], [mic][as.mic()] or [disk][as.disk()], or a [data.frame] containing columns of any of these classes. #' @param x A vector of class [sir][as.sir()], [mic][as.mic()] or [disk][as.disk()], or a [data.frame] containing columns of any of these classes.
#' @param ... Variables to select. Supports [tidyselect language][tidyselect::language] (such as `column1:column4` and `where(is.mic)`), and can thus also be [antimicrobial selectors][amr_selector()]. #' @param ... Variables to select. Supports [tidyselect language][tidyselect::starts_with()] such as `where(is.mic)`, `starts_with(...)`, or `column1:column4`, and can thus also be [antimicrobial selectors][amr_selector()].
#' @param combine_SI A [logical] to indicate whether all values of S, SDD, and I must be merged into one, so the input only consists of S+I vs. R (susceptible vs. resistant) - the default is `TRUE`. #' @param combine_SI A [logical] to indicate whether all values of S, SDD, and I must be merged into one, so the input only consists of S+I vs. R (susceptible vs. resistant) - the default is `TRUE`.
#' @details The mean AMR distance is effectively [the Z-score](https://en.wikipedia.org/wiki/Standard_score); a normalised numeric value to compare AMR test results which can help to identify similar isolates, without comparing antibiograms by hand. #' @details The mean AMR distance is effectively [the Z-score](https://en.wikipedia.org/wiki/Standard_score); a normalised numeric value to compare AMR test results which can help to identify similar isolates, without comparing antibiograms by hand.
#' #'

View File

@@ -432,11 +432,17 @@ pillar_shaft.mic <- function(x, ...) {
} }
crude_numbers <- as.double(x) crude_numbers <- as.double(x)
operators <- gsub("[^<=>]+", "", as.character(x)) operators <- gsub("[^<=>]+", "", as.character(x))
# colourise operators
operators[!is.na(operators) & operators != ""] <- font_silver(operators[!is.na(operators) & operators != ""], collapse = NULL) operators[!is.na(operators) & operators != ""] <- font_silver(operators[!is.na(operators) & operators != ""], collapse = NULL)
out <- trimws(paste0(operators, trimws(format(crude_numbers)))) out <- trimws(paste0(operators, trimws(format(crude_numbers))))
out[is.na(x)] <- font_na(NA) out[is.na(x)] <- font_na(NA)
# make trailing zeroes less visible # make trailing zeroes less visible
out[out %like% "[.]"] <- gsub("([.]?0+)$", font_silver("\\1"), out[out %like% "[.]"], perl = TRUE) if (is_dark()) {
fn <- font_silver
} else {
fn <- font_white
}
out[out %like% "[.]"] <- gsub("([.]?0+)$", fn("\\1"), out[out %like% "[.]"], perl = TRUE)
create_pillar_column(out, align = "right", width = max(nchar(font_stripstyle(out)))) create_pillar_column(out, align = "right", width = max(nchar(font_stripstyle(out))))
} }

2
R/mo.R
View File

@@ -1186,7 +1186,7 @@ parse_and_convert <- function(x) {
parsed <- gsub('"', "", parsed, fixed = TRUE) parsed <- gsub('"', "", parsed, fixed = TRUE)
parsed parsed
}, },
error = function(e) stop(e$message, call. = FALSE) error = function(e) stop(conditionMessage(e), call. = FALSE)
) # this will also be thrown when running `as.mo(no_existing_object)` ) # this will also be thrown when running `as.mo(no_existing_object)`
} }
out <- trimws2(out) out <- trimws2(out)

View File

@@ -974,7 +974,7 @@ mo_validate <- function(x, property, language, keep_synonyms = keep_synonyms, ..
# try to catch an error when inputting an invalid argument # try to catch an error when inputting an invalid argument
# so the 'call.' can be set to FALSE # so the 'call.' can be set to FALSE
tryCatch(x[1L] %in% unlist(AMR_env$MO_lookup[1, property, drop = TRUE]), tryCatch(x[1L] %in% unlist(AMR_env$MO_lookup[1, property, drop = TRUE]),
error = function(e) stop(e$message, call. = FALSE) error = function(e) stop(conditionMessage(e), call. = FALSE)
) )
dots <- list(...) dots <- list(...)

View File

@@ -99,7 +99,7 @@ pca <- function(x,
new_list <- list(0) new_list <- list(0)
for (i in seq_len(length(dots) - 1)) { for (i in seq_len(length(dots) - 1)) {
new_list[[i]] <- tryCatch(eval(dots[[i + 1]], envir = x), new_list[[i]] <- tryCatch(eval(dots[[i + 1]], envir = x),
error = function(e) stop(e$message, call. = FALSE) error = function(e) stop(conditionMessage(e), call. = FALSE)
) )
if (length(new_list[[i]]) == 1) { if (length(new_list[[i]]) == 1) {
if (is.character(new_list[[i]]) && new_list[[i]] %in% colnames(x)) { if (is.character(new_list[[i]]) && new_list[[i]] %in% colnames(x)) {

View File

@@ -90,6 +90,10 @@
#' autoplot(some_mic_values, mo = "Escherichia coli", ab = "cipro") #' autoplot(some_mic_values, mo = "Escherichia coli", ab = "cipro")
#' } #' }
#' if (require("ggplot2")) { #' if (require("ggplot2")) {
#' autoplot(some_mic_values, mo = "Staph aureus", ab = "Ceftaroline", guideline = "CLSI")
#' }
#'
#' if (require("ggplot2")) {
#' # support for 27 languages, various guidelines, and many options #' # support for 27 languages, various guidelines, and many options
#' autoplot(some_disk_values, #' autoplot(some_disk_values,
#' mo = "Escherichia coli", ab = "cipro", #' mo = "Escherichia coli", ab = "cipro",
@@ -146,7 +150,7 @@
#' aes(group, mic) #' aes(group, mic)
#' ) + #' ) +
#' geom_boxplot() + #' geom_boxplot() +
#' geom_violin(linetype = 2, colour = "grey", fill = NA) + #' geom_violin(linetype = 2, colour = "grey30", fill = NA) +
#' scale_y_mic() #' scale_y_mic()
#' } #' }
#' if (require("ggplot2")) { #' if (require("ggplot2")) {
@@ -158,7 +162,7 @@
#' aes(group, mic) #' aes(group, mic)
#' ) + #' ) +
#' geom_boxplot() + #' geom_boxplot() +
#' geom_violin(linetype = 2, colour = "grey", fill = NA) + #' geom_violin(linetype = 2, colour = "grey30", fill = NA) +
#' scale_y_mic(mic_range = c(NA, 0.25)) #' scale_y_mic(mic_range = c(NA, 0.25))
#' } #' }
#' #'
@@ -191,7 +195,7 @@
#' aes(x = group, y = mic, colour = sir) #' aes(x = group, y = mic, colour = sir)
#' ) + #' ) +
#' theme_minimal() + #' theme_minimal() +
#' geom_boxplot(fill = NA, colour = "grey") + #' geom_boxplot(fill = NA, colour = "grey30") +
#' geom_jitter(width = 0.25) #' geom_jitter(width = 0.25)
#' #'
#' plain #' plain
@@ -377,6 +381,8 @@ create_scale_sir <- function(aesthetics, colours_SIR, language, eucast_I, ...) {
args <- list(...) args <- list(...)
args[c("value", "labels", "limits")] <- NULL args[c("value", "labels", "limits")] <- NULL
colours_SIR <- expand_SIR_colours(colours_SIR, unname = FALSE)
if (identical(aesthetics, "x")) { if (identical(aesthetics, "x")) {
ggplot_fn <- ggplot2::scale_x_discrete ggplot_fn <- ggplot2::scale_x_discrete
} else { } else {
@@ -385,24 +391,19 @@ create_scale_sir <- function(aesthetics, colours_SIR, language, eucast_I, ...) {
args, args,
list( list(
aesthetics = aesthetics, aesthetics = aesthetics,
values = c( values = c(colours_SIR, NI = "grey30")
S = colours_SIR[1],
SDD = colours_SIR[2],
I = colours_SIR[2],
R = colours_SIR[3],
NI = "grey30"
)
) )
) )
} }
scale <- do.call(ggplot_fn, args) scale <- do.call(ggplot_fn, args)
scale$labels <- function(x) { scale$labels <- function(x) {
stop_ifnot(all(x %in% c(levels(NA_sir_), NA)), stop_ifnot(all(x %in% c(levels(NA_sir_), "SI", "IR", NA)),
"Apply `scale_", aesthetics[1], "_sir()` to a variable of class 'sir', see `?as.sir`.", "Apply `scale_", aesthetics[1], "_sir()` to a variable of class 'sir', see `?as.sir`.",
call = FALSE call = FALSE
) )
x <- as.character(as.sir(x)) x <- as.character(x)
x[!x %in% c("SI", "IR")] <- as.character(as.sir(x[!x %in% c("SI", "IR")]))
if (!is.null(language)) { if (!is.null(language)) {
x[x == "S"] <- "(S) Susceptible" x[x == "S"] <- "(S) Susceptible"
x[x == "SDD"] <- "(SDD) Susceptible dose-dependent" x[x == "SDD"] <- "(SDD) Susceptible dose-dependent"
@@ -412,6 +413,8 @@ create_scale_sir <- function(aesthetics, colours_SIR, language, eucast_I, ...) {
x[x == "I"] <- "(I) Intermediate" x[x == "I"] <- "(I) Intermediate"
} }
x[x == "R"] <- "(R) Resistant" x[x == "R"] <- "(R) Resistant"
x[x == "SI"] <- "(S/I) Susceptible"
x[x == "IR"] <- "(I/R) Non-susceptible"
x[x == "NI"] <- "(NI) Non-interpretable" x[x == "NI"] <- "(NI) Non-interpretable"
x <- translate_AMR(x, language = language) x <- translate_AMR(x, language = language)
} }
@@ -419,7 +422,7 @@ create_scale_sir <- function(aesthetics, colours_SIR, language, eucast_I, ...) {
} }
scale$limits <- function(x, ...) { scale$limits <- function(x, ...) {
# force SIR in the right order # force SIR in the right order
as.character(sort(factor(x, levels = levels(NA_sir_)))) as.character(sort(factor(x, levels = c(levels(NA_sir_), "SI", "IR"))))
} }
scale scale
@@ -427,11 +430,16 @@ create_scale_sir <- function(aesthetics, colours_SIR, language, eucast_I, ...) {
#' @rdname plot #' @rdname plot
#' @export #' @export
scale_x_sir <- function(colours_SIR = c("#3CAEA3", "#F6D55C", "#ED553B"), scale_x_sir <- function(colours_SIR = c(
S = "#3CAEA3",
SDD = "#8FD6C4",
I = "#F6D55C",
R = "#ED553B"
),
language = get_AMR_locale(), language = get_AMR_locale(),
eucast_I = getOption("AMR_guideline", "EUCAST") == "EUCAST", eucast_I = getOption("AMR_guideline", "EUCAST") == "EUCAST",
...) { ...) {
meet_criteria(colours_SIR, allow_class = "character", has_length = c(1, 3)) meet_criteria(colours_SIR, allow_class = "character", has_length = c(1, 3, 4))
language <- validate_language(language) language <- validate_language(language)
meet_criteria(eucast_I, allow_class = "logical", has_length = 1) meet_criteria(eucast_I, allow_class = "logical", has_length = 1)
create_scale_sir(aesthetics = "x", colours_SIR = colours_SIR, language = language, eucast_I = eucast_I) create_scale_sir(aesthetics = "x", colours_SIR = colours_SIR, language = language, eucast_I = eucast_I)
@@ -439,11 +447,16 @@ scale_x_sir <- function(colours_SIR = c("#3CAEA3", "#F6D55C", "#ED553B"),
#' @rdname plot #' @rdname plot
#' @export #' @export
scale_colour_sir <- function(colours_SIR = c("#3CAEA3", "#F6D55C", "#ED553B"), scale_colour_sir <- function(colours_SIR = c(
S = "#3CAEA3",
SDD = "#8FD6C4",
I = "#F6D55C",
R = "#ED553B"
),
language = get_AMR_locale(), language = get_AMR_locale(),
eucast_I = getOption("AMR_guideline", "EUCAST") == "EUCAST", eucast_I = getOption("AMR_guideline", "EUCAST") == "EUCAST",
...) { ...) {
meet_criteria(colours_SIR, allow_class = "character", has_length = c(1, 3)) meet_criteria(colours_SIR, allow_class = "character", has_length = c(1, 3, 4))
language <- validate_language(language) language <- validate_language(language)
meet_criteria(eucast_I, allow_class = "logical", has_length = 1) meet_criteria(eucast_I, allow_class = "logical", has_length = 1)
args <- list(...) args <- list(...)
@@ -463,11 +476,16 @@ scale_color_sir <- scale_colour_sir
#' @rdname plot #' @rdname plot
#' @export #' @export
scale_fill_sir <- function(colours_SIR = c("#3CAEA3", "#F6D55C", "#ED553B"), scale_fill_sir <- function(colours_SIR = c(
S = "#3CAEA3",
SDD = "#8FD6C4",
I = "#F6D55C",
R = "#ED553B"
),
language = get_AMR_locale(), language = get_AMR_locale(),
eucast_I = getOption("AMR_guideline", "EUCAST") == "EUCAST", eucast_I = getOption("AMR_guideline", "EUCAST") == "EUCAST",
...) { ...) {
meet_criteria(colours_SIR, allow_class = "character", has_length = c(1, 3)) meet_criteria(colours_SIR, allow_class = "character", has_length = c(1, 3, 4))
language <- validate_language(language) language <- validate_language(language)
meet_criteria(eucast_I, allow_class = "logical", has_length = 1) meet_criteria(eucast_I, allow_class = "logical", has_length = 1)
args <- list(...) args <- list(...)
@@ -491,7 +509,12 @@ plot.mic <- function(x,
main = deparse(substitute(x)), main = deparse(substitute(x)),
ylab = translate_AMR("Frequency", language = language), ylab = translate_AMR("Frequency", language = language),
xlab = translate_AMR("Minimum Inhibitory Concentration (mg/L)", language = language), xlab = translate_AMR("Minimum Inhibitory Concentration (mg/L)", language = language),
colours_SIR = c("#3CAEA3", "#F6D55C", "#ED553B"), colours_SIR = c(
S = "#3CAEA3",
SDD = "#8FD6C4",
I = "#F6D55C",
R = "#ED553B"
),
language = get_AMR_locale(), language = get_AMR_locale(),
expand = TRUE, expand = TRUE,
include_PKPD = getOption("AMR_include_PKPD", TRUE), include_PKPD = getOption("AMR_include_PKPD", TRUE),
@@ -503,16 +526,13 @@ plot.mic <- function(x,
meet_criteria(main, allow_class = "character", has_length = 1, allow_NULL = TRUE) meet_criteria(main, allow_class = "character", has_length = 1, allow_NULL = TRUE)
meet_criteria(ylab, allow_class = "character", has_length = 1) meet_criteria(ylab, allow_class = "character", has_length = 1)
meet_criteria(xlab, allow_class = "character", has_length = 1) meet_criteria(xlab, allow_class = "character", has_length = 1)
meet_criteria(colours_SIR, allow_class = "character", has_length = c(1, 3)) meet_criteria(colours_SIR, allow_class = "character", has_length = c(1, 3, 4))
language <- validate_language(language) language <- validate_language(language)
meet_criteria(expand, allow_class = "logical", has_length = 1) meet_criteria(expand, allow_class = "logical", has_length = 1)
x <- as.mic(x) # make sure that currently implemented MIC levels are used x <- as.mic(x) # make sure that currently implemented MIC levels are used
if (length(colours_SIR) == 1) {
colours_SIR <- rep(colours_SIR, 3)
}
main <- gsub(" +", " ", paste0(main, collapse = " ")) main <- gsub(" +", " ", paste0(main, collapse = " "))
colours_SIR <- expand_SIR_colours(colours_SIR)
x <- plotrange_as_table(x, expand = expand) x <- plotrange_as_table(x, expand = expand)
cols_sub <- plot_colours_subtitle_guideline( cols_sub <- plot_colours_subtitle_guideline(
@@ -549,13 +569,17 @@ plot.mic <- function(x,
legend_col <- colours_SIR[1] legend_col <- colours_SIR[1]
} }
if (any(cols_sub$cols == colours_SIR[2] & cols_sub$count > 0)) { if (any(cols_sub$cols == colours_SIR[2] & cols_sub$count > 0)) {
legend_txt <- c(legend_txt, paste("(I)", plot_name_of_I(cols_sub$guideline))) legend_txt <- c(legend_txt, "(SDD) Susceptible dose-dependent")
legend_col <- c(legend_col, colours_SIR[2]) legend_col <- c(legend_col, colours_SIR[2])
} }
if (any(cols_sub$cols == colours_SIR[3] & cols_sub$count > 0)) { if (any(cols_sub$cols == colours_SIR[3] & cols_sub$count > 0)) {
legend_txt <- c(legend_txt, "(R) Resistant") legend_txt <- c(legend_txt, paste("(I)", plot_name_of_I(cols_sub$guideline)))
legend_col <- c(legend_col, colours_SIR[3]) legend_col <- c(legend_col, colours_SIR[3])
} }
if (any(cols_sub$cols == colours_SIR[4] & cols_sub$count > 0)) {
legend_txt <- c(legend_txt, "(R) Resistant")
legend_col <- c(legend_col, colours_SIR[4])
}
legend("top", legend("top",
x.intersp = 0.5, x.intersp = 0.5,
@@ -580,7 +604,12 @@ barplot.mic <- function(height,
main = deparse(substitute(height)), main = deparse(substitute(height)),
ylab = translate_AMR("Frequency", language = language), ylab = translate_AMR("Frequency", language = language),
xlab = translate_AMR("Minimum Inhibitory Concentration (mg/L)", language = language), xlab = translate_AMR("Minimum Inhibitory Concentration (mg/L)", language = language),
colours_SIR = c("#3CAEA3", "#F6D55C", "#ED553B"), colours_SIR = c(
S = "#3CAEA3",
SDD = "#8FD6C4",
I = "#F6D55C",
R = "#ED553B"
),
language = get_AMR_locale(), language = get_AMR_locale(),
expand = TRUE, expand = TRUE,
...) { ...) {
@@ -590,7 +619,7 @@ barplot.mic <- function(height,
meet_criteria(mo, allow_class = c("mo", "character"), allow_NULL = TRUE) meet_criteria(mo, allow_class = c("mo", "character"), allow_NULL = TRUE)
meet_criteria(ab, allow_class = c("ab", "character"), allow_NULL = TRUE) meet_criteria(ab, allow_class = c("ab", "character"), allow_NULL = TRUE)
meet_criteria(guideline, allow_class = "character", has_length = 1) meet_criteria(guideline, allow_class = "character", has_length = 1)
meet_criteria(colours_SIR, allow_class = "character", has_length = c(1, 3)) meet_criteria(colours_SIR, allow_class = "character", has_length = c(1, 3, 4))
language <- validate_language(language) language <- validate_language(language)
meet_criteria(expand, allow_class = "logical", has_length = 1) meet_criteria(expand, allow_class = "logical", has_length = 1)
@@ -622,7 +651,12 @@ autoplot.mic <- function(object,
title = deparse(substitute(object)), title = deparse(substitute(object)),
ylab = translate_AMR("Frequency", language = language), ylab = translate_AMR("Frequency", language = language),
xlab = translate_AMR("Minimum Inhibitory Concentration (mg/L)", language = language), xlab = translate_AMR("Minimum Inhibitory Concentration (mg/L)", language = language),
colours_SIR = c("#3CAEA3", "#F6D55C", "#ED553B"), colours_SIR = c(
S = "#3CAEA3",
SDD = "#8FD6C4",
I = "#F6D55C",
R = "#ED553B"
),
language = get_AMR_locale(), language = get_AMR_locale(),
expand = TRUE, expand = TRUE,
include_PKPD = getOption("AMR_include_PKPD", TRUE), include_PKPD = getOption("AMR_include_PKPD", TRUE),
@@ -635,7 +669,7 @@ autoplot.mic <- function(object,
meet_criteria(title, allow_class = "character", allow_NULL = TRUE) meet_criteria(title, allow_class = "character", allow_NULL = TRUE)
meet_criteria(ylab, allow_class = "character", has_length = 1) meet_criteria(ylab, allow_class = "character", has_length = 1)
meet_criteria(xlab, allow_class = "character", has_length = 1) meet_criteria(xlab, allow_class = "character", has_length = 1)
meet_criteria(colours_SIR, allow_class = "character", has_length = c(1, 3)) meet_criteria(colours_SIR, allow_class = "character", has_length = c(1, 3, 4))
language <- validate_language(language) language <- validate_language(language)
meet_criteria(expand, allow_class = "logical", has_length = 1) meet_criteria(expand, allow_class = "logical", has_length = 1)
@@ -646,6 +680,8 @@ autoplot.mic <- function(object,
title <- gsub(" +", " ", paste0(title, collapse = " ")) title <- gsub(" +", " ", paste0(title, collapse = " "))
} }
colours_SIR <- expand_SIR_colours(colours_SIR)
object <- as.mic(object) # make sure that currently implemented MIC levels are used object <- as.mic(object) # make sure that currently implemented MIC levels are used
x <- plotrange_as_table(object, expand = expand) x <- plotrange_as_table(object, expand = expand)
cols_sub <- plot_colours_subtitle_guideline( cols_sub <- plot_colours_subtitle_guideline(
@@ -665,12 +701,14 @@ autoplot.mic <- function(object,
colnames(df) <- c("mic", "count") colnames(df) <- c("mic", "count")
df$cols <- cols_sub$cols df$cols <- cols_sub$cols
df$cols[df$cols == colours_SIR[1]] <- "(S) Susceptible" df$cols[df$cols == colours_SIR[1]] <- "(S) Susceptible"
df$cols[df$cols == colours_SIR[2]] <- paste("(I)", plot_name_of_I(cols_sub$guideline)) df$cols[df$cols == colours_SIR[2]] <- "(SDD) Susceptible dose-dependent"
df$cols[df$cols == colours_SIR[3]] <- "(R) Resistant" df$cols[df$cols == colours_SIR[3]] <- paste("(I)", plot_name_of_I(cols_sub$guideline))
df$cols[df$cols == colours_SIR[4]] <- "(R) Resistant"
df$cols <- factor(translate_into_language(df$cols, language = language), df$cols <- factor(translate_into_language(df$cols, language = language),
levels = translate_into_language( levels = translate_into_language(
c( c(
"(S) Susceptible", "(S) Susceptible",
"(SDD) Susceptible dose-dependent",
paste("(I)", plot_name_of_I(cols_sub$guideline)), paste("(I)", plot_name_of_I(cols_sub$guideline)),
"(R) Resistant" "(R) Resistant"
), ),
@@ -684,10 +722,10 @@ autoplot.mic <- function(object,
vals <- c( vals <- c(
"(S) Susceptible" = colours_SIR[1], "(S) Susceptible" = colours_SIR[1],
"(SDD) Susceptible dose-dependent" = colours_SIR[2], "(SDD) Susceptible dose-dependent" = colours_SIR[2],
"(I) Susceptible, incr. exp." = colours_SIR[2], "(I) Susceptible, incr. exp." = colours_SIR[3],
"(I) Intermediate" = colours_SIR[2], "(I) Intermediate" = colours_SIR[3],
"(R) Resistant" = colours_SIR[3], "(R) Resistant" = colours_SIR[4],
"(NI) Non-interpretable" = "grey" "(NI) Non-interpretable" = "grey30"
) )
names(vals) <- translate_into_language(names(vals), language = language) names(vals) <- translate_into_language(names(vals), language = language)
p <- p + p <- p +
@@ -731,7 +769,12 @@ plot.disk <- function(x,
mo = NULL, mo = NULL,
ab = NULL, ab = NULL,
guideline = getOption("AMR_guideline", "EUCAST"), guideline = getOption("AMR_guideline", "EUCAST"),
colours_SIR = c("#3CAEA3", "#F6D55C", "#ED553B"), colours_SIR = c(
S = "#3CAEA3",
SDD = "#8FD6C4",
I = "#F6D55C",
R = "#ED553B"
),
language = get_AMR_locale(), language = get_AMR_locale(),
expand = TRUE, expand = TRUE,
include_PKPD = getOption("AMR_include_PKPD", TRUE), include_PKPD = getOption("AMR_include_PKPD", TRUE),
@@ -743,14 +786,12 @@ plot.disk <- function(x,
meet_criteria(mo, allow_class = c("mo", "character"), allow_NULL = TRUE) meet_criteria(mo, allow_class = c("mo", "character"), allow_NULL = TRUE)
meet_criteria(ab, allow_class = c("ab", "character"), allow_NULL = TRUE) meet_criteria(ab, allow_class = c("ab", "character"), allow_NULL = TRUE)
meet_criteria(guideline, allow_class = "character", has_length = 1) meet_criteria(guideline, allow_class = "character", has_length = 1)
meet_criteria(colours_SIR, allow_class = "character", has_length = c(1, 3)) meet_criteria(colours_SIR, allow_class = "character", has_length = c(1, 3, 4))
language <- validate_language(language) language <- validate_language(language)
meet_criteria(expand, allow_class = "logical", has_length = 1) meet_criteria(expand, allow_class = "logical", has_length = 1)
if (length(colours_SIR) == 1) {
colours_SIR <- rep(colours_SIR, 3)
}
main <- gsub(" +", " ", paste0(main, collapse = " ")) main <- gsub(" +", " ", paste0(main, collapse = " "))
colours_SIR <- expand_SIR_colours(colours_SIR)
x <- plotrange_as_table(x, expand = expand) x <- plotrange_as_table(x, expand = expand)
cols_sub <- plot_colours_subtitle_guideline( cols_sub <- plot_colours_subtitle_guideline(
@@ -783,12 +824,16 @@ plot.disk <- function(x,
if (any(colours_SIR %in% cols_sub$cols)) { if (any(colours_SIR %in% cols_sub$cols)) {
legend_txt <- character(0) legend_txt <- character(0)
legend_col <- character(0) legend_col <- character(0)
if (any(cols_sub$cols == colours_SIR[3] & cols_sub$count > 0)) { if (any(cols_sub$cols == colours_SIR[4] & cols_sub$count > 0)) {
legend_txt <- "(R) Resistant" legend_txt <- "(R) Resistant"
legend_col <- colours_SIR[3] legend_col <- colours_SIR[4]
}
if (any(cols_sub$cols == colours_SIR[3] & cols_sub$count > 0)) {
legend_txt <- c(legend_txt, paste("(I)", plot_name_of_I(cols_sub$guideline)))
legend_col <- c(legend_col, colours_SIR[3])
} }
if (any(cols_sub$cols == colours_SIR[2] & cols_sub$count > 0)) { if (any(cols_sub$cols == colours_SIR[2] & cols_sub$count > 0)) {
legend_txt <- c(legend_txt, paste("(I)", plot_name_of_I(cols_sub$guideline))) legend_txt <- c(legend_txt, "(SDD) Susceptible dose-dependent")
legend_col <- c(legend_col, colours_SIR[2]) legend_col <- c(legend_col, colours_SIR[2])
} }
if (any(cols_sub$cols == colours_SIR[1] & cols_sub$count > 0)) { if (any(cols_sub$cols == colours_SIR[1] & cols_sub$count > 0)) {
@@ -818,7 +863,12 @@ barplot.disk <- function(height,
mo = NULL, mo = NULL,
ab = NULL, ab = NULL,
guideline = getOption("AMR_guideline", "EUCAST"), guideline = getOption("AMR_guideline", "EUCAST"),
colours_SIR = c("#3CAEA3", "#F6D55C", "#ED553B"), colours_SIR = c(
S = "#3CAEA3",
SDD = "#8FD6C4",
I = "#F6D55C",
R = "#ED553B"
),
language = get_AMR_locale(), language = get_AMR_locale(),
expand = TRUE, expand = TRUE,
...) { ...) {
@@ -828,7 +878,7 @@ barplot.disk <- function(height,
meet_criteria(mo, allow_class = c("mo", "character"), allow_NULL = TRUE) meet_criteria(mo, allow_class = c("mo", "character"), allow_NULL = TRUE)
meet_criteria(ab, allow_class = c("ab", "character"), allow_NULL = TRUE) meet_criteria(ab, allow_class = c("ab", "character"), allow_NULL = TRUE)
meet_criteria(guideline, allow_class = "character", has_length = 1) meet_criteria(guideline, allow_class = "character", has_length = 1)
meet_criteria(colours_SIR, allow_class = "character", has_length = c(1, 3)) meet_criteria(colours_SIR, allow_class = "character", has_length = c(1, 3, 4))
language <- validate_language(language) language <- validate_language(language)
meet_criteria(expand, allow_class = "logical", has_length = 1) meet_criteria(expand, allow_class = "logical", has_length = 1)
@@ -858,7 +908,12 @@ autoplot.disk <- function(object,
ylab = translate_AMR("Frequency", language = language), ylab = translate_AMR("Frequency", language = language),
xlab = translate_AMR("Disk diffusion diameter (mm)", language = language), xlab = translate_AMR("Disk diffusion diameter (mm)", language = language),
guideline = getOption("AMR_guideline", "EUCAST"), guideline = getOption("AMR_guideline", "EUCAST"),
colours_SIR = c("#3CAEA3", "#F6D55C", "#ED553B"), colours_SIR = c(
S = "#3CAEA3",
SDD = "#8FD6C4",
I = "#F6D55C",
R = "#ED553B"
),
language = get_AMR_locale(), language = get_AMR_locale(),
expand = TRUE, expand = TRUE,
include_PKPD = getOption("AMR_include_PKPD", TRUE), include_PKPD = getOption("AMR_include_PKPD", TRUE),
@@ -871,7 +926,7 @@ autoplot.disk <- function(object,
meet_criteria(mo, allow_class = c("mo", "character"), allow_NULL = TRUE) meet_criteria(mo, allow_class = c("mo", "character"), allow_NULL = TRUE)
meet_criteria(ab, allow_class = c("ab", "character"), allow_NULL = TRUE) meet_criteria(ab, allow_class = c("ab", "character"), allow_NULL = TRUE)
meet_criteria(guideline, allow_class = "character", has_length = 1) meet_criteria(guideline, allow_class = "character", has_length = 1)
meet_criteria(colours_SIR, allow_class = "character", has_length = c(1, 3)) meet_criteria(colours_SIR, allow_class = "character", has_length = c(1, 3, 4))
language <- validate_language(language) language <- validate_language(language)
meet_criteria(expand, allow_class = "logical", has_length = 1) meet_criteria(expand, allow_class = "logical", has_length = 1)
@@ -882,6 +937,8 @@ autoplot.disk <- function(object,
title <- gsub(" +", " ", paste0(title, collapse = " ")) title <- gsub(" +", " ", paste0(title, collapse = " "))
} }
colours_SIR <- expand_SIR_colours(colours_SIR)
x <- plotrange_as_table(object, expand = expand) x <- plotrange_as_table(object, expand = expand)
cols_sub <- plot_colours_subtitle_guideline( cols_sub <- plot_colours_subtitle_guideline(
x = x, x = x,
@@ -899,10 +956,10 @@ autoplot.disk <- function(object,
df <- as.data.frame(x, stringsAsFactors = TRUE) df <- as.data.frame(x, stringsAsFactors = TRUE)
colnames(df) <- c("disk", "count") colnames(df) <- c("disk", "count")
df$cols <- cols_sub$cols df$cols <- cols_sub$cols
df$cols[df$cols == colours_SIR[1]] <- "(S) Susceptible" df$cols[df$cols == colours_SIR[1]] <- "(S) Susceptible"
df$cols[df$cols == colours_SIR[2]] <- paste("(I)", plot_name_of_I(cols_sub$guideline)) df$cols[df$cols == colours_SIR[2]] <- "(SDD) Susceptible dose-dependent"
df$cols[df$cols == colours_SIR[3]] <- "(R) Resistant" df$cols[df$cols == colours_SIR[3]] <- paste("(I)", plot_name_of_I(cols_sub$guideline))
df$cols[df$cols == colours_SIR[4]] <- "(R) Resistant"
df$cols <- factor(translate_into_language(df$cols, language = language), df$cols <- factor(translate_into_language(df$cols, language = language),
levels = translate_into_language( levels = translate_into_language(
c( c(
@@ -920,10 +977,10 @@ autoplot.disk <- function(object,
vals <- c( vals <- c(
"(S) Susceptible" = colours_SIR[1], "(S) Susceptible" = colours_SIR[1],
"(SDD) Susceptible dose-dependent" = colours_SIR[2], "(SDD) Susceptible dose-dependent" = colours_SIR[2],
"(I) Susceptible, incr. exp." = colours_SIR[2], "(I) Susceptible, incr. exp." = colours_SIR[3],
"(I) Intermediate" = colours_SIR[2], "(I) Intermediate" = colours_SIR[3],
"(R) Resistant" = colours_SIR[3], "(R) Resistant" = colours_SIR[4],
"(NI) Non-interpretable" = "grey" "(NI) Non-interpretable" = "grey30"
) )
names(vals) <- translate_into_language(names(vals), language = language) names(vals) <- translate_into_language(names(vals), language = language)
p <- p + p <- p +
@@ -1024,22 +1081,26 @@ barplot.sir <- function(height,
main = deparse(substitute(height)), main = deparse(substitute(height)),
xlab = translate_AMR("Antimicrobial Interpretation", language = language), xlab = translate_AMR("Antimicrobial Interpretation", language = language),
ylab = translate_AMR("Frequency", language = language), ylab = translate_AMR("Frequency", language = language),
colours_SIR = c("#3CAEA3", "#F6D55C", "#ED553B"), colours_SIR = c(
S = "#3CAEA3",
SDD = "#8FD6C4",
I = "#F6D55C",
R = "#ED553B"
),
language = get_AMR_locale(), language = get_AMR_locale(),
expand = TRUE, expand = TRUE,
...) { ...) {
meet_criteria(xlab, allow_class = "character", has_length = 1) meet_criteria(xlab, allow_class = "character", has_length = 1)
meet_criteria(main, allow_class = "character", has_length = 1, allow_NULL = TRUE) meet_criteria(main, allow_class = "character", has_length = 1, allow_NULL = TRUE)
meet_criteria(ylab, allow_class = "character", has_length = 1) meet_criteria(ylab, allow_class = "character", has_length = 1)
meet_criteria(colours_SIR, allow_class = "character", has_length = c(1, 3)) meet_criteria(colours_SIR, allow_class = "character", has_length = c(1, 3, 4))
language <- validate_language(language) language <- validate_language(language)
meet_criteria(expand, allow_class = "logical", has_length = 1) meet_criteria(expand, allow_class = "logical", has_length = 1)
if (length(colours_SIR) == 1) { colours_SIR <- expand_SIR_colours(colours_SIR)
colours_SIR <- rep(colours_SIR, 3)
}
# add SDD and N to colours # add SDD and N to colours
colours_SIR <- c(colours_SIR[1:2], colours_SIR[2], colours_SIR[3], "#888888") colours_SIR <- c(colours_SIR, "grey30")
main <- gsub(" +", " ", paste0(main, collapse = " ")) main <- gsub(" +", " ", paste0(main, collapse = " "))
x <- table(height) x <- table(height)
@@ -1065,14 +1126,19 @@ autoplot.sir <- function(object,
title = deparse(substitute(object)), title = deparse(substitute(object)),
xlab = translate_AMR("Antimicrobial Interpretation", language = language), xlab = translate_AMR("Antimicrobial Interpretation", language = language),
ylab = translate_AMR("Frequency", language = language), ylab = translate_AMR("Frequency", language = language),
colours_SIR = c("#3CAEA3", "#F6D55C", "#ED553B"), colours_SIR = c(
S = "#3CAEA3",
SDD = "#8FD6C4",
I = "#F6D55C",
R = "#ED553B"
),
language = get_AMR_locale(), language = get_AMR_locale(),
...) { ...) {
stop_ifnot_installed("ggplot2") stop_ifnot_installed("ggplot2")
meet_criteria(title, allow_class = "character", allow_NULL = TRUE) meet_criteria(title, allow_class = "character", allow_NULL = TRUE)
meet_criteria(ylab, allow_class = "character", has_length = 1) meet_criteria(ylab, allow_class = "character", has_length = 1)
meet_criteria(xlab, allow_class = "character", has_length = 1) meet_criteria(xlab, allow_class = "character", has_length = 1)
meet_criteria(colours_SIR, allow_class = "character", has_length = c(1, 3)) meet_criteria(colours_SIR, allow_class = "character", has_length = c(1, 3, 4))
if ("main" %in% names(list(...))) { if ("main" %in% names(list(...))) {
title <- list(...)$main title <- list(...)$main
@@ -1081,9 +1147,7 @@ autoplot.sir <- function(object,
title <- gsub(" +", " ", paste0(title, collapse = " ")) title <- gsub(" +", " ", paste0(title, collapse = " "))
} }
if (length(colours_SIR) == 1) { colours_SIR <- expand_SIR_colours(colours_SIR)
colours_SIR <- rep(colours_SIR, 3)
}
df <- as.data.frame(table(object), stringsAsFactors = TRUE) df <- as.data.frame(table(object), stringsAsFactors = TRUE)
colnames(df) <- c("x", "n") colnames(df) <- c("x", "n")
@@ -1095,9 +1159,9 @@ autoplot.sir <- function(object,
values = c( values = c(
"S" = colours_SIR[1], "S" = colours_SIR[1],
"SDD" = colours_SIR[2], "SDD" = colours_SIR[2],
"I" = colours_SIR[2], "I" = colours_SIR[3],
"R" = colours_SIR[3], "R" = colours_SIR[4],
"NI" = "#888888" "NI" = "grey30"
), ),
limits = force limits = force
) + ) +
@@ -1223,9 +1287,9 @@ plot_colours_subtitle_guideline <- function(x, mo, ab, guideline, colours_SIR, f
cols[is.na(sir)] <- "#BEBEBE" cols[is.na(sir)] <- "#BEBEBE"
cols[sir == "S"] <- colours_SIR[1] cols[sir == "S"] <- colours_SIR[1]
cols[sir == "SDD"] <- colours_SIR[2] cols[sir == "SDD"] <- colours_SIR[2]
cols[sir == "I"] <- colours_SIR[2] cols[sir == "I"] <- colours_SIR[3]
cols[sir == "R"] <- colours_SIR[3] cols[sir == "R"] <- colours_SIR[4]
cols[sir == "NI"] <- "#888888" cols[sir == "NI"] <- "grey30"
sub <- bquote(.(abname) ~ "-" ~ italic(.(moname)) ~ .(guideline_txt)) sub <- bquote(.(abname) ~ "-" ~ italic(.(moname)) ~ .(guideline_txt))
} else { } else {
cols <- "#BEBEBE" cols <- "#BEBEBE"
@@ -1284,10 +1348,15 @@ scale_y_percent <- function(breaks = function(x) seq(0, max(x, na.rm = TRUE), 0.
#' @export #' @export
scale_sir_colours <- function(..., scale_sir_colours <- function(...,
aesthetics, aesthetics,
colours_SIR = c("#3CAEA3", "#F6D55C", "#ED553B")) { colours_SIR = c(
S = "#3CAEA3",
SDD = "#8FD6C4",
I = "#F6D55C",
R = "#ED553B"
)) {
stop_ifnot_installed("ggplot2") stop_ifnot_installed("ggplot2")
meet_criteria(aesthetics, allow_class = "character", is_in = c("alpha", "colour", "color", "fill", "linetype", "shape", "size")) meet_criteria(aesthetics, allow_class = "character", is_in = c("alpha", "colour", "color", "fill", "linetype", "shape", "size"))
meet_criteria(colours_SIR, allow_class = "character", has_length = c(1, 3)) meet_criteria(colours_SIR, allow_class = "character", has_length = c(1, 3, 4))
if ("fill" %in% aesthetics && message_not_thrown_before("scale_sir_colours", "fill", entire_session = TRUE)) { if ("fill" %in% aesthetics && message_not_thrown_before("scale_sir_colours", "fill", entire_session = TRUE)) {
warning_("Using `scale_sir_colours()` for the `fill` aesthetic has been superseded by `scale_fill_sir()`, please use that instead. This warning will be shown once per session.") warning_("Using `scale_sir_colours()` for the `fill` aesthetic has been superseded by `scale_fill_sir()`, please use that instead. This warning will be shown once per session.")
@@ -1296,67 +1365,48 @@ scale_sir_colours <- function(...,
warning_("Using `scale_sir_colours()` for the `colour` aesthetic has been superseded by `scale_colour_sir()`, please use that instead. This warning will be shown once per session.") warning_("Using `scale_sir_colours()` for the `colour` aesthetic has been superseded by `scale_colour_sir()`, please use that instead. This warning will be shown once per session.")
} }
if (length(colours_SIR) == 1) {
colours_SIR <- rep(colours_SIR, 3)
}
# behaviour until AMR pkg v1.5.0 and also when coming from ggplot_sir()
if ("colours" %in% names(list(...))) { if ("colours" %in% names(list(...))) {
original_cols <- c( colours_SIR <- list(...)$colours
S = colours_SIR[1], }
SI = colours_SIR[1],
I = colours_SIR[2], colours_SIR <- expand_SIR_colours(colours_SIR, unname = FALSE)
IR = colours_SIR[3],
R = colours_SIR[3] # behaviour when coming from ggplot_sir()
) if ("colours" %in% names(list(...))) {
colours <- replace(original_cols, names(list(...)$colours), list(...)$colours)
# limits = force is needed in ggplot2 3.3.4 and 3.3.5, see here; # limits = force is needed in ggplot2 3.3.4 and 3.3.5, see here;
# https://github.com/tidyverse/ggplot2/issues/4511#issuecomment-866185530 # https://github.com/tidyverse/ggplot2/issues/4511#issuecomment-866185530
return(ggplot2::scale_fill_manual(values = colours, limits = force, aesthetics = aesthetics)) return(ggplot2::scale_fill_manual(values = colours_SIR, limits = force, aesthetics = aesthetics))
} }
if (identical(unlist(list(...)), FALSE)) { if (identical(unlist(list(...)), FALSE)) {
return(invisible()) return(invisible())
} }
names_susceptible <- c( colours_SIR <- unname(colours_SIR)
"S", "SI", "IS", "S+I", "I+S", "susceptible", "Susceptible",
unique(TRANSLATIONS[which(TRANSLATIONS$pattern == "Susceptible"), names_susceptible <- c("S", "SI", "IS", "S+I", "I+S", "susceptible", "Susceptible")
"replacement", names_susceptible_dose_dep <- c("SDD", "susceptible dose-dependent", "Susceptible dose-dependent")
drop = TRUE
])
)
names_incr_exposure <- c( names_incr_exposure <- c(
"I", "intermediate", "increased exposure", "incr. exposure", "I", "intermediate", "increased exposure", "incr. exposure",
"Increased exposure", "Incr. exposure", "Susceptible, incr. exp.", "Increased exposure", "Incr. exposure", "Susceptible, incr. exp."
unique(TRANSLATIONS[which(TRANSLATIONS$pattern == "Intermediate"),
"replacement",
drop = TRUE
]),
unique(TRANSLATIONS[which(TRANSLATIONS$pattern == "Susceptible, incr. exp."),
"replacement",
drop = TRUE
])
)
names_resistant <- c(
"R", "IR", "RI", "R+I", "I+R", "resistant", "Resistant",
unique(TRANSLATIONS[which(TRANSLATIONS$pattern == "Resistant"),
"replacement",
drop = TRUE
])
) )
names_resistant <- c("R", "IR", "RI", "R+I", "I+R", "resistant", "Resistant")
susceptible <- rep(colours_SIR[1], length(names_susceptible)) susceptible <- rep(colours_SIR[1], length(names_susceptible))
names(susceptible) <- names_susceptible names(susceptible) <- names_susceptible
incr_exposure <- rep(colours_SIR[2], length(names_incr_exposure)) susceptible_dose_dep <- rep(colours_SIR[2], length(names_susceptible_dose_dep))
names(susceptible_dose_dep) <- names_susceptible_dose_dep
incr_exposure <- rep(colours_SIR[3], length(names_incr_exposure))
names(incr_exposure) <- names_incr_exposure names(incr_exposure) <- names_incr_exposure
resistant <- rep(colours_SIR[3], length(names_resistant)) resistant <- rep(colours_SIR[4], length(names_resistant))
names(resistant) <- names_resistant names(resistant) <- names_resistant
original_cols <- c(susceptible, incr_exposure, resistant) original_cols <- c(susceptible, susceptible_dose_dep, incr_exposure, resistant)
dots <- c(...) dots <- c(...)
# replace S, I, R as colours: scale_sir_colours(mydatavalue = "S") # replace S, SDD, I, R as colours: scale_sir_colours(mydatavalue = "S")
dots[dots == "S"] <- colours_SIR[1] dots[dots == "S"] <- colours_SIR[1]
dots[dots == "I"] <- colours_SIR[2] dots[dots == "SDD"] <- colours_SIR[2]
dots[dots == "R"] <- colours_SIR[3] dots[dots == "I"] <- colours_SIR[3]
dots[dots == "R"] <- colours_SIR[4]
cols <- replace(original_cols, names(dots), dots) cols <- replace(original_cols, names(dots), dots)
# limits = force is needed in ggplot2 3.3.4 and 3.3.5, see here; # limits = force is needed in ggplot2 3.3.4 and 3.3.5, see here;
# https://github.com/tidyverse/ggplot2/issues/4511#issuecomment-866185530 # https://github.com/tidyverse/ggplot2/issues/4511#issuecomment-866185530
@@ -1435,3 +1485,39 @@ labels_sir_count <- function(position = NULL,
} }
) )
} }
expand_SIR_colours <- function(colours_SIR, unname = TRUE) {
sir_order <- c("S", "SDD", "I", "R", "SI", "IR")
if (is.null(names(colours_SIR))) {
if (length(colours_SIR) == 1) {
colours_SIR <- rep(colours_SIR, 4)
} else if (length(colours_SIR) == 3) {
# old method for AMR < 3.0.1 which allowed for 3 colours
# fill in green for SDD as extra colour
colours_SIR <- c(colours_SIR[1], colours_SIR[1], colours_SIR[2], colours_SIR[3])
}
if (length(colours_SIR) == 4) {
# add colours for SI (same as S) and IR (same as R)
colours_SIR <- c(colours_SIR[1:4], colours_SIR[1], colours_SIR[4])
}
names(colours_SIR) <- sir_order
} else {
# named input: match and reorder
stop_ifnot(
all(names(colours_SIR) %in% sir_order),
"Unknown names in `colours_SIR`. Expected any of: ", vector_or(levels(NA_sir_), quotes = FALSE, sort = FALSE), "."
)
if (length(colours_SIR) == 4) {
# add colours for SI (same as S) and IR (same as R)
colours_SIR <- c(colours_SIR[1:4], SI = unname(colours_SIR[1]), IR = unname(colours_SIR[4]))
}
colours_SIR <- colours_SIR[sir_order]
}
if (unname) {
colours_SIR <- unname(colours_SIR)
}
return(colours_SIR)
}

View File

@@ -237,7 +237,7 @@ resistance <- function(...,
only_all_tested = only_all_tested, only_all_tested = only_all_tested,
only_count = FALSE only_count = FALSE
), ),
error = function(e) stop_(gsub("in sir_calc(): ", "", e$message, fixed = TRUE), call = -5) error = function(e) stop_(gsub("in sir_calc(): ", "", conditionMessage(e), fixed = TRUE), call = -5)
) )
} }
@@ -255,7 +255,7 @@ susceptibility <- function(...,
only_all_tested = only_all_tested, only_all_tested = only_all_tested,
only_count = FALSE only_count = FALSE
), ),
error = function(e) stop_(gsub("in sir_calc(): ", "", e$message, fixed = TRUE), call = -5) error = function(e) stop_(gsub("in sir_calc(): ", "", conditionMessage(e), fixed = TRUE), call = -5)
) )
} }
@@ -283,7 +283,7 @@ sir_confidence_interval <- function(...,
only_all_tested = only_all_tested, only_all_tested = only_all_tested,
only_count = TRUE only_count = TRUE
), ),
error = function(e) stop_(gsub("in sir_calc(): ", "", e$message, fixed = TRUE), call = -5) error = function(e) stop_(gsub("in sir_calc(): ", "", conditionMessage(e), fixed = TRUE), call = -5)
) )
n <- tryCatch( n <- tryCatch(
sir_calc(..., sir_calc(...,
@@ -291,7 +291,7 @@ sir_confidence_interval <- function(...,
only_all_tested = only_all_tested, only_all_tested = only_all_tested,
only_count = TRUE only_count = TRUE
), ),
error = function(e) stop_(gsub("in sir_calc(): ", "", e$message, fixed = TRUE), call = -5) error = function(e) stop_(gsub("in sir_calc(): ", "", conditionMessage(e), fixed = TRUE), call = -5)
) )
if (x == 0) { if (x == 0) {
@@ -347,7 +347,7 @@ proportion_R <- function(...,
only_all_tested = only_all_tested, only_all_tested = only_all_tested,
only_count = FALSE only_count = FALSE
), ),
error = function(e) stop_(gsub("in sir_calc(): ", "", e$message, fixed = TRUE), call = -5) error = function(e) stop_(gsub("in sir_calc(): ", "", conditionMessage(e), fixed = TRUE), call = -5)
) )
} }
@@ -365,7 +365,7 @@ proportion_IR <- function(...,
only_all_tested = only_all_tested, only_all_tested = only_all_tested,
only_count = FALSE only_count = FALSE
), ),
error = function(e) stop_(gsub("in sir_calc(): ", "", e$message, fixed = TRUE), call = -5) error = function(e) stop_(gsub("in sir_calc(): ", "", conditionMessage(e), fixed = TRUE), call = -5)
) )
} }
@@ -383,7 +383,7 @@ proportion_I <- function(...,
only_all_tested = only_all_tested, only_all_tested = only_all_tested,
only_count = FALSE only_count = FALSE
), ),
error = function(e) stop_(gsub("in sir_calc(): ", "", e$message, fixed = TRUE), call = -5) error = function(e) stop_(gsub("in sir_calc(): ", "", conditionMessage(e), fixed = TRUE), call = -5)
) )
} }
@@ -401,7 +401,7 @@ proportion_SI <- function(...,
only_all_tested = only_all_tested, only_all_tested = only_all_tested,
only_count = FALSE only_count = FALSE
), ),
error = function(e) stop_(gsub("in sir_calc(): ", "", e$message, fixed = TRUE), call = -5) error = function(e) stop_(gsub("in sir_calc(): ", "", conditionMessage(e), fixed = TRUE), call = -5)
) )
} }
@@ -419,7 +419,7 @@ proportion_S <- function(...,
only_all_tested = only_all_tested, only_all_tested = only_all_tested,
only_count = FALSE only_count = FALSE
), ),
error = function(e) stop_(gsub("in sir_calc(): ", "", e$message, fixed = TRUE), call = -5) error = function(e) stop_(gsub("in sir_calc(): ", "", conditionMessage(e), fixed = TRUE), call = -5)
) )
} }
@@ -443,6 +443,6 @@ proportion_df <- function(data,
combine_SI = combine_SI, combine_SI = combine_SI,
confidence_level = confidence_level confidence_level = confidence_level
), ),
error = function(e) stop_(gsub("in sir_calc_df(): ", "", e$message, fixed = TRUE), call = -5) error = function(e) stop_(gsub("in sir_calc_df(): ", "", conditionMessage(e), fixed = TRUE), call = -5)
) )
} }

View File

@@ -31,13 +31,17 @@
#' #'
#' These functions can be used for generating random MIC values and disk diffusion diameters, for AMR data analysis practice. By providing a microorganism and antimicrobial drug, the generated results will reflect reality as much as possible. #' These functions can be used for generating random MIC values and disk diffusion diameters, for AMR data analysis practice. By providing a microorganism and antimicrobial drug, the generated results will reflect reality as much as possible.
#' @param size Desired size of the returned vector. If used in a [data.frame] call or `dplyr` verb, will get the current (group) size if left blank. #' @param size Desired size of the returned vector. If used in a [data.frame] call or `dplyr` verb, will get the current (group) size if left blank.
#' @param mo Any [character] that can be coerced to a valid microorganism code with [as.mo()]. #' @param mo Any [character] that can be coerced to a valid microorganism code with [as.mo()]. Can be the same length as `size`.
#' @param ab Any [character] that can be coerced to a valid antimicrobial drug code with [as.ab()]. #' @param ab Any [character] that can be coerced to a valid antimicrobial drug code with [as.ab()].
#' @param prob_SIR A vector of length 3: the probabilities for "S" (1st value), "I" (2nd value) and "R" (3rd value). #' @param prob_SIR A vector of length 3: the probabilities for "S" (1st value), "I" (2nd value) and "R" (3rd value).
#' @param skew Direction of skew for MIC or disk values, either `"right"` or `"left"`. A left-skewed distribution has the majority of the data on the right.
#' @param severity Skew severity; higher values will increase the skewedness. Default is `2`; use `0` to prevent skewedness.
#' @param ... Ignored, only in place to allow future extensions. #' @param ... Ignored, only in place to allow future extensions.
#' @details The base \R function [sample()] is used for generating values. #' @details
#' #' Internally, MIC and disk zone values are sampled based on clinical breakpoints defined in the [clinical_breakpoints] data set. To create specific generated values per bug or drug, set the `mo` and/or `ab` argument. The MICs are sampled on a log2 scale and disks linearly, using weighted probabilities. The weights are based on the `skew` and `severity` arguments:
#' Generated values are based on the EUCAST `r max(as.integer(gsub("[^0-9]", "", subset(clinical_breakpoints, guideline %like% "EUCAST")$guideline)))` guideline as implemented in the [clinical_breakpoints] data set. To create specific generated values per bug or drug, set the `mo` and/or `ab` argument. #' * `skew = "right"` places more emphasis on lower MIC or higher disk values.
#' * `skew = "left"` places more emphasis on higher MIC or lower disk values.
#' * `severity` controls the exponential bias applied.
#' @return class `mic` for [random_mic()] (see [as.mic()]) and class `disk` for [random_disk()] (see [as.disk()]) #' @return class `mic` for [random_mic()] (see [as.mic()]) and class `disk` for [random_disk()] (see [as.disk()])
#' @name random #' @name random
#' @rdname random #' @rdname random
@@ -47,8 +51,13 @@
#' random_disk(25) #' random_disk(25)
#' random_sir(25) #' random_sir(25)
#' #'
#' # add more skewedness, make more realistic by setting a bug and/or drug:
#' disks <- random_disk(100, severity = 2, mo = "Escherichia coli", ab = "CIP")
#' plot(disks)
#' # `plot()` and `ggplot2::autoplot()` allow for coloured bars if `mo` and `ab` are set
#' plot(disks, mo = "Escherichia coli", ab = "CIP", guideline = "CLSI 2025")
#'
#' \donttest{ #' \donttest{
#' # make the random generation more realistic by setting a bug and/or drug:
#' random_mic(25, "Klebsiella pneumoniae") # range 0.0625-64 #' random_mic(25, "Klebsiella pneumoniae") # range 0.0625-64
#' random_mic(25, "Klebsiella pneumoniae", "meropenem") # range 0.0625-16 #' random_mic(25, "Klebsiella pneumoniae", "meropenem") # range 0.0625-16
#' random_mic(25, "Streptococcus pneumoniae", "meropenem") # range 0.0625-4 #' random_mic(25, "Streptococcus pneumoniae", "meropenem") # range 0.0625-4
@@ -57,26 +66,61 @@
#' random_disk(25, "Klebsiella pneumoniae", "ampicillin") # range 11-17 #' random_disk(25, "Klebsiella pneumoniae", "ampicillin") # range 11-17
#' random_disk(25, "Streptococcus pneumoniae", "ampicillin") # range 12-27 #' random_disk(25, "Streptococcus pneumoniae", "ampicillin") # range 12-27
#' } #' }
random_mic <- function(size = NULL, mo = NULL, ab = NULL, ...) { random_mic <- function(size = NULL, mo = NULL, ab = NULL, skew = "right", severity = 1, ...) {
meet_criteria(size, allow_class = c("numeric", "integer"), has_length = 1, is_positive = TRUE, is_finite = TRUE, allow_NULL = TRUE) meet_criteria(size, allow_class = c("numeric", "integer"), has_length = 1, is_positive = TRUE, is_finite = TRUE, allow_NULL = TRUE)
meet_criteria(mo, allow_class = "character", has_length = 1, allow_NULL = TRUE) meet_criteria(mo, allow_class = "character", has_length = c(1, size), allow_NULL = TRUE)
meet_criteria(ab, allow_class = "character", has_length = 1, allow_NULL = TRUE) meet_criteria(ab, allow_class = "character", has_length = 1, allow_NULL = TRUE)
meet_criteria(skew, allow_class = "character", is_in = c("right", "left"), has_length = 1)
meet_criteria(severity, allow_class = c("numeric", "integer"), has_length = 1, is_positive_or_zero = TRUE, is_finite = TRUE)
if (is.null(size)) { if (is.null(size)) {
size <- NROW(get_current_data(arg_name = "size", call = -3)) size <- NROW(get_current_data(arg_name = "size", call = -3))
} }
random_exec("MIC", size = size, mo = mo, ab = ab) if (length(mo) > 1) {
out <- rep(NA_mic_, length(size))
p <- progress_ticker(n = length(unique(mo)), n_min = 10, title = "Generating random MIC values")
for (mo_ in unique(mo)) {
p$tick()
out[which(mo == mo_)] <- random_exec("MIC", size = sum(mo == mo_), mo = mo_, ab = ab, skew = skew, severity = severity)
}
out <- as.mic(out, keep_operators = "none")
if (stats::runif(1) > 0.5 && length(unique(out)) > 1) {
out[out == min(out)] <- paste0("<=", out[out == min(out)])
}
if (stats::runif(1) > 0.5 && length(unique(out)) > 1) {
out[out == max(out) & out %unlike% "<="] <- paste0(">=", out[out == max(out) & out %unlike% "<="])
}
return(out)
} else {
random_exec("MIC", size = size, mo = mo, ab = ab, skew = skew, severity = severity)
}
} }
#' @rdname random #' @rdname random
#' @export #' @export
random_disk <- function(size = NULL, mo = NULL, ab = NULL, ...) { random_disk <- function(size = NULL, mo = NULL, ab = NULL, skew = "left", severity = 1, ...) {
meet_criteria(size, allow_class = c("numeric", "integer"), has_length = 1, is_positive = TRUE, is_finite = TRUE, allow_NULL = TRUE) meet_criteria(size, allow_class = c("numeric", "integer"), has_length = 1, is_positive = TRUE, is_finite = TRUE, allow_NULL = TRUE)
meet_criteria(mo, allow_class = "character", has_length = 1, allow_NULL = TRUE) meet_criteria(mo, allow_class = "character", has_length = c(1, size), allow_NULL = TRUE)
meet_criteria(ab, allow_class = "character", has_length = 1, allow_NULL = TRUE) meet_criteria(ab, allow_class = "character", has_length = 1, allow_NULL = TRUE)
meet_criteria(skew, allow_class = "character", is_in = c("right", "left"), has_length = 1)
meet_criteria(severity, allow_class = c("numeric", "integer"), has_length = 1, is_positive_or_zero = TRUE, is_finite = TRUE)
if (is.null(size)) { if (is.null(size)) {
size <- NROW(get_current_data(arg_name = "size", call = -3)) size <- NROW(get_current_data(arg_name = "size", call = -3))
} }
random_exec("DISK", size = size, mo = mo, ab = ab) if (length(mo) > 1) {
out <- rep(NA_mic_, length(size))
p <- progress_ticker(n = length(unique(mo)), n_min = 10, title = "Generating random MIC values")
for (mo_ in unique(mo)) {
p$tick()
out[which(mo == mo_)] <- random_exec("DISK", size = sum(mo == mo_), mo = mo_, ab = ab, skew = skew, severity = severity)
}
out <- as.disk(out)
return(out)
} else {
random_exec("DISK", size = size, mo = mo, ab = ab, skew = skew, severity = severity)
}
} }
#' @rdname random #' @rdname random
@@ -90,78 +134,60 @@ random_sir <- function(size = NULL, prob_SIR = c(0.33, 0.33, 0.33), ...) {
sample(as.sir(c("S", "I", "R")), size = size, replace = TRUE, prob = prob_SIR) sample(as.sir(c("S", "I", "R")), size = size, replace = TRUE, prob = prob_SIR)
} }
random_exec <- function(method_type, size, mo = NULL, ab = NULL) {
df <- AMR::clinical_breakpoints %pm>% random_exec <- function(method_type, size, mo = NULL, ab = NULL, skew = "right", severity = 1) {
pm_filter(guideline %like% "EUCAST") %pm>% df <- AMR::clinical_breakpoints %pm>% subset(method == method_type & type == "human")
pm_arrange(pm_desc(guideline)) %pm>%
subset(guideline == max(guideline) &
method == method_type &
type == "human")
if (!is.null(mo)) { if (!is.null(mo)) {
mo_coerced <- as.mo(mo) mo_coerced <- as.mo(mo, info = FALSE)
mo_include <- c( mo_include <- c(mo_coerced, as.mo(mo_genus(mo_coerced)), as.mo(mo_family(mo_coerced)), as.mo(mo_order(mo_coerced)))
mo_coerced, df_new <- df %pm>% subset(mo %in% mo_include)
as.mo(mo_genus(mo_coerced)), if (nrow(df_new) > 0) df <- df_new
as.mo(mo_family(mo_coerced)),
as.mo(mo_order(mo_coerced))
)
df_new <- df %pm>%
subset(mo %in% mo_include)
if (nrow(df_new) > 0) {
df <- df_new
} else {
warning_("in `random_", tolower(method_type), "()`: no rows found that match mo '", mo, "', ignoring argument `mo`")
}
} }
if (!is.null(ab)) { if (!is.null(ab)) {
ab_coerced <- as.ab(ab) ab_coerced <- as.ab(ab)
df_new <- df %pm>% df_new <- df %pm>% subset(ab %in% ab_coerced)
subset(ab %in% ab_coerced) if (nrow(df_new) > 0) df <- df_new
if (nrow(df_new) > 0) {
df <- df_new
} else {
warning_("in `random_", tolower(method_type), "()`: no rows found that match ab '", ab, "' (", ab_name(ab_coerced, tolower = TRUE, language = NULL), "), ignoring argument `ab`")
}
} }
if (method_type == "MIC") { if (method_type == "MIC") {
# set range lowest_mic <- min(df$breakpoint_S, na.rm = TRUE)
mic_range <- c(0.001, 0.002, 0.005, 0.010, 0.025, 0.0625, 0.125, 0.250, 0.5, 1, 2, 4, 8, 16, 32, 64, 128, 256) lowest_mic <- log2(lowest_mic) + sample(c(-3:2), 1)
lowest_mic <- 2^lowest_mic
highest_mic <- max(df$breakpoint_R, na.rm = TRUE)
highest_mic <- log2(highest_mic) + sample(c(-3:1), 1)
highest_mic <- max(lowest_mic * 2, 2^highest_mic)
# get highest/lowest +/- random 1 to 3 higher factors of two out <- skewed_values(COMMON_MIC_VALUES, size = size, min = lowest_mic, max = highest_mic, skew = skew, severity = severity)
max_range <- mic_range[min(
length(mic_range),
which(mic_range == max(df$breakpoint_R[!is.na(df$breakpoint_R)], na.rm = TRUE)) + sample(c(1:3), 1)
)]
min_range <- mic_range[max(
1,
which(mic_range == min(df$breakpoint_S, na.rm = TRUE)) - sample(c(1:3), 1)
)]
mic_range_new <- mic_range[mic_range <= max_range & mic_range >= min_range]
if (length(mic_range_new) == 0) {
mic_range_new <- mic_range
}
out <- as.mic(sample(mic_range_new, size = size, replace = TRUE))
# 50% chance that lowest will get <= and highest will get >=
if (stats::runif(1) > 0.5 && length(unique(out)) > 1) { if (stats::runif(1) > 0.5 && length(unique(out)) > 1) {
out[out == min(out)] <- paste0("<=", out[out == min(out)]) out[out == min(out)] <- paste0("<=", out[out == min(out)])
} }
if (stats::runif(1) > 0.5 && length(unique(out)) > 1) { if (stats::runif(1) > 0.5 && length(unique(out)) > 1) {
out[out == max(out)] <- paste0(">=", out[out == max(out)]) out[out == max(out) & out %unlike% "<="] <- paste0(">=", out[out == max(out) & out %unlike% "<="])
} }
return(out) return(as.mic(out))
} else if (method_type == "DISK") { } else if (method_type == "DISK") {
set_range <- seq( disk_range <- seq(
from = as.integer(min(df$breakpoint_R[!is.na(df$breakpoint_R)], na.rm = TRUE) / 1.25), from = floor(min(df$breakpoint_R[!is.na(df$breakpoint_R)], na.rm = TRUE) / 1.25),
to = as.integer(max(df$breakpoint_S, na.rm = TRUE) * 1.25), to = ceiling(max(df$breakpoint_S[df$breakpoint_S != 50], na.rm = TRUE) * 1.25),
by = 1 by = 1
) )
out <- sample(set_range, size = size, replace = TRUE) disk_range <- disk_range[disk_range >= 6 & disk_range <= 50]
out[out < 6] <- sample(c(6:10), length(out[out < 6]), replace = TRUE) out <- skewed_values(disk_range, size = size, min = min(disk_range), max = max(disk_range), skew = skew, severity = severity)
out[out > 50] <- sample(c(40:50), length(out[out > 50]), replace = TRUE)
return(as.disk(out)) return(as.disk(out))
} }
} }
skewed_values <- function(values, size, min, max, skew = c("right", "left"), severity = 1) {
skew <- match.arg(skew)
range_vals <- values[values >= min & values <= max]
if (length(range_vals) < 2) range_vals <- values
ranks <- seq_along(range_vals)
weights <- switch(skew,
right = rev(ranks)^severity,
left = ranks^severity
)
weights <- weights / sum(weights)
sample(range_vals, size = size, replace = TRUE, prob = weights)
}

98
R/sir.R
View File

@@ -69,7 +69,9 @@
#' @param reference_data A [data.frame] to be used for interpretation, which defaults to the [clinical_breakpoints] data set. Changing this argument allows for using own interpretation guidelines. This argument must contain a data set that is equal in structure to the [clinical_breakpoints] data set (same column names and column types). Please note that the `guideline` argument will be ignored when `reference_data` is manually set. #' @param reference_data A [data.frame] to be used for interpretation, which defaults to the [clinical_breakpoints] data set. Changing this argument allows for using own interpretation guidelines. This argument must contain a data set that is equal in structure to the [clinical_breakpoints] data set (same column names and column types). Please note that the `guideline` argument will be ignored when `reference_data` is manually set.
#' @param threshold Maximum fraction of invalid antimicrobial interpretations of `x`, see *Examples*. #' @param threshold Maximum fraction of invalid antimicrobial interpretations of `x`, see *Examples*.
#' @param conserve_capped_values Deprecated, use `capped_mic_handling` instead. #' @param conserve_capped_values Deprecated, use `capped_mic_handling` instead.
#' @param ... For using on a [data.frame]: names of columns to apply [as.sir()] on (supports tidy selection such as `column1:column4`). Otherwise: arguments passed on to methods. #' @param ... For using on a [data.frame]: selection of columns to apply `as.sir()` to. Supports [tidyselect language][tidyselect::starts_with()] such as `where(is.mic)`, `starts_with(...)`, or `column1:column4`, and can thus also be [antimicrobial selectors][amr_selector()] such as `as.sir(df, penicillins())`.
#'
#' Otherwise: arguments passed on to methods.
#' @details #' @details
#' *Note: The clinical breakpoints in this package were validated through, and imported from, [WHONET](https://whonet.org). The public use of this `AMR` package has been endorsed by both CLSI and EUCAST. See [clinical_breakpoints] for more information.* #' *Note: The clinical breakpoints in this package were validated through, and imported from, [WHONET](https://whonet.org). The public use of this `AMR` package has been endorsed by both CLSI and EUCAST. See [clinical_breakpoints] for more information.*
#' #'
@@ -225,9 +227,12 @@
#' df_wide %>% mutate_if(is.mic, as.sir) #' df_wide %>% mutate_if(is.mic, as.sir)
#' df_wide %>% mutate_if(function(x) is.mic(x) | is.disk(x), as.sir) #' df_wide %>% mutate_if(function(x) is.mic(x) | is.disk(x), as.sir)
#' df_wide %>% mutate(across(where(is.mic), as.sir)) #' df_wide %>% mutate(across(where(is.mic), as.sir))
#'
#' df_wide %>% mutate_at(vars(amoxicillin:tobra), as.sir) #' df_wide %>% mutate_at(vars(amoxicillin:tobra), as.sir)
#' df_wide %>% mutate(across(amoxicillin:tobra, as.sir)) #' df_wide %>% mutate(across(amoxicillin:tobra, as.sir))
#' #'
#' df_wide %>% mutate(across(aminopenicillins(), as.sir))
#'
#' # approaches that all work with additional arguments: #' # approaches that all work with additional arguments:
#' df_long %>% #' df_long %>%
#' # given a certain data type, e.g. MIC values #' # given a certain data type, e.g. MIC values
@@ -722,8 +727,17 @@ as.sir.data.frame <- function(x,
meet_criteria(info, allow_class = "logical", has_length = 1) meet_criteria(info, allow_class = "logical", has_length = 1)
meet_criteria(parallel, allow_class = "logical", has_length = 1) meet_criteria(parallel, allow_class = "logical", has_length = 1)
meet_criteria(max_cores, allow_class = c("numeric", "integer"), has_length = 1) meet_criteria(max_cores, allow_class = c("numeric", "integer"), has_length = 1)
x.bak <- x x.bak <- x
if (tryCatch(length(list(...)) > 0, error = function(e) TRUE)) {
sel <- colnames(pm_select(x, ...))
} else {
sel <- colnames(x)
}
if (!is.null(col_mo)) {
sel <- sel[sel != col_mo]
}
for (i in seq_len(ncol(x))) { for (i in seq_len(ncol(x))) {
# don't keep factors, overwriting them is hard # don't keep factors, overwriting them is hard
if (is.factor(x[, i, drop = TRUE])) { if (is.factor(x[, i, drop = TRUE])) {
@@ -803,15 +817,6 @@ as.sir.data.frame <- function(x,
} }
i <- 0 i <- 0
if (tryCatch(length(list(...)) > 0, error = function(e) TRUE)) {
sel <- colnames(pm_select(x, ...))
} else {
sel <- colnames(x)
}
if (!is.null(col_mo)) {
sel <- sel[sel != col_mo]
}
ab_cols <- colnames(x)[vapply(FUN.VALUE = logical(1), x, function(y) { ab_cols <- colnames(x)[vapply(FUN.VALUE = logical(1), x, function(y) {
i <<- i + 1 i <<- i + 1
check <- is.mic(y) | is.disk(y) check <- is.mic(y) | is.disk(y)
@@ -863,7 +868,7 @@ as.sir.data.frame <- function(x,
cl <- tryCatch(parallel::makeCluster(n_cores, type = "PSOCK"), cl <- tryCatch(parallel::makeCluster(n_cores, type = "PSOCK"),
error = function(e) { error = function(e) {
if (isTRUE(info)) { if (isTRUE(info)) {
message_("Could not create parallel cluster, using single-core computation. Error message: ", e$message, add_fn = font_red) message_("Could not create parallel cluster, using single-core computation. Error message: ", conditionMessage(e), add_fn = font_red)
} }
return(NULL) return(NULL)
} }
@@ -1135,7 +1140,6 @@ as_sir_method <- function(method_short,
current_sir_interpretation_history <- NROW(AMR_env$sir_interpretation_history) current_sir_interpretation_history <- NROW(AMR_env$sir_interpretation_history)
if (isTRUE(info) && message_not_thrown_before("as.sir", "sir_interpretation_history")) { if (isTRUE(info) && message_not_thrown_before("as.sir", "sir_interpretation_history")) {
message()
message_("Run `sir_interpretation_history()` afterwards to retrieve a logbook with all details of the breakpoint interpretations.\n\n", add_fn = font_green) message_("Run `sir_interpretation_history()` afterwards to retrieve a logbook with all details of the breakpoint interpretations.\n\n", add_fn = font_green)
} }
@@ -1553,7 +1557,7 @@ as_sir_method <- function(method_short,
)) ))
if (breakpoint_type == "animal") { if (breakpoint_type == "animal") {
# 2025-03-13 for now, only strictly follow guideline for current host, no extrapolation # 2025-03-13/ for now, only strictly follow guideline for current host, no extrapolation
breakpoints_current <- breakpoints_current[which(breakpoints_current$host == host_current), , drop = FALSE] breakpoints_current <- breakpoints_current[which(breakpoints_current$host == host_current), , drop = FALSE]
} }
@@ -1651,26 +1655,23 @@ as_sir_method <- function(method_short,
next next
} }
# sort on host and taxonomic rank # if the user explicitly set uti, keep only those rows
# (this will e.g. prefer 'species' breakpoints over 'order' breakpoints) if (!is.na(uti_current)) {
if (is.na(uti_current)) { breakpoints_current <- breakpoints_current[breakpoints_current$uti == uti_current, , drop = FALSE]
breakpoints_current <- breakpoints_current %pm>%
# `uti` is a column in the data set
# this will put UTI = FALSE first, then UTI = NA, then UTI = TRUE
pm_mutate(uti_index = ifelse(!is.na(uti) & uti == FALSE, 1,
ifelse(is.na(uti), 2,
3
)
)) %pm>%
# be as specific as possible (i.e. prefer species over genus):
pm_arrange(rank_index, uti_index)
} else if (uti_current == TRUE) {
breakpoints_current <- breakpoints_current %pm>%
subset(uti == TRUE) %pm>%
# be as specific as possible (i.e. prefer species over genus):
pm_arrange(rank_index)
} }
# build a helper factor so FALSE < NA < TRUE
uti_index <- factor(
ifelse(is.na(breakpoints_current$uti), "NA",
as.character(breakpoints_current$uti)
),
levels = c("FALSE", "NA", "TRUE")
)
# sort on host and taxonomic rank first, then by UTI
# (this will e.g. prefer 'species' breakpoints over 'order' breakpoints)
breakpoints_current <- breakpoints_current[order(breakpoints_current$rank_index, uti_index), , drop = FALSE]
# throw messages for different body sites # throw messages for different body sites
site <- breakpoints_current[1L, "site", drop = FALSE] # this is the one we'll take site <- breakpoints_current[1L, "site", drop = FALSE] # this is the one we'll take
if (is.na(site)) { if (is.na(site)) {
@@ -1682,7 +1683,7 @@ as_sir_method <- function(method_short,
# only UTI breakpoints available # only UTI breakpoints available
notes_current <- paste0( notes_current <- paste0(
notes_current, "\n", notes_current, "\n",
paste0("Breakpoints for ", font_bold(ab_formatted), " in ", mo_formatted, " are only available for (uncomplicated) urinary tract infections (UTI); assuming `uti = TRUE`.") paste0("Breakpoints for ", font_bold(ab_formatted), " in ", mo_formatted, " are only available for (uncomplicated) urinary tract infections (UTI) - assuming `uti = TRUE`.")
) )
} else if (nrow(breakpoints_current) > 1 && length(unique(breakpoints_current$site)) > 1 && any(is.na(uti_current)) && all(c(TRUE, FALSE) %in% breakpoints_current$uti, na.rm = TRUE) && message_not_thrown_before("as.sir", "siteUTI", mo_current, ab_current)) { } else if (nrow(breakpoints_current) > 1 && length(unique(breakpoints_current$site)) > 1 && any(is.na(uti_current)) && all(c(TRUE, FALSE) %in% breakpoints_current$uti, na.rm = TRUE) && message_not_thrown_before("as.sir", "siteUTI", mo_current, ab_current)) {
# both UTI and Non-UTI breakpoints available # both UTI and Non-UTI breakpoints available
@@ -1705,7 +1706,7 @@ as_sir_method <- function(method_short,
new_sir <- rep(as.sir("R"), length(rows)) new_sir <- rep(as.sir("R"), length(rows))
notes_current <- paste0( notes_current <- paste0(
notes_current, "\n", notes_current, "\n",
paste0("Intrinsic resistance applied for ", ab_formatted, " in ", mo_formatted, "") paste0("Intrinsic resistance applied for ", ab_formatted, " in ", mo_formatted, ".")
) )
} else if (nrow(breakpoints_current) == 0) { } else if (nrow(breakpoints_current) == 0) {
# no rules available # no rules available
@@ -1713,41 +1714,48 @@ as_sir_method <- function(method_short,
} else { } else {
# then run the rules # then run the rules
breakpoints_current <- breakpoints_current[1L, , drop = FALSE] breakpoints_current <- breakpoints_current[1L, , drop = FALSE]
if (breakpoints_current$rank_index > 3) {
# we resort to a high-level taxonomic record since there are no breakpoint on genus (rank_index = 3) or lower, so note this
notes_current <- paste0(
"No genus- or species-level breakpoint available - applying higher taxonomic level instead.\n",
notes_current
)
}
notes_current <- paste0( notes_current <- paste0(
notes_current, "\n", notes_current, "\n",
ifelse(breakpoints_current$mo == "UNKNOWN" | breakpoints_current$ref_tbl %like% "PK.*PD", ifelse(breakpoints_current$mo == "UNKNOWN" | breakpoints_current$ref_tbl %like% "PK.*PD",
"Some PK/PD breakpoints were applied - use `include_PKPD = FALSE` to prevent this", "Some PK/PD breakpoints were applied - use `include_PKPD = FALSE` to prevent this.",
"" ""
), ),
"\n", "\n",
ifelse(breakpoints_current$site %like% "screen" | breakpoints_current$ref_tbl %like% "screen", ifelse(breakpoints_current$site %like% "screen" | breakpoints_current$ref_tbl %like% "screen",
"Some screening breakpoints were applied - use `include_screening = FALSE` to prevent this", "Some screening breakpoints were applied - use `include_screening = FALSE` to prevent this.",
"" ""
), ),
"\n", "\n",
ifelse(method == "mic" & capped_mic_handling %in% c("conservative", "inverse") & as.character(values_bak) %like% "^[<][0-9]", ifelse(method == "mic" & capped_mic_handling %in% c("conservative", "inverse") & as.character(values_bak) %like% "^[<][0-9]",
paste0("MIC values with the operator '<' are all considered 'S' since capped_mic_handling = \"", capped_mic_handling, "\""), paste0("MIC values with the operator '<' are all considered 'S' since capped_mic_handling = \"", capped_mic_handling, "\"."),
"" ""
), ),
"\n", "\n",
ifelse(method == "mic" & capped_mic_handling %in% c("conservative", "inverse") & as.character(values_bak) %like% "^[>][0-9]", ifelse(method == "mic" & capped_mic_handling %in% c("conservative", "inverse") & as.character(values_bak) %like% "^[>][0-9]",
paste0("MIC values with the operator '>' are all considered 'R' since capped_mic_handling = \"", capped_mic_handling, "\""), paste0("MIC values with the operator '>' are all considered 'R' since capped_mic_handling = \"", capped_mic_handling, "\"."),
"" ""
), ),
"\n", "\n",
ifelse(method == "mic" & capped_mic_handling %in% c("conservative", "standard") & as.character(values_bak) %like% "^[><]=[0-9]" & as.double(values) > breakpoints_current$breakpoint_S & as.double(values) < breakpoints_current$breakpoint_R, ifelse(method == "mic" & capped_mic_handling %in% c("conservative", "standard") & as.character(values_bak) %like% "^[><]=[0-9]" & as.double(values) > breakpoints_current$breakpoint_S & as.double(values) < breakpoints_current$breakpoint_R,
paste0("MIC values within the breakpoint guideline range with the operator '<=' or '>=' are considered 'NI' (non-interpretable) since capped_mic_handling = \"", capped_mic_handling, "\""), paste0("MIC values within the breakpoint guideline range with the operator '<=' or '>=' are considered 'NI' (non-interpretable) since capped_mic_handling = \"", capped_mic_handling, "\"."),
"" ""
), ),
"\n", "\n",
ifelse(method == "mic" & capped_mic_handling %in% c("conservative", "standard") & as.character(values_bak) %like% "^<=[0-9]" & as.double(values) == breakpoints_current$breakpoint_R, ifelse(method == "mic" & capped_mic_handling %in% c("conservative", "standard") & as.character(values_bak) %like% "^<=[0-9]" & as.double(values) == breakpoints_current$breakpoint_R,
paste0("MIC values at the R breakpoint with the operator '<=' are considered 'NI' (non-interpretable) since capped_mic_handling = \"", capped_mic_handling, "\""), paste0("MIC values at the R breakpoint with the operator '<=' are considered 'NI' (non-interpretable) since capped_mic_handling = \"", capped_mic_handling, "\"."),
"" ""
), ),
"\n", "\n",
ifelse(method == "mic" & capped_mic_handling %in% c("conservative", "standard") & as.character(values_bak) %like% "^>=[0-9]" & as.double(values) == breakpoints_current$breakpoint_S, ifelse(method == "mic" & capped_mic_handling %in% c("conservative", "standard") & as.character(values_bak) %like% "^>=[0-9]" & as.double(values) == breakpoints_current$breakpoint_S,
paste0("MIC values at the S breakpoint with the operator '>=' are considered 'NI' (non-interpretable) since capped_mic_handling = \"", capped_mic_handling, "\""), paste0("MIC values at the S breakpoint with the operator '>=' are considered 'NI' (non-interpretable) since capped_mic_handling = \"", capped_mic_handling, "\"."),
"" ""
) )
) )
@@ -1757,7 +1765,7 @@ as_sir_method <- function(method_short,
notes_current <- paste0( notes_current <- paste0(
notes_current, "\n", notes_current, "\n",
ifelse(!is.na(breakpoints_current$breakpoint_S) & is.na(breakpoints_current$breakpoint_R), ifelse(!is.na(breakpoints_current$breakpoint_S) & is.na(breakpoints_current$breakpoint_R),
"NAs because of missing R breakpoints were substituted with R since substitute_missing_r_breakpoint = TRUE", "NAs because of missing R breakpoints were substituted with R since substitute_missing_r_breakpoint = TRUE.",
"" ""
) )
) )
@@ -1796,7 +1804,7 @@ as_sir_method <- function(method_short,
} }
# write to verbose output # write to verbose output
notes_current <- trimws2(notes_current) notes_current <- gsub("\n\n", "\n", trimws2(notes_current), fixed = TRUE)
notes_current[notes_current == ""] <- NA_character_ notes_current[notes_current == ""] <- NA_character_
out <- data.frame( out <- data.frame(
# recycling 1 to 2 rows does not always seem to work, which is why vectorise_log_entry() was added # recycling 1 to 2 rows does not always seem to work, which is why vectorise_log_entry() was added
@@ -1904,11 +1912,11 @@ pillar_shaft.sir <- function(x, ...) {
# colours will anyway not work when has_colour() == FALSE, # colours will anyway not work when has_colour() == FALSE,
# but then the indentation should also not be applied # but then the indentation should also not be applied
out[is.na(x)] <- font_grey(" NA") out[is.na(x)] <- font_grey(" NA")
out[x == "NI"] <- font_grey_bg(font_black(" NI "))
out[x == "S"] <- font_green_bg(" S ") out[x == "S"] <- font_green_bg(" S ")
out[x == "SDD"] <- font_green_lighter_bg(" SDD ")
out[x == "I"] <- font_orange_bg(" I ") out[x == "I"] <- font_orange_bg(" I ")
out[x == "SDD"] <- font_orange_bg(" SDD ")
out[x == "R"] <- font_rose_bg(" R ") out[x == "R"] <- font_rose_bg(" R ")
out[x == "NI"] <- font_grey_bg(font_black(" NI "))
} }
create_pillar_column(out, align = "left", width = 5) create_pillar_column(out, align = "left", width = 5)
} }

View File

@@ -244,7 +244,7 @@ sir_calc_df <- function(type, # "proportion", "count" or "both"
translate_ab <- get_translate_ab(translate_ab) translate_ab <- get_translate_ab(translate_ab)
data.bak <- data data.bak <- data
# select only groups and antimicrobials # select only groups and antibiotics
if (is_null_or_grouped_tbl(data)) { if (is_null_or_grouped_tbl(data)) {
data_has_groups <- TRUE data_has_groups <- TRUE
groups <- get_group_names(data) groups <- get_group_names(data)
@@ -255,10 +255,12 @@ sir_calc_df <- function(type, # "proportion", "count" or "both"
} }
data <- as.data.frame(data, stringsAsFactors = FALSE) data <- as.data.frame(data, stringsAsFactors = FALSE)
if (isTRUE(combine_SI)) {
for (i in seq_len(ncol(data))) { for (i in seq_len(ncol(data))) {
# transform SIR columns
if (is.sir(data[, i, drop = TRUE])) { if (is.sir(data[, i, drop = TRUE])) {
data[, i] <- as.character(data[, i, drop = TRUE]) data[, i] <- as.character(data[, i, drop = TRUE])
if (isTRUE(combine_SI)) {
if ("SDD" %in% data[, i, drop = TRUE] && message_not_thrown_before("sir_calc_df", combine_SI, entire_session = TRUE)) { if ("SDD" %in% data[, i, drop = TRUE] && message_not_thrown_before("sir_calc_df", combine_SI, entire_session = TRUE)) {
message_("Note that `sir_calc_df()` will also count dose-dependent susceptibility, 'SDD', as 'SI' when `combine_SI = TRUE`. This note will be shown once for this session.", as_note = FALSE) message_("Note that `sir_calc_df()` will also count dose-dependent susceptibility, 'SDD', as 'SI' when `combine_SI = TRUE`. This note will be shown once for this session.", as_note = FALSE)
} }
@@ -364,7 +366,7 @@ sir_calc_df <- function(type, # "proportion", "count" or "both"
} else { } else {
# don't use as.sir() here, as it would add the class 'sir' and we would like # don't use as.sir() here, as it would add the class 'sir' and we would like
# the same data structure as output, regardless of input # the same data structure as output, regardless of input
if (out$value[out$interpretation == "SDD"] > 0) { if (any(out$value[out$interpretation == "SDD"] > 0, na.rm = TRUE)) {
out$interpretation <- factor(out$interpretation, levels = c("S", "SDD", "I", "R"), ordered = TRUE) out$interpretation <- factor(out$interpretation, levels = c("S", "SDD", "I", "R"), ordered = TRUE)
} else { } else {
out$interpretation <- factor(out$interpretation, levels = c("S", "I", "R"), ordered = TRUE) out$interpretation <- factor(out$interpretation, levels = c("S", "I", "R"), ordered = TRUE)

View File

@@ -47,6 +47,6 @@ sir_df <- function(data,
combine_SI = combine_SI, combine_SI = combine_SI,
confidence_level = confidence_level confidence_level = confidence_level
), ),
error = function(e) stop_(gsub("in sir_calc_df(): ", "", e$message, fixed = TRUE), call = -5) error = function(e) stop_(gsub("in sir_calc_df(): ", "", conditionMessage(e), fixed = TRUE), call = -5)
) )
} }

Binary file not shown.

265
R/tidymodels.R Normal file
View File

@@ -0,0 +1,265 @@
#' AMR Extensions for Tidymodels
#'
#' This family of functions allows using AMR-specific data types such as `<mic>` and `<sir>` inside `tidymodels` pipelines.
#' @inheritParams recipes::step_center
#' @details
#' You can read more in our online [AMR with tidymodels introduction](https://amr-for-r.org/articles/AMR_with_tidymodels.html).
#'
#' Tidyselect helpers include:
#' - [all_mic()] and [all_mic_predictors()] to select `<mic>` columns
#' - [all_sir()] and [all_sir_predictors()] to select `<sir>` columns
#'
#' Pre-processing pipeline steps include:
#' - [step_mic_log2()] to convert MIC columns to numeric (via `as.numeric()`) and apply a log2 transform, to be used with [all_mic_predictors()]
#' - [step_sir_numeric()] to convert SIR columns to numeric (via `as.numeric()`), to be used with [all_sir_predictors()]: `"S"` = 1, `"I"`/`"SDD"` = 2, `"R"` = 3. All other values are rendered `NA`. Keep this in mind for further processing, especially if the model does not allow for `NA` values.
#'
#' These steps integrate with `recipes::recipe()` and work like standard preprocessing steps. They are useful for preparing data for modelling, especially with classification models.
#' @seealso [recipes::recipe()], [as.mic()], [as.sir()]
#' @name amr-tidymodels
#' @keywords internal
#' @export
#' @examples
#' if (require("tidymodels")) {
#'
#' # The below approach formed the basis for this paper: DOI 10.3389/fmicb.2025.1582703
#' # Presence of ESBL genes was predicted based on raw MIC values.
#'
#'
#' # example data set in the AMR package
#' esbl_isolates
#'
#' # Prepare a binary outcome and convert to ordered factor
#' data <- esbl_isolates %>%
#' mutate(esbl = factor(esbl, levels = c(FALSE, TRUE), ordered = TRUE))
#'
#' # Split into training and testing sets
#' split <- initial_split(data)
#' training_data <- training(split)
#' testing_data <- testing(split)
#'
#' # Create and prep a recipe with MIC log2 transformation
#' mic_recipe <- recipe(esbl ~ ., data = training_data) %>%
#'
#' # Optionally remove non-predictive variables
#' remove_role(genus, old_role = "predictor") %>%
#'
#' # Apply the log2 transformation to all MIC predictors
#' step_mic_log2(all_mic_predictors()) %>%
#'
#' # And apply the preparation steps
#' prep()
#'
#' # View prepped recipe
#' mic_recipe
#'
#' # Apply the recipe to training and testing data
#' out_training <- bake(mic_recipe, new_data = NULL)
#' out_testing <- bake(mic_recipe, new_data = testing_data)
#'
#' # Fit a logistic regression model
#' fitted <- logistic_reg(mode = "classification") %>%
#' set_engine("glm") %>%
#' fit(esbl ~ ., data = out_training)
#'
#' # Generate predictions on the test set
#' predictions <- predict(fitted, out_testing) %>%
#' bind_cols(out_testing)
#'
#' # Evaluate predictions using standard classification metrics
#' our_metrics <- metric_set(accuracy, kap, ppv, npv)
#' metrics <- our_metrics(predictions, truth = esbl, estimate = .pred_class)
#'
#' # Show performance
#' metrics
#' }
all_mic <- function() {
x <- tidymodels_amr_select(levels(NA_mic_))
names(x)
}
#' @rdname amr-tidymodels
#' @export
all_mic_predictors <- function() {
x <- tidymodels_amr_select(levels(NA_mic_))
intersect(x, recipes::has_role("predictor"))
}
#' @rdname amr-tidymodels
#' @export
all_sir <- function() {
x <- tidymodels_amr_select(levels(NA_sir_))
names(x)
}
#' @rdname amr-tidymodels
#' @export
all_sir_predictors <- function() {
x <- tidymodels_amr_select(levels(NA_sir_))
intersect(x, recipes::has_role("predictor"))
}
#' @rdname amr-tidymodels
#' @export
step_mic_log2 <- function(
recipe,
...,
role = NA,
trained = FALSE,
columns = NULL,
skip = FALSE,
id = recipes::rand_id("mic_log2")) {
recipes::add_step(
recipe,
step_mic_log2_new(
terms = rlang::enquos(...),
role = role,
trained = trained,
columns = columns,
skip = skip,
id = id
)
)
}
step_mic_log2_new <- function(terms, role, trained, columns, skip, id) {
recipes::step(
subclass = "mic_log2",
terms = terms,
role = role,
trained = trained,
columns = columns,
skip = skip,
id = id
)
}
#' @rawNamespace if(getRversion() >= "3.0.0") S3method(recipes::prep, step_mic_log2)
prep.step_mic_log2 <- function(x, training, info = NULL, ...) {
col_names <- recipes::recipes_eval_select(x$terms, training, info)
recipes::check_type(training[, col_names], types = "ordered")
step_mic_log2_new(
terms = x$terms,
role = x$role,
trained = TRUE,
columns = col_names,
skip = x$skip,
id = x$id
)
}
#' @rawNamespace if(getRversion() >= "3.0.0") S3method(recipes::bake, step_mic_log2)
bake.step_mic_log2 <- function(object, new_data, ...) {
recipes::check_new_data(object$columns, object, new_data)
for (col in object$columns) {
new_data[[col]] <- log2(as.numeric(as.mic(new_data[[col]])))
}
new_data
}
#' @export
print.step_mic_log2 <- function(x, width = max(20, options()$width - 35), ...) {
title <- "Log2 transformation of MIC columns"
recipes::print_step(x$columns, x$terms, x$trained, title, width)
invisible(x)
}
#' @rawNamespace if(getRversion() >= "3.0.0") S3method(recipes::tidy, step_mic_log2)
tidy.step_mic_log2 <- function(x, ...) {
if (recipes::is_trained(x)) {
res <- tibble::tibble(terms = x$columns)
} else {
res <- tibble::tibble(terms = recipes::sel2char(x$terms))
}
res$id <- x$id
res
}
#' @rdname amr-tidymodels
#' @export
step_sir_numeric <- function(
recipe,
...,
role = NA,
trained = FALSE,
columns = NULL,
skip = FALSE,
id = recipes::rand_id("sir_numeric")) {
recipes::add_step(
recipe,
step_sir_numeric_new(
terms = rlang::enquos(...),
role = role,
trained = trained,
columns = columns,
skip = skip,
id = id
)
)
}
step_sir_numeric_new <- function(terms, role, trained, columns, skip, id) {
recipes::step(
subclass = "sir_numeric",
terms = terms,
role = role,
trained = trained,
columns = columns,
skip = skip,
id = id
)
}
#' @rawNamespace if(getRversion() >= "3.0.0") S3method(recipes::prep, step_sir_numeric)
prep.step_sir_numeric <- function(x, training, info = NULL, ...) {
col_names <- recipes::recipes_eval_select(x$terms, training, info)
recipes::check_type(training[, col_names], types = "ordered")
step_sir_numeric_new(
terms = x$terms,
role = x$role,
trained = TRUE,
columns = col_names,
skip = x$skip,
id = x$id
)
}
#' @rawNamespace if(getRversion() >= "3.0.0") S3method(recipes::bake, step_sir_numeric)
bake.step_sir_numeric <- function(object, new_data, ...) {
recipes::check_new_data(object$columns, object, new_data)
for (col in object$columns) {
new_data[[col]] <- as.numeric(as.sir(new_data[[col]]))
}
new_data
}
#' @export
print.step_sir_numeric <- function(x, width = max(20, options()$width - 35), ...) {
title <- "Numeric transformation of SIR columns"
recipes::print_step(x$columns, x$terms, x$trained, title, width)
invisible(x)
}
#' @rawNamespace if(getRversion() >= "3.0.0") S3method(recipes::tidy, step_sir_numeric)
tidy.step_sir_numeric <- function(x, ...) {
if (recipes::is_trained(x)) {
res <- tibble::tibble(terms = x$columns)
} else {
res <- tibble::tibble(terms = recipes::sel2char(x$terms))
}
res$id <- x$id
res
}
tidymodels_amr_select <- function(check_vector) {
df <- get_current_data()
ind <- which(
vapply(
FUN.VALUE = logical(1),
df,
function(x) all(x %in% c(check_vector, NA), na.rm = TRUE) & any(x %in% check_vector),
USE.NAMES = TRUE
),
useNames = TRUE
)
ind
}

View File

@@ -258,6 +258,11 @@ translate_into_language <- function(from,
return(from) return(from)
} }
if (only_affect_ab_names == TRUE) {
df_trans$pattern[df_trans$regular_expr == TRUE] <- paste0(df_trans$pattern[df_trans$regular_expr == TRUE], "$")
df_trans$pattern[df_trans$regular_expr == TRUE] <- gsub("$$", "$", df_trans$pattern[df_trans$regular_expr == TRUE], fixed = TRUE)
}
lapply( lapply(
# starting with longest pattern, since more general translations are shorter, such as 'Group' # starting with longest pattern, since more general translations are shorter, such as 'Group'
order(nchar(df_trans$pattern), decreasing = TRUE), order(nchar(df_trans$pattern), decreasing = TRUE),

View File

@@ -30,7 +30,6 @@
# These are all S3 implementations for the vctrs package, # These are all S3 implementations for the vctrs package,
# that is used internally by tidyverse packages such as dplyr. # that is used internally by tidyverse packages such as dplyr.
# They are to convert AMR-specific classes to bare characters and integers. # They are to convert AMR-specific classes to bare characters and integers.
# All of them will be exported using s3_register() in R/zzz.R when loading the package.
# see https://github.com/tidyverse/dplyr/issues/5955 why this is required # see https://github.com/tidyverse/dplyr/issues/5955 why this is required

View File

@@ -127,7 +127,7 @@ AMR_env$cross_icon <- if (isTRUE(base::l10n_info()$`UTF-8`)) "\u00d7" else "x"
suppressWarnings(suppressMessages(add_custom_antimicrobials(x))) suppressWarnings(suppressMessages(add_custom_antimicrobials(x)))
packageStartupMessage("OK.") packageStartupMessage("OK.")
}, },
error = function(e) packageStartupMessage("Failed: ", e$message) error = function(e) packageStartupMessage("Failed: ", conditionMessage(e))
) )
} }
} }
@@ -143,7 +143,7 @@ AMR_env$cross_icon <- if (isTRUE(base::l10n_info()$`UTF-8`)) "\u00d7" else "x"
suppressWarnings(suppressMessages(add_custom_microorganisms(x))) suppressWarnings(suppressMessages(add_custom_microorganisms(x)))
packageStartupMessage("OK.") packageStartupMessage("OK.")
}, },
error = function(e) packageStartupMessage("Failed: ", e$message) error = function(e) packageStartupMessage("Failed: ", conditionMessage(e))
) )
} }
} }

View File

@@ -234,6 +234,7 @@ reference:
- "`antimicrobials`" - "`antimicrobials`"
- "`clinical_breakpoints`" - "`clinical_breakpoints`"
- "`example_isolates`" - "`example_isolates`"
- "`esbl_isolates`"
- "`microorganisms.codes`" - "`microorganisms.codes`"
- "`microorganisms.groups`" - "`microorganisms.groups`"
- "`intrinsic_resistant`" - "`intrinsic_resistant`"

View File

@@ -56,7 +56,8 @@ os.makedirs(r_lib_path, exist_ok=True)
os.environ['R_LIBS_SITE'] = r_lib_path os.environ['R_LIBS_SITE'] = r_lib_path
from rpy2 import robjects from rpy2 import robjects
from rpy2.robjects import pandas2ri from rpy2.robjects.conversion import localconverter
from rpy2.robjects import default_converter, numpy2ri, pandas2ri
from rpy2.robjects.packages import importr, isinstalled from rpy2.robjects.packages import importr, isinstalled
# Import base and utils # Import base and utils
@@ -94,10 +95,9 @@ if r_amr_version != python_amr_version:
print(f"AMR: Setting up R environment and AMR datasets...", flush=True) print(f"AMR: Setting up R environment and AMR datasets...", flush=True)
# Activate the automatic conversion between R and pandas DataFrames # Activate the automatic conversion between R and pandas DataFrames
pandas2ri.activate() with localconverter(default_converter + numpy2ri.converter + pandas2ri.converter):
# example_isolates # example_isolates
example_isolates = pandas2ri.rpy2py(robjects.r(''' example_isolates = robjects.r('''
df <- AMR::example_isolates df <- AMR::example_isolates
df[] <- lapply(df, function(x) { df[] <- lapply(df, function(x) {
if (inherits(x, c("Date", "POSIXt", "factor"))) { if (inherits(x, c("Date", "POSIXt", "factor"))) {
@@ -108,13 +108,13 @@ df[] <- lapply(df, function(x) {
}) })
df <- df[, !sapply(df, is.list)] df <- df[, !sapply(df, is.list)]
df df
''')) ''')
example_isolates['date'] = pd.to_datetime(example_isolates['date']) example_isolates['date'] = pd.to_datetime(example_isolates['date'])
# microorganisms # microorganisms
microorganisms = pandas2ri.rpy2py(robjects.r('AMR::microorganisms[, !sapply(AMR::microorganisms, is.list)]')) microorganisms = robjects.r('AMR::microorganisms[, !sapply(AMR::microorganisms, is.list)]')
antimicrobials = pandas2ri.rpy2py(robjects.r('AMR::antimicrobials[, !sapply(AMR::antimicrobials, is.list)]')) antimicrobials = robjects.r('AMR::antimicrobials[, !sapply(AMR::antimicrobials, is.list)]')
clinical_breakpoints = pandas2ri.rpy2py(robjects.r('AMR::clinical_breakpoints[, !sapply(AMR::clinical_breakpoints, is.list)]')) clinical_breakpoints = robjects.r('AMR::clinical_breakpoints[, !sapply(AMR::clinical_breakpoints, is.list)]')
base.options(warn = 0) base.options(warn = 0)
@@ -129,16 +129,15 @@ echo "from .datasets import clinical_breakpoints" >> $init_file
# Write header to the functions Python file, including the convert_to_python function # Write header to the functions Python file, including the convert_to_python function
cat <<EOL > "$functions_file" cat <<EOL > "$functions_file"
import functools
import rpy2.robjects as robjects import rpy2.robjects as robjects
from rpy2.robjects.packages import importr from rpy2.robjects.packages import importr
from rpy2.robjects.vectors import StrVector, FactorVector, IntVector, FloatVector, DataFrame from rpy2.robjects.vectors import StrVector, FactorVector, IntVector, FloatVector, DataFrame
from rpy2.robjects import pandas2ri from rpy2.robjects.conversion import localconverter
from rpy2.robjects import default_converter, numpy2ri, pandas2ri
import pandas as pd import pandas as pd
import numpy as np import numpy as np
# Activate automatic conversion between R data frames and pandas data frames
pandas2ri.activate()
# Import the AMR R package # Import the AMR R package
amr_r = importr('AMR') amr_r = importr('AMR')
@@ -156,10 +155,8 @@ def convert_to_python(r_output):
return list(r_output) # Convert to a Python list of integers or floats return list(r_output) # Convert to a Python list of integers or floats
# Check if it's a pandas-compatible R data frame # Check if it's a pandas-compatible R data frame
elif isinstance(r_output, pd.DataFrame): elif isinstance(r_output, (pd.DataFrame, DataFrame)):
return r_output # Return as pandas DataFrame (already converted by pandas2ri) return r_output # Return as pandas DataFrame (already converted by pandas2ri)
elif isinstance(r_output, DataFrame):
return pandas2ri.rpy2py(r_output) # Return as pandas DataFrame
# Check if the input is a NumPy array and has a string data type # Check if the input is a NumPy array and has a string data type
if isinstance(r_output, np.ndarray) and np.issubdtype(r_output.dtype, np.str_): if isinstance(r_output, np.ndarray) and np.issubdtype(r_output.dtype, np.str_):
@@ -167,6 +164,15 @@ def convert_to_python(r_output):
# Fall-back # Fall-back
return r_output return r_output
def r_to_python(r_func):
"""Decorator that runs an rpy2 function under a localconverter
and then applies convert_to_python to its output."""
@functools.wraps(r_func)
def wrapper(*args, **kwargs):
with localconverter(default_converter + numpy2ri.converter + pandas2ri.converter):
return convert_to_python(r_func(*args, **kwargs))
return wrapper
EOL EOL
# Directory where the .Rd files are stored (update path as needed) # Directory where the .Rd files are stored (update path as needed)
@@ -246,10 +252,11 @@ for rd_file in "$rd_dir"/*.Rd; do
gsub("FALSE", "False", func_args) gsub("FALSE", "False", func_args)
gsub("NULL", "None", func_args) gsub("NULL", "None", func_args)
# Write the Python function definition to the output file # Write the Python function definition to the output file, using decorator
print "@r_to_python" >> "'"$functions_file"'"
print "def " func_name_py "(" func_args "):" >> "'"$functions_file"'" print "def " func_name_py "(" func_args "):" >> "'"$functions_file"'"
print " \"\"\"Please see our website of the R package for the full manual: https://amr-for-r.org\"\"\"" >> "'"$functions_file"'" print " \"\"\"Please see our website of the R package for the full manual: https://amr-for-r.org\"\"\"" >> "'"$functions_file"'"
print " return convert_to_python(amr_r." func_name_py "(" func_args "))" >> "'"$functions_file"'" print " return amr_r." func_name_py "(" func_args ")" >> "'"$functions_file"'"
print "from .functions import " func_name_py >> "'"$init_file"'" print "from .functions import " func_name_py >> "'"$init_file"'"
} }

View File

@@ -663,7 +663,9 @@ if (files_changed()) {
} }
# Update index.md and README.md ------------------------------------------- # Update index.md and README.md -------------------------------------------
if (files_changed("man/microorganisms.Rd") || if (files_changed("README.Rmd") ||
files_changed("index.Rmd") ||
files_changed("man/microorganisms.Rd") ||
files_changed("man/antimicrobials.Rd") || files_changed("man/antimicrobials.Rd") ||
files_changed("man/clinical_breakpoints.Rd") || files_changed("man/clinical_breakpoints.Rd") ||
files_changed("man/antibiogram.Rd") || files_changed("man/antibiogram.Rd") ||

View File

@@ -288,7 +288,7 @@ for (page in LETTERS) {
url <- paste0("https://lpsn.dsmz.de/genus?page=", page) url <- paste0("https://lpsn.dsmz.de/genus?page=", page)
x <- tryCatch(read_html(url), x <- tryCatch(read_html(url),
error = function(e) { error = function(e) {
message("Waiting 10 seconds because of error: ", e$message) message("Waiting 10 seconds because of error: ", conditionMessage(e))
Sys.sleep(10) Sys.sleep(10)
read_html(url) read_html(url)
}) })

View File

@@ -108,3 +108,18 @@ writeLines(contents, "R/aa_helper_pm_functions.R")
# note: pm_left_join() will be overwritten by aaa_helper_functions.R, which contains a faster implementation # note: pm_left_join() will be overwritten by aaa_helper_functions.R, which contains a faster implementation
# replace `res <- as.data.frame(res)` with `res <- as.data.frame(res, stringsAsFactors = FALSE)` # replace `res <- as.data.frame(res)` with `res <- as.data.frame(res, stringsAsFactors = FALSE)`
# after running, pm_select must be altered. The line:
# col_pos <- pm_select_positions(.data, ..., .group_pos = TRUE)
# ... must be replaced with this to support tidyselect functionality such as `starts_with()`:
# col_pos <- tryCatch(pm_select_positions(.data, ..., .group_pos = TRUE), error = function(e) NULL)
# if (is.null(col_pos)) {
# # try with tidyverse
# select_dplyr <- import_fn("select", "dplyr", error_on_fail = FALSE)
# if (!is.null(select_dplyr)) {
# col_pos <- which(colnames(.data) %in% colnames(select_dplyr(.data, ...)))
# } else {
# # this will throw an error as it did, but dplyr is not available, so no other option
# col_pos <- pm_select_positions(.data, ..., .group_pos = TRUE)
# }
# }

View File

@@ -1 +1 @@
228840b3941753c4adee2b781d901590 d12f1c78feaecbb4d1631f9c735ad49b

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -116,7 +116,7 @@
"CSU" 68718 "Cefsumide" "Cephalosporins (unclassified gen.)" "NA" "NA" "cefsulmid,cefsumido,cefsumidum" "NA" "CSU" 68718 "Cefsumide" "Cephalosporins (unclassified gen.)" "NA" "NA" "cefsulmid,cefsumido,cefsumidum" "NA"
"CPT" 56841980 "Ceftaroline" "Cephalosporins (5th gen.)" "J01DI02,QJ01DI02" "ceftar,cfro" "ceftaroine,teflaro,zinforo" "73604-1,73605-8,73626-4,73627-2,73649-6,73650-4,74170-2" "CPT" 56841980 "Ceftaroline" "Cephalosporins (5th gen.)" "J01DI02,QJ01DI02" "ceftar,cfro" "ceftaroine,teflaro,zinforo" "73604-1,73605-8,73626-4,73627-2,73649-6,73650-4,74170-2"
"CPA" "Ceftaroline/avibactam" "Cephalosporins (5th gen.)" "NA" "NA" "NA" "73604-1,73626-4,73649-6" "CPA" "Ceftaroline/avibactam" "Cephalosporins (5th gen.)" "NA" "NA" "NA" "73604-1,73626-4,73649-6"
"CAZ" 5481173 "Ceftazidime" "Cephalosporins (3rd gen.)" "J01DD02,QJ01DD02" "Other beta-lactam antibacterials" "Third-generation cephalosporins" "caz,cefta,ceftaz,cfta,cftz,taz,tz,xtz" "ceftazimide,ceptaz,fortam,fortaz,fortum,glazidim,kefazim,modacin,pentacef,tazicef,tizime" 4 "g" "101481-0,101482-8,101483-6,132-1,133-9,134-7,135-4,18893-8,21151-6,3449-6,35774-9,35775-6,35776-4,42352-5,55648-0,55649-8,55650-6,55651-4,58705-5,6995-5,73603-3,73625-6,73648-8,80960-8,87734-0,90850-9" "CAZ" 5481173 "Ceftazidime" "Cephalosporins (3rd gen.)" "J01DD02,QJ01DD02" "Other beta-lactam antibacterials" "Third-generation cephalosporins" "caz,cef,cefta,ceftaz,cfta,cftz,taz,tz,xtz" "ceftazimide,ceptaz,fortam,fortaz,fortum,glazidim,kefazim,modacin,pentacef,tazicef,tizime" 4 "g" "101481-0,101482-8,101483-6,132-1,133-9,134-7,135-4,18893-8,21151-6,3449-6,35774-9,35775-6,35776-4,42352-5,55648-0,55649-8,55650-6,55651-4,58705-5,6995-5,73603-3,73625-6,73648-8,80960-8,87734-0,90850-9"
"CZA" 90643431 "Ceftazidime/avibactam" "Cephalosporins (3rd gen.)" "J01DD52,QJ01DD52" "cfav" "avycaz,zavicefta" 6 "g" "101483-6,73603-3,73625-6,73648-8,87734-0" "CZA" 90643431 "Ceftazidime/avibactam" "Cephalosporins (3rd gen.)" "J01DD52,QJ01DD52" "cfav" "avycaz,zavicefta" 6 "g" "101483-6,73603-3,73625-6,73648-8,87734-0"
"CCV" 9575352 "Ceftazidime/clavulanic acid" "Cephalosporins (3rd gen.)" "J01DD52,QJ01DD52" "Other beta-lactam antibacterials" "Third-generation cephalosporins" "czcl,tazcla,xtzl" "NA" 6 "g" "NA" "CCV" 9575352 "Ceftazidime/clavulanic acid" "Cephalosporins (3rd gen.)" "J01DD52,QJ01DD52" "Other beta-lactam antibacterials" "Third-generation cephalosporins" "czcl,tazcla,xtzl" "NA" 6 "g" "NA"
"CEM" 6537431 "Cefteram" "Cephalosporins (3rd gen.)" "J01DD18,QJ01DD18" "cefter" "cefterame,cefteramum,ceftetrame" 0.4 "g" "100047-0,76144-5" "CEM" 6537431 "Cefteram" "Cephalosporins (3rd gen.)" "J01DD18,QJ01DD18" "cefter" "cefterame,cefteramum,ceftetrame" 0.4 "g" "100047-0,76144-5"
@@ -162,7 +162,7 @@
"CYC" 6234 "Cycloserine" "Oxazolidinones" "J04AB01,QJ04AB01" "Drugs for treatment of tuberculosis" "Antibiotics" "cycl,cyclos" "cicloserina,closina,cyclorin,cycloserin,cycloserinum,farmiserina,levcicloserina,levcycloserine,levcycloserinum,micoserina,miroserina,miroseryn,novoserin,oxamicina,oxamycin,seromycin,tebemicina,wasserina" 0.75 "g" "16702-3,18914-2,212-1,213-9,214-7,215-4,23608-3,25207-2,25208-0,25209-8,25251-0,3519-6,55667-0" "CYC" 6234 "Cycloserine" "Oxazolidinones" "J04AB01,QJ04AB01" "Drugs for treatment of tuberculosis" "Antibiotics" "cycl,cyclos" "cicloserina,closina,cyclorin,cycloserin,cycloserinum,farmiserina,levcicloserina,levcycloserine,levcycloserinum,micoserina,miroserina,miroseryn,novoserin,oxamicina,oxamycin,seromycin,tebemicina,wasserina" 0.75 "g" "16702-3,18914-2,212-1,213-9,214-7,215-4,23608-3,25207-2,25208-0,25209-8,25251-0,3519-6,55667-0"
"DAL" 23724878 "Dalbavancin" "Glycopeptides" "J01XA04,QJ01XA04" "Other antibacterials" "Glycopeptide antibacterials" "dalb,dalbav" "dalbavancina,dalvance,xydalba,zeven" 1.5 "g" "41688-3,41689-1,41690-9,41734-5" "DAL" 23724878 "Dalbavancin" "Glycopeptides" "J01XA04,QJ01XA04" "Other antibacterials" "Glycopeptide antibacterials" "dalb,dalbav" "dalbavancina,dalvance,xydalba,zeven" 1.5 "g" "41688-3,41689-1,41690-9,41734-5"
"DAN" 71335 "Danofloxacin" "Fluoroquinolones" "QJ01MA92" "danofl" "advocin,danofloxacine,danofloxacino,danofloxacinum" "73601-7,73623-1,73646-2" "DAN" 71335 "Danofloxacin" "Fluoroquinolones" "QJ01MA92" "danofl" "advocin,danofloxacine,danofloxacino,danofloxacinum" "73601-7,73623-1,73646-2"
"DPS" 2955 "Dapsone" "Other antibacterials" "D10AX05,J04BA02,QD10AX05,QJ04BA02" "Drugs for treatment of lepra" "Drugs for treatment of lepra" "NA" "aczone,atrisone,avlosulfon,avlosulfone,avlosulphone,benzenamide,benzenamine,bissulfone,bissulphone,croysulfone,croysulphone,dapson,dapsona,dapsonum,daspone,diaphenylsulfon,diaphenylsulfone,diaphenylsulphon,diaphenylsulphone,diphenasone,diphone,disulfone,disulone,disulphone,dubronax,dumitone,eporal,medapsol,novophone,servidapson,sulfadione,sulfona,sulfonyldianiline,sulphadione,sulphonyldianiline,tarimyl,udolac,undolac" 50 "mg" "51698-9,9747-7" "DPS" 2955 "Dapsone" "Other antibacterials" "D10AX05,J04BA02,QD10AX05,QJ04BA02" "Drugs for treatment of lepra" "Drugs for treatment of lepra" "dao" "aczone,atrisone,avlosulfon,avlosulfone,avlosulphone,benzenamide,benzenamine,bissulfone,bissulphone,croysulfone,croysulphone,dapson,dapsona,dapsonum,daspone,diaphenylsulfon,diaphenylsulfone,diaphenylsulphon,diaphenylsulphone,diphenasone,diphone,disulfone,disulone,disulphone,dubronax,dumitone,eporal,medapsol,novophone,servidapson,sulfadione,sulfona,sulfonyldianiline,sulphadione,sulphonyldianiline,tarimyl,udolac,undolac" 50 "mg" "51698-9,9747-7"
"DAP" 16134395 "Daptomycin" "Other antibacterials" "J01XX09,QJ01XX09" "Other antibacterials" "Other antibacterials" "dap,dapt,dapt25,dapt50,daptom" "cidecin,cubicin,dapcin,daptomicina,daptomycine,daptomycinum,deptomycin" 0.28 "g" "35787-1,35788-9,35789-7,41691-7" "DAP" 16134395 "Daptomycin" "Other antibacterials" "J01XX09,QJ01XX09" "Other antibacterials" "Other antibacterials" "dap,dapt,dapt25,dapt50,daptom" "cidecin,cubicin,dapcin,daptomicina,daptomycine,daptomycinum,deptomycin" 0.28 "g" "35787-1,35788-9,35789-7,41691-7"
"DFX" 487101 "Delafloxacin" "Fluoroquinolones" "J01MA23,QJ01MA23" "NA" "baxdela,delafloxacinum,quofenix" 0.9 "g" 0.6 "g" "88885-9,90447-4,93790-4" "DFX" 487101 "Delafloxacin" "Fluoroquinolones" "J01MA23,QJ01MA23" "NA" "baxdela,delafloxacinum,quofenix" 0.9 "g" 0.6 "g" "88885-9,90447-4,93790-4"
"DLM" 6480466 "Delamanid" "Antimycobacterials" "J04AK06,QJ04AK06" "Drugs for treatment of tuberculosis" "Other drugs for treatment of tuberculosis" "dela" "deltyba" 0.2 "g" "93851-4,96109-4" "DLM" 6480466 "Delamanid" "Antimycobacterials" "J04AK06,QJ04AK06" "Drugs for treatment of tuberculosis" "Other drugs for treatment of tuberculosis" "dela" "deltyba" 0.2 "g" "93851-4,96109-4"
@@ -184,7 +184,7 @@
"ERV" 54726192 "Eravacycline" "Tetracyclines" "J01AA13,QJ01AA13" "Tetracyclines" "Tetracyclines" "erav" "xerava" 0.14 "g" "100049-6,85423-2,93767-2" "ERV" 54726192 "Eravacycline" "Tetracyclines" "J01AA13,QJ01AA13" "Tetracyclines" "Tetracyclines" "erav" "xerava" 0.14 "g" "100049-6,85423-2,93767-2"
"ETP" 150610 "Ertapenem" "Carbapenems" "J01DH03,QJ01DH03" "Other beta-lactam antibacterials" "Carbapenems" "erta,ertape,etp" "ertapenemsalt,invanz" 1 "g" "101486-9,35799-6,35800-2,35801-0,35802-8" "ETP" 150610 "Ertapenem" "Carbapenems" "J01DH03,QJ01DH03" "Other beta-lactam antibacterials" "Carbapenems" "erta,ertape,etp" "ertapenemsalt,invanz" 1 "g" "101486-9,35799-6,35800-2,35801-0,35802-8"
"ERY" 12560 "Erythromycin" "Macrolides/lincosamides" "D10AF02,J01FA01,QD10AF02,QJ01FA01,QJ51FA01,QS01AA17,S01AA17" "Macrolides, lincosamides and streptogramins" "Macrolides" "e,em,ery,ery32,eryt,eryth" "abboticin,abomacetin,acneryne,acnesol,aknemycin,aknin,benzamycin,derimer,deripil,dotycin,dumotrycin,emgel,emuvin,emycin,endoeritrin,erecin,erisone,eritomicina,eritrocina,eritromicina,ermycin,eryacne,eryacnen,erycen,erycette,erycinum,eryderm,erydermer,erygel,eryhexal,erymax,erymed,erysafe,erytab,erythro,erythroderm,erythrogran,erythroguent,erythromast,erythromid,erythromycine,erythromycinum,erytop,erytrociclin,ilocaps,ilosone,iloticina,ilotycin,inderm,latotryd,lederpax,mephamycin,mercina,oftamolets,pantoderm,pantodrin,pantomicina,pharyngocin,primacine,propiocine,proterytrin,retcin,robimycin,sansac,spotex,staticin,stiemicyn,stiemycin,tiprocin,torlamicina,wemid" 2 "g" 1 "g" "100050-4,11576-6,12298-6,16829-4,16830-2,18919-1,18920-9,20380-2,232-9,233-7,234-5,235-2,236-0,23633-1,237-8,238-6,239-4,25224-7,25275-9,3597-2,7009-4" "ERY" 12560 "Erythromycin" "Macrolides/lincosamides" "D10AF02,J01FA01,QD10AF02,QJ01FA01,QJ51FA01,QS01AA17,S01AA17" "Macrolides, lincosamides and streptogramins" "Macrolides" "e,em,ery,ery32,eryt,eryth" "abboticin,abomacetin,acneryne,acnesol,aknemycin,aknin,benzamycin,derimer,deripil,dotycin,dumotrycin,emgel,emuvin,emycin,endoeritrin,erecin,erisone,eritomicina,eritrocina,eritromicina,ermycin,eryacne,eryacnen,erycen,erycette,erycinum,eryderm,erydermer,erygel,eryhexal,erymax,erymed,erysafe,erytab,erythro,erythroderm,erythrogran,erythroguent,erythromast,erythromid,erythromycine,erythromycinum,erytop,erytrociclin,ilocaps,ilosone,iloticina,ilotycin,inderm,latotryd,lederpax,mephamycin,mercina,oftamolets,pantoderm,pantodrin,pantomicina,pharyngocin,primacine,propiocine,proterytrin,retcin,robimycin,sansac,spotex,staticin,stiemicyn,stiemycin,tiprocin,torlamicina,wemid" 2 "g" 1 "g" "100050-4,11576-6,12298-6,16829-4,16830-2,18919-1,18920-9,20380-2,232-9,233-7,234-5,235-2,236-0,23633-1,237-8,238-6,239-4,25224-7,25275-9,3597-2,7009-4"
"ETH" 14052 "Ethambutol" "Antimycobacterials" "J04AK02,QJ04AK02" "Drugs for treatment of tuberculosis" "Other drugs for treatment of tuberculosis" "etha,ethamb" "aethambutolum,dadibutol,diambutol,etambutol,etambutolo,ethambutolum,myambutol,purderal,servambutol,tibutol" 1.2 "g" 1.2 "g" "100051-2,16841-9,18921-7,20381-0,23625-7,240-2,241-0,242-8,243-6,25187-6,25194-2,25195-9,25230-4,25404-5,3607-9,42645-2,42646-0,55154-9,55674-6,56025-0,7010-2,89491-5" "ETH" 14052 "Ethambutol" "Antimycobacterials" "J04AK02,QJ04AK02" "Drugs for treatment of tuberculosis" "Other drugs for treatment of tuberculosis" "emb,etha,ethamb" "aethambutolum,dadibutol,diambutol,etambutol,etambutolo,ethambutolum,myambutol,purderal,servambutol,tibutol" 1.2 "g" 1.2 "g" "100051-2,16841-9,18921-7,20381-0,23625-7,240-2,241-0,242-8,243-6,25187-6,25194-2,25195-9,25230-4,25404-5,3607-9,42645-2,42646-0,55154-9,55674-6,56025-0,7010-2,89491-5"
"ETI" 456476 "Ethambutol/isoniazid" "Antimycobacterials" "J04AM03,QJ04AM03" "Drugs for treatment of tuberculosis" "Combinations of drugs for treatment of tuberculosis" "NA" "NA" "NA" "ETI" 456476 "Ethambutol/isoniazid" "Antimycobacterials" "J04AM03,QJ04AM03" "Drugs for treatment of tuberculosis" "Combinations of drugs for treatment of tuberculosis" "NA" "NA" "NA"
"ETI1" 2761171 "Ethionamide" "Antimycobacterials" "J04AD03,QJ04AD03" "Drugs for treatment of tuberculosis" "Thiocarbamide derivatives" "ethi,ethion" "aethionamidum,aetina,aetiva,amidazin,amidazine,atina,ethimide,ethina,ethinamide,ethionamidum,ethioniamide,ethylisothiamide,ethyonomide,etimid,etiocidan,etionamid,etionamida,etionamide,etioniamid,etionid,etionizin,etionizina,etionizine,fatoliamid,iridocin,iridozin,isothin,isotiamida,itiocide,nicotion,nisotin,nizotin,rigenicid,sertinon,teberus,thianid,thianide,thioamide,thiodine,thiomid,thioniden,tianid,tiomid,trecator,trekator,trescatyl,trescazide,tubenamide,tubermin,tuberoid,tuberoson" 0.75 "g" "16099-4,16845-0,18922-5,20382-8,23617-4,25183-5,25196-7,25198-3,25231-2,41693-3,42647-8,42648-6,7011-0,96110-2" "ETI1" 2761171 "Ethionamide" "Antimycobacterials" "J04AD03,QJ04AD03" "Drugs for treatment of tuberculosis" "Thiocarbamide derivatives" "ethi,ethion" "aethionamidum,aetina,aetiva,amidazin,amidazine,atina,ethimide,ethina,ethinamide,ethionamidum,ethioniamide,ethylisothiamide,ethyonomide,etimid,etiocidan,etionamid,etionamida,etionamide,etioniamid,etionid,etionizin,etionizina,etionizine,fatoliamid,iridocin,iridozin,isothin,isotiamida,itiocide,nicotion,nisotin,nizotin,rigenicid,sertinon,teberus,thianid,thianide,thioamide,thiodine,thiomid,thioniden,tianid,tiomid,trecator,trekator,trescatyl,trescazide,tubenamide,tubermin,tuberoid,tuberoson" 0.75 "g" "16099-4,16845-0,18922-5,20382-8,23617-4,25183-5,25196-7,25198-3,25231-2,41693-3,42647-8,42648-6,7011-0,96110-2"
"ETO" 6034 "Ethopabate" "Other antibacterials" "QP51AX17" "NA" "ethopabat" "NA" "ETO" 6034 "Ethopabate" "Other antibacterials" "QP51AX17" "NA" "ethopabat" "NA"
@@ -202,7 +202,7 @@
"FLM" 3374 "Flumequine" "Quinolones" "J01MB07,QJ01MB07" "Quinolone antibacterials" "Other quinolones" "flumeq" "apurone,fantacin,flumequina,flumequino,flumequinum,flumigal,flumiquil,flumisol,flumix,imequyl" 1.2 "g" "55675-3,55676-1,55677-9,55678-7" "FLM" 3374 "Flumequine" "Quinolones" "J01MB07,QJ01MB07" "Quinolone antibacterials" "Other quinolones" "flumeq" "apurone,fantacin,flumequina,flumequino,flumequinum,flumigal,flumiquil,flumisol,flumix,imequyl" 1.2 "g" "55675-3,55676-1,55677-9,55678-7"
"FLR1" 71260 "Flurithromycin" "Macrolides/lincosamides" "J01FA14,QJ01FA14" "Macrolides, lincosamides and streptogramins" "Macrolides" "NA" "abbot,beritromicina,berythromycin,berythromycine,berythromycinum,flurithromycine,flurithromycinum,fluritromicina,fluritromycinum,flurizic,mizar" 0.75 "g" "NA" "FLR1" 71260 "Flurithromycin" "Macrolides/lincosamides" "J01FA14,QJ01FA14" "Macrolides, lincosamides and streptogramins" "Macrolides" "NA" "abbot,beritromicina,berythromycin,berythromycine,berythromycinum,flurithromycine,flurithromycinum,fluritromicina,fluritromycinum,flurizic,mizar" 0.75 "g" "NA"
"FFL" 214356 "Fosfluconazole" "Antifungals/antimycotics" "NA" "NA" "fosfluconazol,procif,prodif" "NA" "FFL" 214356 "Fosfluconazole" "Antifungals/antimycotics" "NA" "NA" "fosfluconazol,procif,prodif" "NA"
"FOS" 446987 "Fosfomycin" "Other antibacterials" "J01XX01,QJ01XX01,QS02AA17,S02AA17" "Other antibacterials" "Other antibacterials" "ff,fm,fo,fof,fos,fosf,fosfom,fosmyc" "fosfocina,fosfomicin,fosfomicina,fosfomycine,fosfomycinum,fosfonomycin,infectophos,phosphonemycin,phosphonomycin,veramina" 3 "g" 8 "g" "25596-8,25653-7,35809-3,35810-1" "FOS" 446987 "Fosfomycin" "Phosphonics" "J01XX01,QJ01XX01,QS02AA17,S02AA17" "Other antibacterials" "Other antibacterials" "ff,fm,fo,fof,fos,fosf,fosfom,fosmyc" "fosfocina,fosfomicin,fosfomicina,fosfomycine,fosfomycinum,fosfonomycin,infectophos,phosphonemycin,phosphonomycin,veramina" 3 "g" 8 "g" "25596-8,25653-7,35809-3,35810-1"
"FMD" 572 "Fosmidomycin" "Other antibacterials" "NA" "NA" "fosmidomicina,fosmidomycina,fosmidomycine,fosmidomycinsalt,fosmidomycinum" "NA" "FMD" 572 "Fosmidomycin" "Other antibacterials" "NA" "NA" "fosmidomicina,fosmidomycina,fosmidomycine,fosmidomycinsalt,fosmidomycinum" "NA"
"FRM" 8378 "Framycetin" "Aminoglycosides" "D09AA01,QD09AA01,QJ01GB91,QR01AX08,QS01AA07,R01AX08,S01AA07" "fram,framyc" "actilin,actiline,antibiotique,bycomycin,enterfram,fradiomycin,fradiomycinum,framicetina,framidal,framycetine,framycetinum,framycin,framygen,francetin,jernadex,myacyne,mycerin,mycifradin,neobrettin,neolate,neomas,neomcin,neomicina,neomin,neomycine,neomycinum,nivemycin,soframycin,soframycine" "18926-6,257-6,258-4,259-2,260-0,55679-5" "FRM" 8378 "Framycetin" "Aminoglycosides" "D09AA01,QD09AA01,QJ01GB91,QR01AX08,QS01AA07,R01AX08,S01AA07" "fram,framyc" "actilin,actiline,antibiotique,bycomycin,enterfram,fradiomycin,fradiomycinum,framicetina,framidal,framycetine,framycetinum,framycin,framygen,francetin,jernadex,myacyne,mycerin,mycifradin,neobrettin,neolate,neomas,neomcin,neomicina,neomin,neomycine,neomycinum,nivemycin,soframycin,soframycine" "18926-6,257-6,258-4,259-2,260-0,55679-5"
"FUR" 6870646 "Furazidin" "Other antibacterials" "J01XE03,QJ01XE03" "Other antibacterials" "Nitrofuran derivatives" "NA" "akritoin,furagin,furaginum,furamag,furazidine,hydantoin" 0.3 "g" "NA" "FUR" 6870646 "Furazidin" "Other antibacterials" "J01XE03,QJ01XE03" "Other antibacterials" "Nitrofuran derivatives" "NA" "akritoin,furagin,furaginum,furamag,furazidine,hydantoin" 0.3 "g" "NA"
@@ -268,7 +268,7 @@
"MET" 6087 "Meticillin" "Beta-lactams/penicillins" "J01CF03,QJ01CF03,QJ51CF03" "Beta-lactam antibacterials, penicillins" "Beta-lactamase resistant penicillins" "methic,meti" "belfacillin,celbenin,celpilline,cinopenil,dimocillin,estafcilina,flabelline,lucopenin,metacillin,methcillin,methicillin,methicillinanhydrous,methicillinhydrate,methicillinsalt,methicillinum,methycillin,meticilina,meticillina,meticilline,meticillinsalt,meticillinum,penaureus,penysol,staficyn,staphcillin,synticillin" 4 "g" "NA" "MET" 6087 "Meticillin" "Beta-lactams/penicillins" "J01CF03,QJ01CF03,QJ51CF03" "Beta-lactam antibacterials, penicillins" "Beta-lactamase resistant penicillins" "methic,meti" "belfacillin,celbenin,celpilline,cinopenil,dimocillin,estafcilina,flabelline,lucopenin,metacillin,methcillin,methicillin,methicillinanhydrous,methicillinhydrate,methicillinsalt,methicillinum,methycillin,meticilina,meticillina,meticilline,meticillinsalt,meticillinum,penaureus,penysol,staficyn,staphcillin,synticillin" 4 "g" "NA"
"MTP" 68590 "Metioprim" "Other antibacterials" "NA" "NA" "methioprim,metioprima,metioprime,metioprimum" "NA" "MTP" 68590 "Metioprim" "Other antibacterials" "NA" "NA" "methioprim,metioprima,metioprime,metioprimum" "NA"
"MXT" 3047729 "Metioxate" "Fluoroquinolones" "NA" "NA" "metioxato,metioxatum" "NA" "MXT" 3047729 "Metioxate" "Fluoroquinolones" "NA" "NA" "metioxato,metioxatum" "NA"
"MTR" 4173 "Metronidazole" "Other antibacterials" "A01AB17,D06BX01,G01AF01,J01XD01,P01AB01,QA01AB17,QD06BX01,QG01AF01,QJ01XD01,QP51CA01" "Other antibacterials" "Imidazole derivatives" "metr,metron,mnz" "acromona,anagiardil,arilin,atrivyl,bexon,clont,danizol,deflamon,donnan,efloran,elyzol,entizol,eumin,flagemona,flagesol,flagil,flagyl,flazol,flegyl,florazole,fossyol,giatricol,gineflavir,givagil,hydroxydimetridazole,hydroxymetronidazole,izoklion,klion,klont,mepagyl,meronidal,metric,metrolag,metrolyl,metromidol,metronidazolo,metronidazolum,metroplex,metrotop,mexibol,monagyl,monasin,nalox,nidagyl,noritate,novonidazol,nuvessa,orvagil,polibiotic,protostat,rathimed,rosaced,rosased,sanatrichom,satric,takimetol,trichazol,trichex,trichobrol,trichocide,trichomol,trichopal,trichopol,tricocet,tricom,trikacide,trikamon,trikhopol,trikojol,trikozol,trimeks,trivazol,vagilen,vagimid,vandazole,vertisal,wagitran,zadstat,zidoval" 2 "g" 1.5 "g" "10991-8,18946-4,326-9,327-7,328-5,329-3,7031-8" "MTR" 4173 "Metronidazole" "Other antibacterials" "A01AB17,D06BX01,G01AF01,J01XD01,P01AB01,QA01AB17,QD06BX01,QG01AF01,QJ01XD01,QP51CA01" "Other antibacterials" "Imidazole derivatives" "metr,metron,mnz,mtz" "acromona,anagiardil,arilin,atrivyl,bexon,clont,danizol,deflamon,donnan,efloran,elyzol,entizol,eumin,flagemona,flagesol,flagil,flagyl,flazol,flegyl,florazole,fossyol,giatricol,gineflavir,givagil,hydroxydimetridazole,hydroxymetronidazole,izoklion,klion,klont,mepagyl,meronidal,metric,metrolag,metrolyl,metromidol,metronidazolo,metronidazolum,metroplex,metrotop,mexibol,monagyl,monasin,nalox,nidagyl,noritate,novonidazol,nuvessa,orvagil,polibiotic,protostat,rathimed,rosaced,rosased,sanatrichom,satric,takimetol,trichazol,trichex,trichobrol,trichocide,trichomol,trichopal,trichopol,tricocet,tricom,trikacide,trikamon,trikhopol,trikojol,trikozol,trimeks,trivazol,vagilen,vagimid,vandazole,vertisal,wagitran,zadstat,zidoval" 2 "g" 1.5 "g" "10991-8,18946-4,326-9,327-7,328-5,329-3,7031-8"
"MEZ" 656511 "Mezlocillin" "Beta-lactams/penicillins" "J01CA10,QJ01CA10" "Beta-lactam antibacterials, penicillins" "Penicillins with extended spectrum" "mez,mezl,mezlo,mz" "baycipen,baypen,mezlin,mezlocilina,mezlocilline,mezlocillinsalt,mezlocillinum,multocillin" 6 "g" "18947-2,330-1,331-9,332-7,333-5,3820-8,41702-2,54194-6,54195-3,54196-1" "MEZ" 656511 "Mezlocillin" "Beta-lactams/penicillins" "J01CA10,QJ01CA10" "Beta-lactam antibacterials, penicillins" "Penicillins with extended spectrum" "mez,mezl,mezlo,mz" "baycipen,baypen,mezlin,mezlocilina,mezlocilline,mezlocillinsalt,mezlocillinum,multocillin" 6 "g" "18947-2,330-1,331-9,332-7,333-5,3820-8,41702-2,54194-6,54195-3,54196-1"
"MSU" "Mezlocillin/sulbactam" "Beta-lactams/penicillins" "NA" "mezsul" "NA" "54194-6,54195-3,54196-1" "MSU" "Mezlocillin/sulbactam" "Beta-lactams/penicillins" "NA" "mezsul" "NA" "54194-6,54195-3,54196-1"
"MIF" 477468 "Micafungin" "Antifungals/antimycotics" "J02AX05,QJ02AX05" "Antimycotics for systemic use" "Other antimycotics for systemic use" "mica,micafu" "fungard,funguard,micafungina,micafunginsalt,mycamine" 0.1 "g" "53812-4,58418-5,65340-2,85048-7" "MIF" 477468 "Micafungin" "Antifungals/antimycotics" "J02AX05,QJ02AX05" "Antimycotics for systemic use" "Other antimycotics for systemic use" "mica,micafu" "fungard,funguard,micafungina,micafunginsalt,mycamine" 0.1 "g" "53812-4,58418-5,65340-2,85048-7"
@@ -339,7 +339,7 @@
"PMR" 5284447 "Pimaricin" "Antifungals/antimycotics" "NA" "natamycin" "delvocid,delvolan,delvopos,mycophyt,myprozine,natacyn,natafucin,natajen,natamatrix,natamax,natamicina,natamycin,natamycine,natamycinum,pimafucin,pimaracin,pimaricine,pimarizin,synogil,tennecetin" "NA" "PMR" 5284447 "Pimaricin" "Antifungals/antimycotics" "NA" "natamycin" "delvocid,delvolan,delvopos,mycophyt,myprozine,natacyn,natafucin,natajen,natamatrix,natamax,natamicina,natamycin,natamycine,natamycinum,pimafucin,pimaracin,pimaricine,pimarizin,synogil,tennecetin" "NA"
"PPA" 4831 "Pipemidic acid" "Quinolones" "J01MB04,QJ01MB04" "Quinolone antibacterials" "Other quinolones" "pipaci,pipz,pizu" "deblaston,dolcol,filtrax,karunomazin,memento,nuril,palin,pipedac,pipemid,pipemidate,pipemidic,pipemidicacid,pipram,pipurin,tractur,uromidin,urosten,uroval" 0.8 "g" "NA" "PPA" 4831 "Pipemidic acid" "Quinolones" "J01MB04,QJ01MB04" "Quinolone antibacterials" "Other quinolones" "pipaci,pipz,pizu" "deblaston,dolcol,filtrax,karunomazin,memento,nuril,palin,pipedac,pipemid,pipemidate,pipemidic,pipemidicacid,pipram,pipurin,tractur,uromidin,urosten,uroval" 0.8 "g" "NA"
"PIP" 43672 "Piperacillin" "Beta-lactams/penicillins" "J01CA12,QJ01CA12" "Beta-lactam antibacterials, penicillins" "Penicillins with extended spectrum" "pi,pip,pipc,pipe,pipera,pp" "penmalin,pentcillin,peperacillin,peracin,piperacilina,piperacillina,piperacilline,piperacillinhydrate,piperacillinum,pipercillin,pipracil,tazocin" 14 "g" "101490-1,101491-9,18969-6,18970-4,25268-4,3972-7,407-7,408-5,409-3,410-1,411-9,412-7,413-5,414-3,54197-9,54198-7,54199-5,55704-1,7043-3,7044-1" "PIP" 43672 "Piperacillin" "Beta-lactams/penicillins" "J01CA12,QJ01CA12" "Beta-lactam antibacterials, penicillins" "Penicillins with extended spectrum" "pi,pip,pipc,pipe,pipera,pp" "penmalin,pentcillin,peperacillin,peracin,piperacilina,piperacillina,piperacilline,piperacillinhydrate,piperacillinum,pipercillin,pipracil,tazocin" 14 "g" "101490-1,101491-9,18969-6,18970-4,25268-4,3972-7,407-7,408-5,409-3,410-1,411-9,412-7,413-5,414-3,54197-9,54198-7,54199-5,55704-1,7043-3,7044-1"
"PIS" "Piperacillin/sulbactam" "Beta-lactams/penicillins" "J01CR05,QJ01CR05" "NA" "NA" 14 "g" "54197-9,54198-7,54199-5,55704-1" "PIS" "Piperacillin/sulbactam" "Beta-lactams/penicillins" "NA" "NA" "NA" 14 "g" "54197-9,54198-7,54199-5,55704-1"
"TZP" 461573 "Piperacillin/tazobactam" "Beta-lactams/penicillins" "J01CR05,QJ01CR05" "Beta-lactam antibacterials, penicillins" "Combinations of penicillins, incl. beta-lactamase inhibitors" "p/t,piptaz,piptazo,pit,pita,pt,ptc,ptz,tzp" "piptazobactam,tazonam,zobactin,zosyn" 14 "g" "101491-9,18970-4,411-9,412-7,413-5,414-3,7044-1" "TZP" 461573 "Piperacillin/tazobactam" "Beta-lactams/penicillins" "J01CR05,QJ01CR05" "Beta-lactam antibacterials, penicillins" "Combinations of penicillins, incl. beta-lactamase inhibitors" "p/t,piptaz,piptazo,pit,pita,pt,ptc,ptz,tzp" "piptazobactam,tazonam,zobactin,zosyn" 14 "g" "101491-9,18970-4,411-9,412-7,413-5,414-3,7044-1"
"PRC" 71978 "Piridicillin" "Beta-lactams/penicillins" "NA" "NA" "NA" "NA" "PRC" 71978 "Piridicillin" "Beta-lactams/penicillins" "NA" "NA" "NA" "NA"
"PRL" 157385 "Pirlimycin" "Macrolides/lincosamides" "QJ51FF90" "pirlim" "pirlimycina,pirlimycine,pirlimycinum,pirsue" "35829-1,35830-9,35831-7" "PRL" 157385 "Pirlimycin" "Macrolides/lincosamides" "QJ51FF90" "pirlim" "pirlimycina,pirlimycine,pirlimycinum,pirsue" "35829-1,35830-9,35831-7"
@@ -370,7 +370,7 @@
"RBC" 44631912 "Ribociclib" "Antifungals/antimycotics" "L01EF02,QL01EF02" "Antimycotics for systemic use" "Triazole derivatives" "ribo" "kisqali" 0.45 "g" "NA" "RBC" 44631912 "Ribociclib" "Antifungals/antimycotics" "L01EF02,QL01EF02" "Antimycotics for systemic use" "Triazole derivatives" "ribo" "kisqali" 0.45 "g" "NA"
"RST" 33042 "Ribostamycin" "Aminoglycosides" "J01GB10,QJ01GB10" "Aminoglycoside antibacterials" "Other aminoglycosides" "NA" "exaluren,hetangmycin,ribastamin,ribostamicina,ribostamycine,ribostamycinum,vistamycin,xylostatin" 1 "g" "NA" "RST" 33042 "Ribostamycin" "Aminoglycosides" "J01GB10,QJ01GB10" "Aminoglycoside antibacterials" "Other aminoglycosides" "NA" "exaluren,hetangmycin,ribastamin,ribostamicina,ribostamycine,ribostamycinum,vistamycin,xylostatin" 1 "g" "NA"
"RID1" 16659285 "Ridinilazole" "Other antibacterials" "NA" "NA" "ridinilazol" "NA" "RID1" 16659285 "Ridinilazole" "Other antibacterials" "NA" "NA" "ridinilazol" "NA"
"RIB" 135398743 "Rifabutin" "Antimycobacterials" "J04AB04,QJ04AB04" "Drugs for treatment of tuberculosis" "Antibiotics" "ansamy,rifb" "alfacid,ansamicin,ansamycins,ansatipin,ansatipine,assatipin,mycobutin,rifabutinum" 0.15 "g" "100699-8,16100-0,16386-5,16387-3,19149-4,20386-9,23630-7,24032-5,25199-1,25200-7,25201-5,42655-1,42656-9,54183-9,96113-6" "RIB" 135398743 "Rifabutin" "Antimycobacterials" "J04AB04,QJ04AB04" "Drugs for treatment of tuberculosis" "Antibiotics" "ansamy,rfb,rifb" "alfacid,ansamicin,ansamycins,ansatipin,ansatipine,assatipin,mycobutin,rifabutinum" 0.15 "g" "100699-8,16100-0,16386-5,16387-3,19149-4,20386-9,23630-7,24032-5,25199-1,25200-7,25201-5,42655-1,42656-9,54183-9,96113-6"
"RIF" 135398735 "Rifampicin" "Antimycobacterials" "J04AB02,QJ04AB02,QJ54AB02" "Drugs for treatment of tuberculosis" "Antibiotics" "rifa,rifamp" "abrifam,archidyn,arficin,arzide,benemicin,doloresum,eremfat,famcin,fenampicin,rifadin,rifadine,rifagen,rifaldazin,rifaldazine,rifaldin,rifam,rifamor,rifampicina,rifampicine,rifampicinum,rifampin,rifamsolin,rifapiam,rifaprodin,rifcin,rifinah,rifobac,rifoldin,rifoldine,riforal,rimactan,rimactane,rimactazid,rimactizid,rimazid,sinerdol,tubocin" 0.6 "g" 0.6 "g" "NA" "RIF" 135398735 "Rifampicin" "Antimycobacterials" "J04AB02,QJ04AB02,QJ54AB02" "Drugs for treatment of tuberculosis" "Antibiotics" "rifa,rifamp" "abrifam,archidyn,arficin,arzide,benemicin,doloresum,eremfat,famcin,fenampicin,rifadin,rifadine,rifagen,rifaldazin,rifaldazine,rifaldin,rifam,rifamor,rifampicina,rifampicine,rifampicinum,rifampin,rifamsolin,rifapiam,rifaprodin,rifcin,rifinah,rifobac,rifoldin,rifoldine,riforal,rimactan,rimactane,rimactazid,rimactizid,rimazid,sinerdol,tubocin" 0.6 "g" 0.6 "g" "NA"
"REI" 135483893 "Rifampicin/ethambutol/isoniazid" "Antimycobacterials" "J04AM07,QJ04AM07" "Drugs for treatment of tuberculosis" "Combinations of drugs for treatment of tuberculosis" "NA" "isonarif,rifamate,rifamazid" "NA" "REI" 135483893 "Rifampicin/ethambutol/isoniazid" "Antimycobacterials" "J04AM07,QJ04AM07" "Drugs for treatment of tuberculosis" "Combinations of drugs for treatment of tuberculosis" "NA" "isonarif,rifamate,rifamazid" "NA"
"RFI" "Rifampicin/isoniazid" "Antimycobacterials" "J04AM02,QJ04AM02" "Drugs for treatment of tuberculosis" "Combinations of drugs for treatment of tuberculosis" "NA" "NA" "NA" "RFI" "Rifampicin/isoniazid" "Antimycobacterials" "J04AM02,QJ04AM02" "Drugs for treatment of tuberculosis" "Combinations of drugs for treatment of tuberculosis" "NA" "NA" "NA"
@@ -391,7 +391,6 @@
"SRC" 54681908 "Sarecycline" "Tetracyclines" "J01AA14,QJ01AA14" "Tetracyclines" "Tetracyclines" "NA" "sareciclina,seysara" 0.1 "g" "NA" "SRC" 54681908 "Sarecycline" "Tetracyclines" "J01AA14,QJ01AA14" "Tetracyclines" "Tetracyclines" "NA" "sareciclina,seysara" 0.1 "g" "NA"
"SRX" 9933415 "Sarmoxicillin" "Beta-lactams/penicillins" "NA" "NA" "sarmoxillina,sarmoxilline,sarmoxillinum" "NA" "SRX" 9933415 "Sarmoxicillin" "Beta-lactams/penicillins" "NA" "NA" "sarmoxillina,sarmoxilline,sarmoxillinum" "NA"
"SEC" 71815 "Secnidazole" "Other antibacterials" "P01AB07" "NA" "flagentyl,secnidal,secnidazolum,secnil,sindose,solosec" 2 "g" "NA" "SEC" 71815 "Secnidazole" "Other antibacterials" "P01AB07" "NA" "flagentyl,secnidal,secnidazolum,secnil,sindose,solosec" 2 "g" "NA"
"SMF" "Simvastatin/fenofibrate" "Antimycobacterials" "C10BA04,QC10BA04" "Drugs for treatment of tuberculosis" "Other drugs for treatment of tuberculosis" "simv" "NA" "NA"
"SIS" 36119 "Sisomicin" "Aminoglycosides" "J01GB08,QJ01GB08" "Aminoglycoside antibacterials" "Other aminoglycosides" "siso,sisomy" "rickamicin,salvamina,sisomicina,sisomicine,sisomicinum,sisomin,sisomycin,sissomicin,sizomycin" 0.24 "g" "18979-5,447-3,448-1,449-9,450-7,55714-0" "SIS" 36119 "Sisomicin" "Aminoglycosides" "J01GB08,QJ01GB08" "Aminoglycoside antibacterials" "Other aminoglycosides" "siso,sisomy" "rickamicin,salvamina,sisomicina,sisomicine,sisomicinum,sisomin,sisomycin,sissomicin,sizomycin" 0.24 "g" "18979-5,447-3,448-1,449-9,450-7,55714-0"
"SIT" 461399 "Sitafloxacin" "Fluoroquinolones" "J01MA21,QJ01MA21" "sitafl" "gracevit" 0.1 "g" "NA" "SIT" 461399 "Sitafloxacin" "Fluoroquinolones" "J01MA21,QJ01MA21" "sitafl" "gracevit" 0.1 "g" "NA"
"SDA" 2724368 "Sodium aminosalicylate" "Antimycobacterials" "J04AA02,QJ04AA02" "Drugs for treatment of tuberculosis" "Aminosalicylic acid and derivatives" "NA" "bactylan,lepasen,monopas,tubersan" 14 "g" 14 "g" "NA" "SDA" 2724368 "Sodium aminosalicylate" "Antimycobacterials" "J04AA02,QJ04AA02" "Drugs for treatment of tuberculosis" "Aminosalicylic acid and derivatives" "NA" "bactylan,lepasen,monopas,tubersan" 14 "g" 14 "g" "NA"
@@ -495,4 +494,4 @@
"VOR" 71616 "Voriconazole" "Antifungals/antimycotics" "J02AC03,QJ02AC03" "Antimycotics for systemic use" "Triazole derivatives" "vori,vorico,vrc" "vfend,voriconazol,voriconazolum,voriconzole,vorikonazole" 0.4 "g" 0.4 "g" "32379-0,35862-2,35863-0,38370-3,41199-1,41200-7,53902-3,73676-9,80553-1,80651-3" "VOR" 71616 "Voriconazole" "Antifungals/antimycotics" "J02AC03,QJ02AC03" "Antimycotics for systemic use" "Triazole derivatives" "vori,vorico,vrc" "vfend,voriconazol,voriconazolum,voriconzole,vorikonazole" 0.4 "g" 0.4 "g" "32379-0,35862-2,35863-0,38370-3,41199-1,41200-7,53902-3,73676-9,80553-1,80651-3"
"XBR" 72144 "Xibornol" "Other antibacterials" "J01XX02,QJ01XX02" "Other antibacterials" "Other antibacterials" "NA" "bactacine,bracen,nanbacine,xibornolo,xibornolum" "NA" "XBR" 72144 "Xibornol" "Other antibacterials" "J01XX02,QJ01XX02" "Other antibacterials" "Other antibacterials" "NA" "bactacine,bracen,nanbacine,xibornolo,xibornolum" "NA"
"ZID" 77846445 "Zidebactam" "Other antibacterials" "NA" "NA" "zidebactamsalt" "NA" "ZID" 77846445 "Zidebactam" "Other antibacterials" "NA" "NA" "zidebactamsalt" "NA"
"ZFD" "Zoliflodacin" "NA" "NA" "NA" "NA" "ZFD" "Zoliflodacin" "NA" "zol" "NA" "NA"

View File

@@ -283,7 +283,7 @@ for (i in 2:length(sheets_to_analyse)) {
guideline_name = guideline_name guideline_name = guideline_name
) )
), ),
error = function(e) message(e$message) error = function(e) message(conditionMessage(e))
) )
} }

Binary file not shown.

Binary file not shown.

BIN
data/esbl_isolates.rda Normal file

Binary file not shown.

View File

@@ -28,8 +28,8 @@ AMR:::reset_all_thrown_messages()
> Now available for Python too! [Click here](./articles/AMR_for_Python.html) to read more. > Now available for Python too! [Click here](./articles/AMR_for_Python.html) to read more.
<div style="display: flex; font-size: 0.8em;"> <div style="display: flex; font-size: 0.8em;">
<p style="text-align:left; width: 50%;"><small><a href="https://amr-for-r.org/">https://amr-for-r.org</a></small></p> <p style="text-align:left; width: 50%;"><small><a href="https://amr-for-r.org/">amr-for-r.org</a></small></p>
<p style="text-align:right; width: 50%;"><small><a href="https://doi.org/10.18637/jss.v104.i03" target="_blank">https://doi.org/10.18637/jss.v104.i03</a></small></p> <p style="text-align:right; width: 50%;"><small><a href="https://doi.org/10.18637/jss.v104.i03" target="_blank">doi.org/10.18637/jss.v104.i03</a></small></p>
</div> </div>
<a href="./reference/clinical_breakpoints.html#response-from-clsi-and-eucast"><img src="./endorsement_clsi_eucast.jpg" class="endorse_img" align="right" height="120" /></a> <a href="./reference/clinical_breakpoints.html#response-from-clsi-and-eucast"><img src="./endorsement_clsi_eucast.jpg" class="endorse_img" align="right" height="120" /></a>
@@ -133,7 +133,7 @@ ggplot(data.frame(mic = some_mic_values,
sir = interpretation), sir = interpretation),
aes(x = group, y = mic, colour = sir)) + aes(x = group, y = mic, colour = sir)) +
theme_minimal() + theme_minimal() +
geom_boxplot(fill = NA, colour = "grey") + geom_boxplot(fill = NA, colour = "grey30") +
geom_jitter(width = 0.25) + geom_jitter(width = 0.25) +
# NEW scale function: plot MIC values to x, y, colour or fill # NEW scale function: plot MIC values to x, y, colour or fill

View File

@@ -27,12 +27,12 @@
<p style="text-align:left; width: 50%;"> <p style="text-align:left; width: 50%;">
<small><a href="https://amr-for-r.org/">https://amr-for-r.org</a></small> <small><a href="https://amr-for-r.org/">amr-for-r.org</a></small>
</p> </p>
<p style="text-align:right; width: 50%;"> <p style="text-align:right; width: 50%;">
<small><a href="https://doi.org/10.18637/jss.v104.i03" target="_blank">https://doi.org/10.18637/jss.v104.i03</a></small> <small><a href="https://doi.org/10.18637/jss.v104.i03" target="_blank">doi.org/10.18637/jss.v104.i03</a></small>
</p> </p>
</div> </div>
@@ -171,14 +171,14 @@ example_isolates %>%
select(bacteria, select(bacteria,
aminoglycosides(), aminoglycosides(),
carbapenems()) carbapenems())
#> Using column 'mo' as input for mo_fullname() #> 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_gram_negative()`
#> Using column 'mo' as input for mo_is_intrinsic_resistant() #> Using column 'mo' as input for `mo_is_intrinsic_resistant()`
#> Determining intrinsic resistance based on 'EUCAST Expected Resistant #> Determining intrinsic resistance based on 'EUCAST Expected Resistant
#> Phenotypes' v1.2 (2023). This note will be shown once per session. #> Phenotypes' v1.2 (2023). This note will be shown once per session.
#> For aminoglycosides() using columns 'GEN' (gentamicin), 'TOB' #> For `aminoglycosides()` using columns 'GEN' (gentamicin), 'TOB'
#> (tobramycin), 'AMK' (amikacin), and 'KAN' (kanamycin) #> (tobramycin), 'AMK' (amikacin), and 'KAN' (kanamycin)
#> For carbapenems() using columns 'IPM' (imipenem) and 'MEM' (meropenem) #> For `carbapenems()` using columns 'IPM' (imipenem) and 'MEM' (meropenem)
#> # A tibble: 35 × 7 #> # A tibble: 35 × 7
#> bacteria GEN TOB AMK KAN IPM MEM #> bacteria GEN TOB AMK KAN IPM MEM
#> <chr> <sir> <sir> <sir> <sir> <sir> <sir> #> <chr> <sir> <sir> <sir> <sir> <sir> <sir>
@@ -215,9 +215,9 @@ output format automatically (such as markdown, LaTeX, HTML, etc.).
``` r ``` r
antibiogram(example_isolates, antibiogram(example_isolates,
antimicrobials = c(aminoglycosides(), carbapenems())) antimicrobials = c(aminoglycosides(), carbapenems()))
#> For aminoglycosides() using columns 'GEN' (gentamicin), 'TOB' #> For `aminoglycosides()` using columns 'GEN' (gentamicin), 'TOB'
#> (tobramycin), 'AMK' (amikacin), and 'KAN' (kanamycin) #> (tobramycin), 'AMK' (amikacin), and 'KAN' (kanamycin)
#> For carbapenems() using columns 'IPM' (imipenem) and 'MEM' (meropenem) #> For `carbapenems()` using columns 'IPM' (imipenem) and 'MEM' (meropenem)
``` ```
| Pathogen | Amikacin | Gentamicin | Imipenem | Kanamycin | Meropenem | Tobramycin | | Pathogen | Amikacin | Gentamicin | Imipenem | Kanamycin | Meropenem | Tobramycin |
@@ -289,7 +289,7 @@ ggplot(data.frame(mic = some_mic_values,
sir = interpretation), sir = interpretation),
aes(x = group, y = mic, colour = sir)) + aes(x = group, y = mic, colour = sir)) +
theme_minimal() + theme_minimal() +
geom_boxplot(fill = NA, colour = "grey") + geom_boxplot(fill = NA, colour = "grey30") +
geom_jitter(width = 0.25) + geom_jitter(width = 0.25) +
# NEW scale function: plot MIC values to x, y, colour or fill # NEW scale function: plot MIC values to x, y, colour or fill
@@ -321,9 +321,9 @@ example_isolates %>%
#> # A tibble: 3 × 5 #> # A tibble: 3 × 5
#> ward GEN_total_R GEN_conf_int TOB_total_R TOB_conf_int #> ward GEN_total_R GEN_conf_int TOB_total_R TOB_conf_int
#> <chr> <dbl> <chr> <dbl> <chr> #> <chr> <dbl> <chr> <dbl> <chr>
#> 1 Clinical 0.2289362 0.205-0.254 0.3147503 0.284-0.347 #> 1 Clinical 0.229 0.205-0.254 0.315 0.284-0.347
#> 2 ICU 0.2902655 0.253-0.33 0.4004739 0.353-0.449 #> 2 ICU 0.290 0.253-0.33 0.400 0.353-0.449
#> 3 Outpatient 0.2 0.131-0.285 0.3676471 0.254-0.493 #> 3 Outpatient 0.2 0.131-0.285 0.368 0.254-0.493
``` ```
Or use [antimicrobial Or use [antimicrobial
@@ -340,22 +340,22 @@ out <- example_isolates %>%
# calculate AMR using resistance(), over all aminoglycosides and polymyxins: # calculate AMR using resistance(), over all aminoglycosides and polymyxins:
summarise(across(c(aminoglycosides(), polymyxins()), summarise(across(c(aminoglycosides(), polymyxins()),
resistance)) resistance))
#> For aminoglycosides() using columns 'GEN' (gentamicin), 'TOB' #> For `aminoglycosides()` using columns 'GEN' (gentamicin), 'TOB'
#> (tobramycin), 'AMK' (amikacin), and 'KAN' (kanamycin) #> (tobramycin), 'AMK' (amikacin), and 'KAN' (kanamycin)
#> For polymyxins() using column 'COL' (colistin) #> For `polymyxins()` using column 'COL' (colistin)
#> Warning: There was 1 warning in `summarise()`. #> Warning: There was 1 warning in `summarise()`.
#> In argument: `across(c(aminoglycosides(), polymyxins()), resistance)`. #> In argument: `across(c(aminoglycosides(), polymyxins()), resistance)`.
#> In group 3: `ward = "Outpatient"`. #> In group 3: `ward = "Outpatient"`.
#> Caused by warning: #> Caused by warning:
#> ! Introducing NA: only 23 results available for KAN in group: ward = #> ! Introducing NA: only 23 results available for KAN in group: ward =
#> "Outpatient" (minimum = 30). #> "Outpatient" (`minimum` = 30).
out out
#> # A tibble: 3 × 6 #> # A tibble: 3 × 6
#> ward GEN TOB AMK KAN COL #> ward GEN TOB AMK KAN COL
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> #> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 Clinical 0.2289362 0.3147503 0.6258993 1 0.7802956 #> 1 Clinical 0.229 0.315 0.626 1 0.780
#> 2 ICU 0.2902655 0.4004739 0.6624473 1 0.8574144 #> 2 ICU 0.290 0.400 0.662 1 0.857
#> 3 Outpatient 0.2 0.3676471 0.6052632 NA 0.8888889 #> 3 Outpatient 0.2 0.368 0.605 NA 0.889
``` ```
``` r ``` r
@@ -364,9 +364,9 @@ out %>% set_ab_names()
#> # A tibble: 3 × 6 #> # A tibble: 3 × 6
#> ward gentamicin tobramycin amikacin kanamycin colistin #> ward gentamicin tobramycin amikacin kanamycin colistin
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> #> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 Clinical 0.2289362 0.3147503 0.6258993 1 0.7802956 #> 1 Clinical 0.229 0.315 0.626 1 0.780
#> 2 ICU 0.2902655 0.4004739 0.6624473 1 0.8574144 #> 2 ICU 0.290 0.400 0.662 1 0.857
#> 3 Outpatient 0.2 0.3676471 0.6052632 NA 0.8888889 #> 3 Outpatient 0.2 0.368 0.605 NA 0.889
``` ```
``` r ``` r
@@ -375,9 +375,9 @@ out %>% set_ab_names(property = "atc")
#> # A tibble: 3 × 6 #> # A tibble: 3 × 6
#> ward J01GB03 J01GB01 J01GB06 J01GB04 J01XB01 #> ward J01GB03 J01GB01 J01GB06 J01GB04 J01XB01
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> #> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 Clinical 0.2289362 0.3147503 0.6258993 1 0.7802956 #> 1 Clinical 0.229 0.315 0.626 1 0.780
#> 2 ICU 0.2902655 0.4004739 0.6624473 1 0.8574144 #> 2 ICU 0.290 0.400 0.662 1 0.857
#> 3 Outpatient 0.2 0.3676471 0.6052632 NA 0.8888889 #> 3 Outpatient 0.2 0.368 0.605 NA 0.889
``` ```
## What else can you do with this package? ## What else can you do with this package?

View File

@@ -4,20 +4,23 @@
\alias{age_groups} \alias{age_groups}
\title{Split Ages into Age Groups} \title{Split Ages into Age Groups}
\usage{ \usage{
age_groups(x, split_at = c(12, 25, 55, 75), na.rm = FALSE) age_groups(x, split_at = c(0, 12, 25, 55, 75), names = NULL,
na.rm = FALSE)
} }
\arguments{ \arguments{
\item{x}{Age, e.g. calculated with \code{\link[=age]{age()}}.} \item{x}{Age, e.g. calculated with \code{\link[=age]{age()}}.}
\item{split_at}{Values to split \code{x} at - the default is age groups 0-11, 12-24, 25-54, 55-74 and 75+. See \emph{Details}.} \item{split_at}{Values to split \code{x} at - the default is age groups 0-11, 12-24, 25-54, 55-74 and 75+. See \emph{Details}.}
\item{names}{Optional names to be given to the various age groups.}
\item{na.rm}{A \link{logical} to indicate whether missing values should be removed.} \item{na.rm}{A \link{logical} to indicate whether missing values should be removed.}
} }
\value{ \value{
Ordered \link{factor} Ordered \link{factor}
} }
\description{ \description{
Split ages into age groups defined by the \code{split} argument. This allows for easier demographic (antimicrobial resistance) analysis. Split ages into age groups defined by the \code{split} argument. This allows for easier demographic (antimicrobial resistance) analysis. The function returns an ordered \link{factor}.
} }
\details{ \details{
To split ages, the input for the \code{split_at} argument can be: To split ages, the input for the \code{split_at} argument can be:
@@ -41,6 +44,7 @@ age_groups(ages, 50)
# split into 0-19, 20-49 and 50+ # split into 0-19, 20-49 and 50+
age_groups(ages, c(20, 50)) age_groups(ages, c(20, 50))
age_groups(ages, c(20, 50), names = c("Under 20 years", "20 to 50 years", "Over 50 years"))
# split into groups of ten years # split into groups of ten years
age_groups(ages, 1:10 * 10) age_groups(ages, 1:10 * 10)

125
man/amr-tidymodels.Rd Normal file
View File

@@ -0,0 +1,125 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/tidymodels.R
\name{amr-tidymodels}
\alias{amr-tidymodels}
\alias{all_mic}
\alias{all_mic_predictors}
\alias{all_sir}
\alias{all_sir_predictors}
\alias{step_mic_log2}
\alias{step_sir_numeric}
\title{AMR Extensions for Tidymodels}
\usage{
all_mic()
all_mic_predictors()
all_sir()
all_sir_predictors()
step_mic_log2(recipe, ..., role = NA, trained = FALSE, columns = NULL,
skip = FALSE, id = recipes::rand_id("mic_log2"))
step_sir_numeric(recipe, ..., role = NA, trained = FALSE, columns = NULL,
skip = FALSE, id = recipes::rand_id("sir_numeric"))
}
\arguments{
\item{recipe}{A recipe object. The step will be added to the sequence of
operations for this recipe.}
\item{...}{One or more selector functions to choose variables for this step.
See \code{\link[recipes:selections]{selections()}} for more details.}
\item{role}{Not used by this step since no new variables are created.}
\item{trained}{A logical to indicate if the quantities for preprocessing have
been estimated.}
\item{skip}{A logical. Should the step be skipped when the recipe is baked by
\code{\link[recipes:bake]{bake()}}? While all operations are baked when \code{\link[recipes:prep]{prep()}} is run, some
operations may not be able to be conducted on new data (e.g. processing the
outcome variable(s)). Care should be taken when using \code{skip = TRUE} as it
may affect the computations for subsequent operations.}
\item{id}{A character string that is unique to this step to identify it.}
}
\description{
This family of functions allows using AMR-specific data types such as \verb{<mic>} and \verb{<sir>} inside \code{tidymodels} pipelines.
}
\details{
You can read more in our online \href{https://amr-for-r.org/articles/AMR_with_tidymodels.html}{AMR with tidymodels introduction}.
Tidyselect helpers include:
\itemize{
\item \code{\link[=all_mic]{all_mic()}} and \code{\link[=all_mic_predictors]{all_mic_predictors()}} to select \verb{<mic>} columns
\item \code{\link[=all_sir]{all_sir()}} and \code{\link[=all_sir_predictors]{all_sir_predictors()}} to select \verb{<sir>} columns
}
Pre-processing pipeline steps include:
\itemize{
\item \code{\link[=step_mic_log2]{step_mic_log2()}} to convert MIC columns to numeric (via \code{as.numeric()}) and apply a log2 transform, to be used with \code{\link[=all_mic_predictors]{all_mic_predictors()}}
\item \code{\link[=step_sir_numeric]{step_sir_numeric()}} to convert SIR columns to numeric (via \code{as.numeric()}), to be used with \code{\link[=all_sir_predictors]{all_sir_predictors()}}: \code{"S"} = 1, \code{"I"}/\code{"SDD"} = 2, \code{"R"} = 3. All other values are rendered \code{NA}. Keep this in mind for further processing, especially if the model does not allow for \code{NA} values.
}
These steps integrate with \code{recipes::recipe()} and work like standard preprocessing steps. They are useful for preparing data for modelling, especially with classification models.
}
\examples{
if (require("tidymodels")) {
# The below approach formed the basis for this paper: DOI 10.3389/fmicb.2025.1582703
# Presence of ESBL genes was predicted based on raw MIC values.
# example data set in the AMR package
esbl_isolates
# Prepare a binary outcome and convert to ordered factor
data <- esbl_isolates \%>\%
mutate(esbl = factor(esbl, levels = c(FALSE, TRUE), ordered = TRUE))
# Split into training and testing sets
split <- initial_split(data)
training_data <- training(split)
testing_data <- testing(split)
# Create and prep a recipe with MIC log2 transformation
mic_recipe <- recipe(esbl ~ ., data = training_data) \%>\%
# Optionally remove non-predictive variables
remove_role(genus, old_role = "predictor") \%>\%
# Apply the log2 transformation to all MIC predictors
step_mic_log2(all_mic_predictors()) \%>\%
# And apply the preparation steps
prep()
# View prepped recipe
mic_recipe
# Apply the recipe to training and testing data
out_training <- bake(mic_recipe, new_data = NULL)
out_testing <- bake(mic_recipe, new_data = testing_data)
# Fit a logistic regression model
fitted <- logistic_reg(mode = "classification") \%>\%
set_engine("glm") \%>\%
fit(esbl ~ ., data = out_training)
# Generate predictions on the test set
predictions <- predict(fitted, out_testing) \%>\%
bind_cols(out_testing)
# Evaluate predictions using standard classification metrics
our_metrics <- metric_set(accuracy, kap, ppv, npv)
metrics <- our_metrics(predictions, truth = esbl, estimate = .pred_class)
# Show performance
metrics
}
}
\seealso{
\code{\link[recipes:recipe]{recipes::recipe()}}, \code{\link[=as.mic]{as.mic()}}, \code{\link[=as.sir]{as.sir()}}
}
\keyword{internal}

View File

@@ -11,7 +11,7 @@
\source{ \source{
\itemize{ \itemize{
\item Bielicki JA \emph{et al.} (2016). \strong{Selecting appropriate empirical antibiotic regimens for paediatric bloodstream infections: application of a Bayesian decision model to local and pooled antimicrobial resistance surveillance data} \emph{Journal of Antimicrobial Chemotherapy} 71(3); \doi{10.1093/jac/dkv397} \item Bielicki JA \emph{et al.} (2016). \strong{Selecting appropriate empirical antibiotic regimens for paediatric bloodstream infections: application of a Bayesian decision model to local and pooled antimicrobial resistance surveillance data} \emph{Journal of Antimicrobial Chemotherapy} 71(3); \doi{10.1093/jac/dkv397}
\item Bielicki JA \emph{et al.} (2020). \strong{Evaluation of the coverage of 3 antibiotic regimens for neonatal sepsis in the hospital setting across Asian countries} \emph{JAMA Netw Open.} 3(2):e1921124; \doi{10.1001.jamanetworkopen.2019.21124} \item Bielicki JA \emph{et al.} (2020). \strong{Evaluation of the coverage of 3 antibiotic regimens for neonatal sepsis in the hospital setting across Asian countries} \emph{JAMA Netw Open.} 3(2):e1921124; \doi{10.1001/jamanetworkopen.2019.21124}
\item Klinker KP \emph{et al.} (2021). \strong{Antimicrobial stewardship and antibiograms: importance of moving beyond traditional antibiograms}. \emph{Therapeutic Advances in Infectious Disease}, May 5;8:20499361211011373; \doi{10.1177/20499361211011373} \item Klinker KP \emph{et al.} (2021). \strong{Antimicrobial stewardship and antibiograms: importance of moving beyond traditional antibiograms}. \emph{Therapeutic Advances in Infectious Disease}, May 5;8:20499361211011373; \doi{10.1177/20499361211011373}
\item Barbieri E \emph{et al.} (2021). \strong{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} \emph{Antimicrobial Resistance & Infection Control} May 1;10(1):74; \doi{10.1186/s13756-021-00939-2} \item Barbieri E \emph{et al.} (2021). \strong{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} \emph{Antimicrobial Resistance & Infection Control} May 1;10(1):74; \doi{10.1186/s13756-021-00939-2}
\item \strong{M39 Analysis and Presentation of Cumulative Antimicrobial Susceptibility Test Data, 5th Edition}, 2022, \emph{Clinical and Laboratory Standards Institute (CLSI)}. \url{https://clsi.org/standards/products/microbiology/documents/m39/}. \item \strong{M39 Analysis and Presentation of Cumulative Antimicrobial Susceptibility Test Data, 5th Edition}, 2022, \emph{Clinical and Laboratory Standards Institute (CLSI)}. \url{https://clsi.org/standards/products/microbiology/documents/m39/}.
@@ -56,6 +56,7 @@ retrieve_wisca_parameters(wisca_model, ...)
\item \code{c(aminoglycosides(), "AMP", "AMC")} \item \code{c(aminoglycosides(), "AMP", "AMC")}
\item \code{c(aminoglycosides(), carbapenems())} \item \code{c(aminoglycosides(), carbapenems())}
} }
\item Column indices using numbers
\item Combination therapy, indicated by using \code{"+"}, with or without \link[=antimicrobial_selectors]{antimicrobial selectors}, e.g.: \item Combination therapy, indicated by using \code{"+"}, with or without \link[=antimicrobial_selectors]{antimicrobial selectors}, e.g.:
\itemize{ \itemize{
\item \code{"cipro + genta"} \item \code{"cipro + genta"}
@@ -163,7 +164,7 @@ Set \code{digits} (defaults to \code{0}) to alter the rounding of the susceptibi
There are various antibiogram types, as summarised by Klinker \emph{et al.} (2021, \doi{10.1177/20499361211011373}), and they are all supported by \code{\link[=antibiogram]{antibiogram()}}. There are various antibiogram types, as summarised by Klinker \emph{et al.} (2021, \doi{10.1177/20499361211011373}), and they are all supported by \code{\link[=antibiogram]{antibiogram()}}.
For clinical coverage estimations, \strong{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 \emph{et al.} (2020, \doi{10.1001.jamanetworkopen.2019.21124}). See the section \emph{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. For clinical coverage estimations, \strong{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 \emph{et al.} (2020, \doi{10.1001/jamanetworkopen.2019.21124}). See the section \emph{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.
\enumerate{ \enumerate{
\item \strong{Traditional Antibiogram} \item \strong{Traditional Antibiogram}

View File

@@ -181,7 +181,7 @@ The \code{\link[=not_intrinsic_resistant]{not_intrinsic_resistant()}} function c
\item \code{\link[=aminoglycosides]{aminoglycosides()}} can select: \cr amikacin (AMK), amikacin/fosfomycin (AKF), apramycin (APR), arbekacin (ARB), astromicin (AST), bekanamycin (BEK), dibekacin (DKB), framycetin (FRM), gentamicin (GEN), gentamicin-high (GEH), habekacin (HAB), hygromycin (HYG), isepamicin (ISE), kanamycin (KAN), kanamycin-high (KAH), kanamycin/cephalexin (KAC), micronomicin (MCR), neomycin (NEO), netilmicin (NET), pentisomicin (PIM), plazomicin (PLZ), propikacin (PKA), ribostamycin (RST), sisomicin (SIS), streptoduocin (STR), streptomycin (STR1), streptomycin-high (STH), tobramycin (TOB), and tobramycin-high (TOH) \item \code{\link[=aminoglycosides]{aminoglycosides()}} can select: \cr amikacin (AMK), amikacin/fosfomycin (AKF), apramycin (APR), arbekacin (ARB), astromicin (AST), bekanamycin (BEK), dibekacin (DKB), framycetin (FRM), gentamicin (GEN), gentamicin-high (GEH), habekacin (HAB), hygromycin (HYG), isepamicin (ISE), kanamycin (KAN), kanamycin-high (KAH), kanamycin/cephalexin (KAC), micronomicin (MCR), neomycin (NEO), netilmicin (NET), pentisomicin (PIM), plazomicin (PLZ), propikacin (PKA), ribostamycin (RST), sisomicin (SIS), streptoduocin (STR), streptomycin (STR1), streptomycin-high (STH), tobramycin (TOB), and tobramycin-high (TOH)
\item \code{\link[=aminopenicillins]{aminopenicillins()}} can select: \cr amoxicillin (AMX) and ampicillin (AMP) \item \code{\link[=aminopenicillins]{aminopenicillins()}} can select: \cr amoxicillin (AMX) and ampicillin (AMP)
\item \code{\link[=antifungals]{antifungals()}} can select: \cr amorolfine (AMO), amphotericin B (AMB), amphotericin B-high (AMH), anidulafungin (ANI), butoconazole (BUT), caspofungin (CAS), ciclopirox (CIX), clotrimazole (CTR), econazole (ECO), fluconazole (FLU), flucytosine (FCT), fosfluconazole (FFL), griseofulvin (GRI), hachimycin (HCH), ibrexafungerp (IBX), isavuconazole (ISV), isoconazole (ISO), itraconazole (ITR), ketoconazole (KET), manogepix (MGX), micafungin (MIF), miconazole (MCZ), nystatin (NYS), oteseconazole (OTE), pimaricin (PMR), posaconazole (POS), rezafungin (RZF), ribociclib (RBC), sulconazole (SUC), terbinafine (TRB), terconazole (TRC), and voriconazole (VOR) \item \code{\link[=antifungals]{antifungals()}} can select: \cr amorolfine (AMO), amphotericin B (AMB), amphotericin B-high (AMH), anidulafungin (ANI), butoconazole (BUT), caspofungin (CAS), ciclopirox (CIX), clotrimazole (CTR), econazole (ECO), fluconazole (FLU), flucytosine (FCT), fosfluconazole (FFL), griseofulvin (GRI), hachimycin (HCH), ibrexafungerp (IBX), isavuconazole (ISV), isoconazole (ISO), itraconazole (ITR), ketoconazole (KET), manogepix (MGX), micafungin (MIF), miconazole (MCZ), nystatin (NYS), oteseconazole (OTE), pimaricin (PMR), posaconazole (POS), rezafungin (RZF), ribociclib (RBC), sulconazole (SUC), terbinafine (TRB), terconazole (TRC), and voriconazole (VOR)
\item \code{\link[=antimycobacterials]{antimycobacterials()}} can select: \cr 4-aminosalicylic acid (AMA), calcium aminosalicylate (CLA), capreomycin (CAP), clofazimine (CLF), delamanid (DLM), enviomycin (ENV), ethambutol (ETH), ethambutol/isoniazid (ETI), ethionamide (ETI1), isoniazid (INH), isoniazid/sulfamethoxazole/trimethoprim/pyridoxine (IST), morinamide (MRN), p-aminosalicylic acid (PAS), pretomanid (PMD), protionamide (PTH), pyrazinamide (PZA), rifabutin (RIB), rifampicin (RIF), rifampicin/ethambutol/isoniazid (REI), rifampicin/isoniazid (RFI), rifampicin/pyrazinamide/ethambutol/isoniazid (RPEI), rifampicin/pyrazinamide/isoniazid (RPI), rifamycin (RFM), rifapentine (RFP), simvastatin/fenofibrate (SMF), sodium aminosalicylate (SDA), streptomycin/isoniazid (STI), terizidone (TRZ), thioacetazone (TAT), thioacetazone/isoniazid (THI1), tiocarlide (TCR), and viomycin (VIO) \item \code{\link[=antimycobacterials]{antimycobacterials()}} can select: \cr 4-aminosalicylic acid (AMA), calcium aminosalicylate (CLA), capreomycin (CAP), clofazimine (CLF), delamanid (DLM), enviomycin (ENV), ethambutol (ETH), ethambutol/isoniazid (ETI), ethionamide (ETI1), isoniazid (INH), isoniazid/sulfamethoxazole/trimethoprim/pyridoxine (IST), morinamide (MRN), p-aminosalicylic acid (PAS), pretomanid (PMD), protionamide (PTH), pyrazinamide (PZA), rifabutin (RIB), rifampicin (RIF), rifampicin/ethambutol/isoniazid (REI), rifampicin/isoniazid (RFI), rifampicin/pyrazinamide/ethambutol/isoniazid (RPEI), rifampicin/pyrazinamide/isoniazid (RPI), rifamycin (RFM), rifapentine (RFP), sodium aminosalicylate (SDA), streptomycin/isoniazid (STI), terizidone (TRZ), thioacetazone (TAT), thioacetazone/isoniazid (THI1), tiocarlide (TCR), and viomycin (VIO)
\item \code{\link[=betalactams]{betalactams()}} can select: \cr amoxicillin (AMX), amoxicillin/clavulanic acid (AMC), amoxicillin/sulbactam (AXS), ampicillin (AMP), ampicillin/sulbactam (SAM), apalcillin (APL), aspoxicillin (APX), azidocillin (AZD), azlocillin (AZL), aztreonam (ATM), aztreonam/avibactam (AZA), aztreonam/nacubactam (ANC), bacampicillin (BAM), benzathine benzylpenicillin (BNB), benzathine phenoxymethylpenicillin (BNP), benzylpenicillin (PEN), benzylpenicillin screening test (PEN-S), biapenem (BIA), carbenicillin (CRB), carindacillin (CRN), carumonam (CAR), cefacetrile (CAC), cefaclor (CEC), cefadroxil (CFR), cefalexin (LEX), cefaloridine (RID), cefalotin (CEP), cefamandole (MAN), cefapirin (HAP), cefatrizine (CTZ), cefazedone (CZD), cefazolin (CZO), cefcapene (CCP), cefcapene pivoxil (CCX), cefdinir (CDR), cefditoren (DIT), cefditoren pivoxil (DIX), cefepime (FEP), cefepime/amikacin (CFA), cefepime/clavulanic acid (CPC), cefepime/enmetazobactam (FPE), cefepime/nacubactam (FNC), cefepime/tazobactam (FPT), cefepime/zidebactam (FPZ), cefetamet (CAT), cefetamet pivoxil (CPI), cefetecol (CCL), cefetrizole (CZL), cefiderocol (FDC), cefixime (CFM), cefmenoxime (CMX), cefmetazole (CMZ), cefodizime (DIZ), cefonicid (CID), cefoperazone (CFP), cefoperazone/sulbactam (CSL), ceforanide (CND), cefoselis (CSE), cefotaxime (CTX), cefotaxime screening test (CTX-S), cefotaxime/clavulanic acid (CTC), cefotaxime/sulbactam (CTS), cefotetan (CTT), cefotiam (CTF), cefotiam hexetil (CHE), cefovecin (FOV), cefoxitin (FOX), cefoxitin screening test (FOX-S), cefozopran (ZOP), cefpimizole (CFZ), cefpiramide (CPM), cefpirome (CPO), cefpodoxime (CPD), cefpodoxime proxetil (CPX), cefpodoxime/clavulanic acid (CDC), cefprozil (CPR), cefquinome (CEQ), cefroxadine (CRD), cefsulodin (CFS), cefsumide (CSU), ceftaroline (CPT), ceftaroline/avibactam (CPA), ceftazidime (CAZ), ceftazidime/avibactam (CZA), ceftazidime/clavulanic acid (CCV), cefteram (CEM), cefteram pivoxil (CPL), ceftezole (CTL), ceftibuten (CTB), ceftiofur (TIO), ceftizoxime (CZX), ceftizoxime alapivoxil (CZP), ceftobiprole (BPR), ceftobiprole medocaril (CFM1), ceftolozane/tazobactam (CZT), ceftriaxone (CRO), ceftriaxone/beta-lactamase inhibitor (CEB), cefuroxime (CXM), cefuroxime axetil (CXA), cephradine (CED), ciclacillin (CIC), clometocillin (CLM), cloxacillin (CLO), dicloxacillin (DIC), doripenem (DOR), epicillin (EPC), ertapenem (ETP), flucloxacillin (FLC), hetacillin (HET), imipenem (IPM), imipenem/EDTA (IPE), imipenem/relebactam (IMR), latamoxef (LTM), lenampicillin (LEN), loracarbef (LOR), mecillinam (MEC), meropenem (MEM), meropenem/nacubactam (MNC), meropenem/vaborbactam (MEV), metampicillin (MTM), meticillin (MET), mezlocillin (MEZ), mezlocillin/sulbactam (MSU), nafcillin (NAF), oxacillin (OXA), oxacillin screening test (OXA-S), panipenem (PAN), penamecillin (PNM), penicillin/novobiocin (PNO), penicillin/sulbactam (PSU), pheneticillin (PHE), phenoxymethylpenicillin (PHN), piperacillin (PIP), piperacillin/sulbactam (PIS), piperacillin/tazobactam (TZP), piridicillin (PRC), pivampicillin (PVM), pivmecillinam (PME), procaine benzylpenicillin (PRB), propicillin (PRP), razupenem (RZM), ritipenem (RIT), ritipenem acoxil (RIA), sarmoxicillin (SRX), sulbenicillin (SBC), sultamicillin (SLT6), talampicillin (TAL), tebipenem (TBP), temocillin (TEM), ticarcillin (TIC), ticarcillin/clavulanic acid (TCC), and tigemonam (TMN) \item \code{\link[=betalactams]{betalactams()}} can select: \cr amoxicillin (AMX), amoxicillin/clavulanic acid (AMC), amoxicillin/sulbactam (AXS), ampicillin (AMP), ampicillin/sulbactam (SAM), apalcillin (APL), aspoxicillin (APX), azidocillin (AZD), azlocillin (AZL), aztreonam (ATM), aztreonam/avibactam (AZA), aztreonam/nacubactam (ANC), bacampicillin (BAM), benzathine benzylpenicillin (BNB), benzathine phenoxymethylpenicillin (BNP), benzylpenicillin (PEN), benzylpenicillin screening test (PEN-S), biapenem (BIA), carbenicillin (CRB), carindacillin (CRN), carumonam (CAR), cefacetrile (CAC), cefaclor (CEC), cefadroxil (CFR), cefalexin (LEX), cefaloridine (RID), cefalotin (CEP), cefamandole (MAN), cefapirin (HAP), cefatrizine (CTZ), cefazedone (CZD), cefazolin (CZO), cefcapene (CCP), cefcapene pivoxil (CCX), cefdinir (CDR), cefditoren (DIT), cefditoren pivoxil (DIX), cefepime (FEP), cefepime/amikacin (CFA), cefepime/clavulanic acid (CPC), cefepime/enmetazobactam (FPE), cefepime/nacubactam (FNC), cefepime/tazobactam (FPT), cefepime/zidebactam (FPZ), cefetamet (CAT), cefetamet pivoxil (CPI), cefetecol (CCL), cefetrizole (CZL), cefiderocol (FDC), cefixime (CFM), cefmenoxime (CMX), cefmetazole (CMZ), cefodizime (DIZ), cefonicid (CID), cefoperazone (CFP), cefoperazone/sulbactam (CSL), ceforanide (CND), cefoselis (CSE), cefotaxime (CTX), cefotaxime screening test (CTX-S), cefotaxime/clavulanic acid (CTC), cefotaxime/sulbactam (CTS), cefotetan (CTT), cefotiam (CTF), cefotiam hexetil (CHE), cefovecin (FOV), cefoxitin (FOX), cefoxitin screening test (FOX-S), cefozopran (ZOP), cefpimizole (CFZ), cefpiramide (CPM), cefpirome (CPO), cefpodoxime (CPD), cefpodoxime proxetil (CPX), cefpodoxime/clavulanic acid (CDC), cefprozil (CPR), cefquinome (CEQ), cefroxadine (CRD), cefsulodin (CFS), cefsumide (CSU), ceftaroline (CPT), ceftaroline/avibactam (CPA), ceftazidime (CAZ), ceftazidime/avibactam (CZA), ceftazidime/clavulanic acid (CCV), cefteram (CEM), cefteram pivoxil (CPL), ceftezole (CTL), ceftibuten (CTB), ceftiofur (TIO), ceftizoxime (CZX), ceftizoxime alapivoxil (CZP), ceftobiprole (BPR), ceftobiprole medocaril (CFM1), ceftolozane/tazobactam (CZT), ceftriaxone (CRO), ceftriaxone/beta-lactamase inhibitor (CEB), cefuroxime (CXM), cefuroxime axetil (CXA), cephradine (CED), ciclacillin (CIC), clometocillin (CLM), cloxacillin (CLO), dicloxacillin (DIC), doripenem (DOR), epicillin (EPC), ertapenem (ETP), flucloxacillin (FLC), hetacillin (HET), imipenem (IPM), imipenem/EDTA (IPE), imipenem/relebactam (IMR), latamoxef (LTM), lenampicillin (LEN), loracarbef (LOR), mecillinam (MEC), meropenem (MEM), meropenem/nacubactam (MNC), meropenem/vaborbactam (MEV), metampicillin (MTM), meticillin (MET), mezlocillin (MEZ), mezlocillin/sulbactam (MSU), nafcillin (NAF), oxacillin (OXA), oxacillin screening test (OXA-S), panipenem (PAN), penamecillin (PNM), penicillin/novobiocin (PNO), penicillin/sulbactam (PSU), pheneticillin (PHE), phenoxymethylpenicillin (PHN), piperacillin (PIP), piperacillin/sulbactam (PIS), piperacillin/tazobactam (TZP), piridicillin (PRC), pivampicillin (PVM), pivmecillinam (PME), procaine benzylpenicillin (PRB), propicillin (PRP), razupenem (RZM), ritipenem (RIT), ritipenem acoxil (RIA), sarmoxicillin (SRX), sulbenicillin (SBC), sultamicillin (SLT6), talampicillin (TAL), tebipenem (TBP), temocillin (TEM), ticarcillin (TIC), ticarcillin/clavulanic acid (TCC), and tigemonam (TMN)
\item \code{\link[=betalactams_with_inhibitor]{betalactams_with_inhibitor()}} can select: \cr amoxicillin/clavulanic acid (AMC), amoxicillin/sulbactam (AXS), ampicillin/sulbactam (SAM), aztreonam/avibactam (AZA), aztreonam/nacubactam (ANC), cefepime/amikacin (CFA), cefepime/clavulanic acid (CPC), cefepime/enmetazobactam (FPE), cefepime/nacubactam (FNC), cefepime/tazobactam (FPT), cefepime/zidebactam (FPZ), cefoperazone/sulbactam (CSL), cefotaxime/clavulanic acid (CTC), cefotaxime/sulbactam (CTS), cefpodoxime/clavulanic acid (CDC), ceftaroline/avibactam (CPA), ceftazidime/avibactam (CZA), ceftazidime/clavulanic acid (CCV), ceftolozane/tazobactam (CZT), ceftriaxone/beta-lactamase inhibitor (CEB), imipenem/relebactam (IMR), meropenem/nacubactam (MNC), meropenem/vaborbactam (MEV), mezlocillin/sulbactam (MSU), penicillin/novobiocin (PNO), penicillin/sulbactam (PSU), piperacillin/sulbactam (PIS), piperacillin/tazobactam (TZP), and ticarcillin/clavulanic acid (TCC) \item \code{\link[=betalactams_with_inhibitor]{betalactams_with_inhibitor()}} can select: \cr amoxicillin/clavulanic acid (AMC), amoxicillin/sulbactam (AXS), ampicillin/sulbactam (SAM), aztreonam/avibactam (AZA), aztreonam/nacubactam (ANC), cefepime/amikacin (CFA), cefepime/clavulanic acid (CPC), cefepime/enmetazobactam (FPE), cefepime/nacubactam (FNC), cefepime/tazobactam (FPT), cefepime/zidebactam (FPZ), cefoperazone/sulbactam (CSL), cefotaxime/clavulanic acid (CTC), cefotaxime/sulbactam (CTS), cefpodoxime/clavulanic acid (CDC), ceftaroline/avibactam (CPA), ceftazidime/avibactam (CZA), ceftazidime/clavulanic acid (CCV), ceftolozane/tazobactam (CZT), ceftriaxone/beta-lactamase inhibitor (CEB), imipenem/relebactam (IMR), meropenem/nacubactam (MNC), meropenem/vaborbactam (MEV), mezlocillin/sulbactam (MSU), penicillin/novobiocin (PNO), penicillin/sulbactam (PSU), piperacillin/sulbactam (PIS), piperacillin/tazobactam (TZP), and ticarcillin/clavulanic acid (TCC)
\item \code{\link[=carbapenems]{carbapenems()}} can select: \cr biapenem (BIA), doripenem (DOR), ertapenem (ETP), imipenem (IPM), imipenem/EDTA (IPE), imipenem/relebactam (IMR), meropenem (MEM), meropenem/nacubactam (MNC), meropenem/vaborbactam (MEV), panipenem (PAN), razupenem (RZM), ritipenem (RIT), ritipenem acoxil (RIA), and tebipenem (TBP) \item \code{\link[=carbapenems]{carbapenems()}} can select: \cr biapenem (BIA), doripenem (DOR), ertapenem (ETP), imipenem (IPM), imipenem/EDTA (IPE), imipenem/relebactam (IMR), meropenem (MEM), meropenem/nacubactam (MNC), meropenem/vaborbactam (MEV), panipenem (PAN), razupenem (RZM), ritipenem (RIT), ritipenem acoxil (RIA), and tebipenem (TBP)

View File

@@ -5,9 +5,9 @@
\alias{antimicrobials} \alias{antimicrobials}
\alias{antibiotics} \alias{antibiotics}
\alias{antivirals} \alias{antivirals}
\title{Data Sets with 617 Antimicrobial Drugs} \title{Data Sets with 616 Antimicrobial Drugs}
\format{ \format{
\subsection{For the \link{antimicrobials} data set: a \link[tibble:tibble]{tibble} with 497 observations and 14 variables:}{ \subsection{For the \link{antimicrobials} data set: a \link[tibble:tibble]{tibble} with 496 observations and 14 variables:}{
\itemize{ \itemize{
\item \code{ab}\cr antimicrobial ID as used in this package (such as \code{AMC}), using the official EARS-Net (European Antimicrobial Resistance Surveillance Network) codes where available. \emph{\strong{This is a unique identifier.}} \item \code{ab}\cr antimicrobial ID as used in this package (such as \code{AMC}), using the official EARS-Net (European Antimicrobial Resistance Surveillance Network) codes where available. \emph{\strong{This is a unique identifier.}}
\item \code{cid}\cr Compound ID as found in PubChem. \emph{\strong{This is a unique identifier.}} \item \code{cid}\cr Compound ID as found in PubChem. \emph{\strong{This is a unique identifier.}}
@@ -50,7 +50,7 @@ LOINC:
} }
} }
An object of class \code{deprecated_amr_dataset} (inherits from \code{tbl_df}, \code{tbl}, \code{data.frame}) with 497 rows and 14 columns. An object of class \code{deprecated_amr_dataset} (inherits from \code{tbl_df}, \code{tbl}, \code{data.frame}) with 496 rows and 14 columns.
An object of class \code{tbl_df} (inherits from \code{tbl}, \code{data.frame}) with 120 rows and 11 columns. An object of class \code{tbl_df} (inherits from \code{tbl}, \code{data.frame}) with 120 rows and 11 columns.
} }

View File

@@ -75,7 +75,9 @@ sir_interpretation_history(clean = FALSE)
\arguments{ \arguments{
\item{x}{Vector of values (for class \code{\link{mic}}: MIC values in mg/L, for class \code{\link{disk}}: a disk diffusion radius in millimetres).} \item{x}{Vector of values (for class \code{\link{mic}}: MIC values in mg/L, for class \code{\link{disk}}: a disk diffusion radius in millimetres).}
\item{...}{For using on a \link{data.frame}: names of columns to apply \code{\link[=as.sir]{as.sir()}} on (supports tidy selection such as \code{column1:column4}). Otherwise: arguments passed on to methods.} \item{...}{For using on a \link{data.frame}: selection of columns to apply \code{as.sir()} to. Supports \link[tidyselect:starts_with]{tidyselect language} such as \code{where(is.mic)}, \code{starts_with(...)}, or \code{column1:column4}, and can thus also be \link[=amr_selector]{antimicrobial selectors} such as \code{as.sir(df, penicillins())}.
Otherwise: arguments passed on to methods.}
\item{threshold}{Maximum fraction of invalid antimicrobial interpretations of \code{x}, see \emph{Examples}.} \item{threshold}{Maximum fraction of invalid antimicrobial interpretations of \code{x}, see \emph{Examples}.}
@@ -314,9 +316,12 @@ if (require("dplyr")) {
df_wide \%>\% mutate_if(is.mic, as.sir) df_wide \%>\% mutate_if(is.mic, as.sir)
df_wide \%>\% mutate_if(function(x) is.mic(x) | is.disk(x), as.sir) df_wide \%>\% mutate_if(function(x) is.mic(x) | is.disk(x), as.sir)
df_wide \%>\% mutate(across(where(is.mic), as.sir)) df_wide \%>\% mutate(across(where(is.mic), as.sir))
df_wide \%>\% mutate_at(vars(amoxicillin:tobra), as.sir) df_wide \%>\% mutate_at(vars(amoxicillin:tobra), as.sir)
df_wide \%>\% mutate(across(amoxicillin:tobra, as.sir)) df_wide \%>\% mutate(across(amoxicillin:tobra, as.sir))
df_wide \%>\% mutate(across(aminopenicillins(), as.sir))
# approaches that all work with additional arguments: # approaches that all work with additional arguments:
df_long \%>\% df_long \%>\%
# given a certain data type, e.g. MIC values # given a certain data type, e.g. MIC values

View File

@@ -103,7 +103,7 @@ These 35 antimicrobial groups are allowed in the rules (case-insensitive) and ca
\item aminoglycosides\cr(amikacin, amikacin/fosfomycin, apramycin, arbekacin, astromicin, bekanamycin, dibekacin, framycetin, gentamicin, gentamicin-high, habekacin, hygromycin, isepamicin, kanamycin, kanamycin-high, kanamycin/cephalexin, micronomicin, neomycin, netilmicin, pentisomicin, plazomicin, propikacin, ribostamycin, sisomicin, streptoduocin, streptomycin, streptomycin-high, tobramycin, and tobramycin-high) \item aminoglycosides\cr(amikacin, amikacin/fosfomycin, apramycin, arbekacin, astromicin, bekanamycin, dibekacin, framycetin, gentamicin, gentamicin-high, habekacin, hygromycin, isepamicin, kanamycin, kanamycin-high, kanamycin/cephalexin, micronomicin, neomycin, netilmicin, pentisomicin, plazomicin, propikacin, ribostamycin, sisomicin, streptoduocin, streptomycin, streptomycin-high, tobramycin, and tobramycin-high)
\item aminopenicillins\cr(amoxicillin and ampicillin) \item aminopenicillins\cr(amoxicillin and ampicillin)
\item antifungals\cr(amorolfine, amphotericin B, amphotericin B-high, anidulafungin, butoconazole, caspofungin, ciclopirox, clotrimazole, econazole, fluconazole, flucytosine, fosfluconazole, griseofulvin, hachimycin, ibrexafungerp, isavuconazole, isoconazole, itraconazole, ketoconazole, manogepix, micafungin, miconazole, nystatin, oteseconazole, pimaricin, posaconazole, rezafungin, ribociclib, sulconazole, terbinafine, terconazole, and voriconazole) \item antifungals\cr(amorolfine, amphotericin B, amphotericin B-high, anidulafungin, butoconazole, caspofungin, ciclopirox, clotrimazole, econazole, fluconazole, flucytosine, fosfluconazole, griseofulvin, hachimycin, ibrexafungerp, isavuconazole, isoconazole, itraconazole, ketoconazole, manogepix, micafungin, miconazole, nystatin, oteseconazole, pimaricin, posaconazole, rezafungin, ribociclib, sulconazole, terbinafine, terconazole, and voriconazole)
\item antimycobacterials\cr(4-aminosalicylic acid, calcium aminosalicylate, capreomycin, clofazimine, delamanid, enviomycin, ethambutol, ethambutol/isoniazid, ethionamide, isoniazid, isoniazid/sulfamethoxazole/trimethoprim/pyridoxine, morinamide, p-aminosalicylic acid, pretomanid, protionamide, pyrazinamide, rifabutin, rifampicin, rifampicin/ethambutol/isoniazid, rifampicin/isoniazid, rifampicin/pyrazinamide/ethambutol/isoniazid, rifampicin/pyrazinamide/isoniazid, rifamycin, rifapentine, simvastatin/fenofibrate, sodium aminosalicylate, streptomycin/isoniazid, terizidone, thioacetazone, thioacetazone/isoniazid, tiocarlide, and viomycin) \item antimycobacterials\cr(4-aminosalicylic acid, calcium aminosalicylate, capreomycin, clofazimine, delamanid, enviomycin, ethambutol, ethambutol/isoniazid, ethionamide, isoniazid, isoniazid/sulfamethoxazole/trimethoprim/pyridoxine, morinamide, p-aminosalicylic acid, pretomanid, protionamide, pyrazinamide, rifabutin, rifampicin, rifampicin/ethambutol/isoniazid, rifampicin/isoniazid, rifampicin/pyrazinamide/ethambutol/isoniazid, rifampicin/pyrazinamide/isoniazid, rifamycin, rifapentine, sodium aminosalicylate, streptomycin/isoniazid, terizidone, thioacetazone, thioacetazone/isoniazid, tiocarlide, and viomycin)
\item betalactams\cr(amoxicillin, amoxicillin/clavulanic acid, amoxicillin/sulbactam, ampicillin, ampicillin/sulbactam, apalcillin, aspoxicillin, azidocillin, azlocillin, aztreonam, aztreonam/avibactam, aztreonam/nacubactam, bacampicillin, benzathine benzylpenicillin, benzathine phenoxymethylpenicillin, benzylpenicillin, benzylpenicillin screening test, biapenem, carbenicillin, carindacillin, carumonam, cefacetrile, cefaclor, cefadroxil, cefalexin, cefaloridine, cefalotin, cefamandole, cefapirin, cefatrizine, cefazedone, cefazolin, cefcapene, cefcapene pivoxil, cefdinir, cefditoren, cefditoren pivoxil, cefepime, cefepime/amikacin, cefepime/clavulanic acid, cefepime/enmetazobactam, cefepime/nacubactam, cefepime/tazobactam, cefepime/zidebactam, cefetamet, cefetamet pivoxil, cefetecol, cefetrizole, cefiderocol, cefixime, cefmenoxime, cefmetazole, cefodizime, cefonicid, cefoperazone, cefoperazone/sulbactam, ceforanide, cefoselis, cefotaxime, cefotaxime screening test, cefotaxime/clavulanic acid, cefotaxime/sulbactam, cefotetan, cefotiam, cefotiam hexetil, cefovecin, cefoxitin, cefoxitin screening test, cefozopran, cefpimizole, cefpiramide, cefpirome, cefpodoxime, cefpodoxime proxetil, cefpodoxime/clavulanic acid, cefprozil, cefquinome, cefroxadine, cefsulodin, cefsumide, ceftaroline, ceftaroline/avibactam, ceftazidime, ceftazidime/avibactam, ceftazidime/clavulanic acid, cefteram, cefteram pivoxil, ceftezole, ceftibuten, ceftiofur, ceftizoxime, ceftizoxime alapivoxil, ceftobiprole, ceftobiprole medocaril, ceftolozane/tazobactam, ceftriaxone, ceftriaxone/beta-lactamase inhibitor, cefuroxime, cefuroxime axetil, cephradine, ciclacillin, clometocillin, cloxacillin, dicloxacillin, doripenem, epicillin, ertapenem, flucloxacillin, hetacillin, imipenem, imipenem/EDTA, imipenem/relebactam, latamoxef, lenampicillin, loracarbef, mecillinam, meropenem, meropenem/nacubactam, meropenem/vaborbactam, metampicillin, meticillin, mezlocillin, mezlocillin/sulbactam, nafcillin, oxacillin, oxacillin screening test, panipenem, penamecillin, penicillin/novobiocin, penicillin/sulbactam, pheneticillin, phenoxymethylpenicillin, piperacillin, piperacillin/sulbactam, piperacillin/tazobactam, piridicillin, pivampicillin, pivmecillinam, procaine benzylpenicillin, propicillin, razupenem, ritipenem, ritipenem acoxil, sarmoxicillin, sulbenicillin, sultamicillin, talampicillin, tebipenem, temocillin, ticarcillin, ticarcillin/clavulanic acid, and tigemonam) \item betalactams\cr(amoxicillin, amoxicillin/clavulanic acid, amoxicillin/sulbactam, ampicillin, ampicillin/sulbactam, apalcillin, aspoxicillin, azidocillin, azlocillin, aztreonam, aztreonam/avibactam, aztreonam/nacubactam, bacampicillin, benzathine benzylpenicillin, benzathine phenoxymethylpenicillin, benzylpenicillin, benzylpenicillin screening test, biapenem, carbenicillin, carindacillin, carumonam, cefacetrile, cefaclor, cefadroxil, cefalexin, cefaloridine, cefalotin, cefamandole, cefapirin, cefatrizine, cefazedone, cefazolin, cefcapene, cefcapene pivoxil, cefdinir, cefditoren, cefditoren pivoxil, cefepime, cefepime/amikacin, cefepime/clavulanic acid, cefepime/enmetazobactam, cefepime/nacubactam, cefepime/tazobactam, cefepime/zidebactam, cefetamet, cefetamet pivoxil, cefetecol, cefetrizole, cefiderocol, cefixime, cefmenoxime, cefmetazole, cefodizime, cefonicid, cefoperazone, cefoperazone/sulbactam, ceforanide, cefoselis, cefotaxime, cefotaxime screening test, cefotaxime/clavulanic acid, cefotaxime/sulbactam, cefotetan, cefotiam, cefotiam hexetil, cefovecin, cefoxitin, cefoxitin screening test, cefozopran, cefpimizole, cefpiramide, cefpirome, cefpodoxime, cefpodoxime proxetil, cefpodoxime/clavulanic acid, cefprozil, cefquinome, cefroxadine, cefsulodin, cefsumide, ceftaroline, ceftaroline/avibactam, ceftazidime, ceftazidime/avibactam, ceftazidime/clavulanic acid, cefteram, cefteram pivoxil, ceftezole, ceftibuten, ceftiofur, ceftizoxime, ceftizoxime alapivoxil, ceftobiprole, ceftobiprole medocaril, ceftolozane/tazobactam, ceftriaxone, ceftriaxone/beta-lactamase inhibitor, cefuroxime, cefuroxime axetil, cephradine, ciclacillin, clometocillin, cloxacillin, dicloxacillin, doripenem, epicillin, ertapenem, flucloxacillin, hetacillin, imipenem, imipenem/EDTA, imipenem/relebactam, latamoxef, lenampicillin, loracarbef, mecillinam, meropenem, meropenem/nacubactam, meropenem/vaborbactam, metampicillin, meticillin, mezlocillin, mezlocillin/sulbactam, nafcillin, oxacillin, oxacillin screening test, panipenem, penamecillin, penicillin/novobiocin, penicillin/sulbactam, pheneticillin, phenoxymethylpenicillin, piperacillin, piperacillin/sulbactam, piperacillin/tazobactam, piridicillin, pivampicillin, pivmecillinam, procaine benzylpenicillin, propicillin, razupenem, ritipenem, ritipenem acoxil, sarmoxicillin, sulbenicillin, sultamicillin, talampicillin, tebipenem, temocillin, ticarcillin, ticarcillin/clavulanic acid, and tigemonam)
\item betalactams_with_inhibitor\cr(amoxicillin/clavulanic acid, amoxicillin/sulbactam, ampicillin/sulbactam, aztreonam/avibactam, aztreonam/nacubactam, cefepime/amikacin, cefepime/clavulanic acid, cefepime/enmetazobactam, cefepime/nacubactam, cefepime/tazobactam, cefepime/zidebactam, cefoperazone/sulbactam, cefotaxime/clavulanic acid, cefotaxime/sulbactam, cefpodoxime/clavulanic acid, ceftaroline/avibactam, ceftazidime/avibactam, ceftazidime/clavulanic acid, ceftolozane/tazobactam, ceftriaxone/beta-lactamase inhibitor, imipenem/relebactam, meropenem/nacubactam, meropenem/vaborbactam, mezlocillin/sulbactam, penicillin/novobiocin, penicillin/sulbactam, piperacillin/sulbactam, piperacillin/tazobactam, and ticarcillin/clavulanic acid) \item betalactams_with_inhibitor\cr(amoxicillin/clavulanic acid, amoxicillin/sulbactam, ampicillin/sulbactam, aztreonam/avibactam, aztreonam/nacubactam, cefepime/amikacin, cefepime/clavulanic acid, cefepime/enmetazobactam, cefepime/nacubactam, cefepime/tazobactam, cefepime/zidebactam, cefoperazone/sulbactam, cefotaxime/clavulanic acid, cefotaxime/sulbactam, cefpodoxime/clavulanic acid, ceftaroline/avibactam, ceftazidime/avibactam, ceftazidime/clavulanic acid, ceftolozane/tazobactam, ceftriaxone/beta-lactamase inhibitor, imipenem/relebactam, meropenem/nacubactam, meropenem/vaborbactam, mezlocillin/sulbactam, penicillin/novobiocin, penicillin/sulbactam, piperacillin/sulbactam, piperacillin/tazobactam, and ticarcillin/clavulanic acid)
\item carbapenems\cr(biapenem, doripenem, ertapenem, imipenem, imipenem/EDTA, imipenem/relebactam, meropenem, meropenem/nacubactam, meropenem/vaborbactam, panipenem, razupenem, ritipenem, ritipenem acoxil, and tebipenem) \item carbapenems\cr(biapenem, doripenem, ertapenem, imipenem, imipenem/EDTA, imipenem/relebactam, meropenem, meropenem/nacubactam, meropenem/vaborbactam, panipenem, razupenem, ritipenem, ritipenem acoxil, and tebipenem)

View File

@@ -99,7 +99,7 @@ All 35 antimicrobial selectors are supported for use in the rules:
\item \code{\link[=aminoglycosides]{aminoglycosides()}} can select: \cr amikacin, amikacin/fosfomycin, apramycin, arbekacin, astromicin, bekanamycin, dibekacin, framycetin, gentamicin, gentamicin-high, habekacin, hygromycin, isepamicin, kanamycin, kanamycin-high, kanamycin/cephalexin, micronomicin, neomycin, netilmicin, pentisomicin, plazomicin, propikacin, ribostamycin, sisomicin, streptoduocin, streptomycin, streptomycin-high, tobramycin, and tobramycin-high \item \code{\link[=aminoglycosides]{aminoglycosides()}} can select: \cr amikacin, amikacin/fosfomycin, apramycin, arbekacin, astromicin, bekanamycin, dibekacin, framycetin, gentamicin, gentamicin-high, habekacin, hygromycin, isepamicin, kanamycin, kanamycin-high, kanamycin/cephalexin, micronomicin, neomycin, netilmicin, pentisomicin, plazomicin, propikacin, ribostamycin, sisomicin, streptoduocin, streptomycin, streptomycin-high, tobramycin, and tobramycin-high
\item \code{\link[=aminopenicillins]{aminopenicillins()}} can select: \cr amoxicillin and ampicillin \item \code{\link[=aminopenicillins]{aminopenicillins()}} can select: \cr amoxicillin and ampicillin
\item \code{\link[=antifungals]{antifungals()}} can select: \cr amorolfine, amphotericin B, amphotericin B-high, anidulafungin, butoconazole, caspofungin, ciclopirox, clotrimazole, econazole, fluconazole, flucytosine, fosfluconazole, griseofulvin, hachimycin, ibrexafungerp, isavuconazole, isoconazole, itraconazole, ketoconazole, manogepix, micafungin, miconazole, nystatin, oteseconazole, pimaricin, posaconazole, rezafungin, ribociclib, sulconazole, terbinafine, terconazole, and voriconazole \item \code{\link[=antifungals]{antifungals()}} can select: \cr amorolfine, amphotericin B, amphotericin B-high, anidulafungin, butoconazole, caspofungin, ciclopirox, clotrimazole, econazole, fluconazole, flucytosine, fosfluconazole, griseofulvin, hachimycin, ibrexafungerp, isavuconazole, isoconazole, itraconazole, ketoconazole, manogepix, micafungin, miconazole, nystatin, oteseconazole, pimaricin, posaconazole, rezafungin, ribociclib, sulconazole, terbinafine, terconazole, and voriconazole
\item \code{\link[=antimycobacterials]{antimycobacterials()}} can select: \cr 4-aminosalicylic acid, calcium aminosalicylate, capreomycin, clofazimine, delamanid, enviomycin, ethambutol, ethambutol/isoniazid, ethionamide, isoniazid, isoniazid/sulfamethoxazole/trimethoprim/pyridoxine, morinamide, p-aminosalicylic acid, pretomanid, protionamide, pyrazinamide, rifabutin, rifampicin, rifampicin/ethambutol/isoniazid, rifampicin/isoniazid, rifampicin/pyrazinamide/ethambutol/isoniazid, rifampicin/pyrazinamide/isoniazid, rifamycin, rifapentine, simvastatin/fenofibrate, sodium aminosalicylate, streptomycin/isoniazid, terizidone, thioacetazone, thioacetazone/isoniazid, tiocarlide, and viomycin \item \code{\link[=antimycobacterials]{antimycobacterials()}} can select: \cr 4-aminosalicylic acid, calcium aminosalicylate, capreomycin, clofazimine, delamanid, enviomycin, ethambutol, ethambutol/isoniazid, ethionamide, isoniazid, isoniazid/sulfamethoxazole/trimethoprim/pyridoxine, morinamide, p-aminosalicylic acid, pretomanid, protionamide, pyrazinamide, rifabutin, rifampicin, rifampicin/ethambutol/isoniazid, rifampicin/isoniazid, rifampicin/pyrazinamide/ethambutol/isoniazid, rifampicin/pyrazinamide/isoniazid, rifamycin, rifapentine, sodium aminosalicylate, streptomycin/isoniazid, terizidone, thioacetazone, thioacetazone/isoniazid, tiocarlide, and viomycin
\item \code{\link[=betalactams]{betalactams()}} can select: \cr amoxicillin, amoxicillin/clavulanic acid, amoxicillin/sulbactam, ampicillin, ampicillin/sulbactam, apalcillin, aspoxicillin, azidocillin, azlocillin, aztreonam, aztreonam/avibactam, aztreonam/nacubactam, bacampicillin, benzathine benzylpenicillin, benzathine phenoxymethylpenicillin, benzylpenicillin, benzylpenicillin screening test, biapenem, carbenicillin, carindacillin, carumonam, cefacetrile, cefaclor, cefadroxil, cefalexin, cefaloridine, cefalotin, cefamandole, cefapirin, cefatrizine, cefazedone, cefazolin, cefcapene, cefcapene pivoxil, cefdinir, cefditoren, cefditoren pivoxil, cefepime, cefepime/amikacin, cefepime/clavulanic acid, cefepime/enmetazobactam, cefepime/nacubactam, cefepime/tazobactam, cefepime/zidebactam, cefetamet, cefetamet pivoxil, cefetecol, cefetrizole, cefiderocol, cefixime, cefmenoxime, cefmetazole, cefodizime, cefonicid, cefoperazone, cefoperazone/sulbactam, ceforanide, cefoselis, cefotaxime, cefotaxime screening test, cefotaxime/clavulanic acid, cefotaxime/sulbactam, cefotetan, cefotiam, cefotiam hexetil, cefovecin, cefoxitin, cefoxitin screening test, cefozopran, cefpimizole, cefpiramide, cefpirome, cefpodoxime, cefpodoxime proxetil, cefpodoxime/clavulanic acid, cefprozil, cefquinome, cefroxadine, cefsulodin, cefsumide, ceftaroline, ceftaroline/avibactam, ceftazidime, ceftazidime/avibactam, ceftazidime/clavulanic acid, cefteram, cefteram pivoxil, ceftezole, ceftibuten, ceftiofur, ceftizoxime, ceftizoxime alapivoxil, ceftobiprole, ceftobiprole medocaril, ceftolozane/tazobactam, ceftriaxone, ceftriaxone/beta-lactamase inhibitor, cefuroxime, cefuroxime axetil, cephradine, ciclacillin, clometocillin, cloxacillin, dicloxacillin, doripenem, epicillin, ertapenem, flucloxacillin, hetacillin, imipenem, imipenem/EDTA, imipenem/relebactam, latamoxef, lenampicillin, loracarbef, mecillinam, meropenem, meropenem/nacubactam, meropenem/vaborbactam, metampicillin, meticillin, mezlocillin, mezlocillin/sulbactam, nafcillin, oxacillin, oxacillin screening test, panipenem, penamecillin, penicillin/novobiocin, penicillin/sulbactam, pheneticillin, phenoxymethylpenicillin, piperacillin, piperacillin/sulbactam, piperacillin/tazobactam, piridicillin, pivampicillin, pivmecillinam, procaine benzylpenicillin, propicillin, razupenem, ritipenem, ritipenem acoxil, sarmoxicillin, sulbenicillin, sultamicillin, talampicillin, tebipenem, temocillin, ticarcillin, ticarcillin/clavulanic acid, and tigemonam \item \code{\link[=betalactams]{betalactams()}} can select: \cr amoxicillin, amoxicillin/clavulanic acid, amoxicillin/sulbactam, ampicillin, ampicillin/sulbactam, apalcillin, aspoxicillin, azidocillin, azlocillin, aztreonam, aztreonam/avibactam, aztreonam/nacubactam, bacampicillin, benzathine benzylpenicillin, benzathine phenoxymethylpenicillin, benzylpenicillin, benzylpenicillin screening test, biapenem, carbenicillin, carindacillin, carumonam, cefacetrile, cefaclor, cefadroxil, cefalexin, cefaloridine, cefalotin, cefamandole, cefapirin, cefatrizine, cefazedone, cefazolin, cefcapene, cefcapene pivoxil, cefdinir, cefditoren, cefditoren pivoxil, cefepime, cefepime/amikacin, cefepime/clavulanic acid, cefepime/enmetazobactam, cefepime/nacubactam, cefepime/tazobactam, cefepime/zidebactam, cefetamet, cefetamet pivoxil, cefetecol, cefetrizole, cefiderocol, cefixime, cefmenoxime, cefmetazole, cefodizime, cefonicid, cefoperazone, cefoperazone/sulbactam, ceforanide, cefoselis, cefotaxime, cefotaxime screening test, cefotaxime/clavulanic acid, cefotaxime/sulbactam, cefotetan, cefotiam, cefotiam hexetil, cefovecin, cefoxitin, cefoxitin screening test, cefozopran, cefpimizole, cefpiramide, cefpirome, cefpodoxime, cefpodoxime proxetil, cefpodoxime/clavulanic acid, cefprozil, cefquinome, cefroxadine, cefsulodin, cefsumide, ceftaroline, ceftaroline/avibactam, ceftazidime, ceftazidime/avibactam, ceftazidime/clavulanic acid, cefteram, cefteram pivoxil, ceftezole, ceftibuten, ceftiofur, ceftizoxime, ceftizoxime alapivoxil, ceftobiprole, ceftobiprole medocaril, ceftolozane/tazobactam, ceftriaxone, ceftriaxone/beta-lactamase inhibitor, cefuroxime, cefuroxime axetil, cephradine, ciclacillin, clometocillin, cloxacillin, dicloxacillin, doripenem, epicillin, ertapenem, flucloxacillin, hetacillin, imipenem, imipenem/EDTA, imipenem/relebactam, latamoxef, lenampicillin, loracarbef, mecillinam, meropenem, meropenem/nacubactam, meropenem/vaborbactam, metampicillin, meticillin, mezlocillin, mezlocillin/sulbactam, nafcillin, oxacillin, oxacillin screening test, panipenem, penamecillin, penicillin/novobiocin, penicillin/sulbactam, pheneticillin, phenoxymethylpenicillin, piperacillin, piperacillin/sulbactam, piperacillin/tazobactam, piridicillin, pivampicillin, pivmecillinam, procaine benzylpenicillin, propicillin, razupenem, ritipenem, ritipenem acoxil, sarmoxicillin, sulbenicillin, sultamicillin, talampicillin, tebipenem, temocillin, ticarcillin, ticarcillin/clavulanic acid, and tigemonam
\item \code{\link[=betalactams_with_inhibitor]{betalactams_with_inhibitor()}} can select: \cr amoxicillin/clavulanic acid, amoxicillin/sulbactam, ampicillin/sulbactam, aztreonam/avibactam, aztreonam/nacubactam, cefepime/amikacin, cefepime/clavulanic acid, cefepime/enmetazobactam, cefepime/nacubactam, cefepime/tazobactam, cefepime/zidebactam, cefoperazone/sulbactam, cefotaxime/clavulanic acid, cefotaxime/sulbactam, cefpodoxime/clavulanic acid, ceftaroline/avibactam, ceftazidime/avibactam, ceftazidime/clavulanic acid, ceftolozane/tazobactam, ceftriaxone/beta-lactamase inhibitor, imipenem/relebactam, meropenem/nacubactam, meropenem/vaborbactam, mezlocillin/sulbactam, penicillin/novobiocin, penicillin/sulbactam, piperacillin/sulbactam, piperacillin/tazobactam, and ticarcillin/clavulanic acid \item \code{\link[=betalactams_with_inhibitor]{betalactams_with_inhibitor()}} can select: \cr amoxicillin/clavulanic acid, amoxicillin/sulbactam, ampicillin/sulbactam, aztreonam/avibactam, aztreonam/nacubactam, cefepime/amikacin, cefepime/clavulanic acid, cefepime/enmetazobactam, cefepime/nacubactam, cefepime/tazobactam, cefepime/zidebactam, cefoperazone/sulbactam, cefotaxime/clavulanic acid, cefotaxime/sulbactam, cefpodoxime/clavulanic acid, ceftaroline/avibactam, ceftazidime/avibactam, ceftazidime/clavulanic acid, ceftolozane/tazobactam, ceftriaxone/beta-lactamase inhibitor, imipenem/relebactam, meropenem/nacubactam, meropenem/vaborbactam, mezlocillin/sulbactam, penicillin/novobiocin, penicillin/sulbactam, piperacillin/sulbactam, piperacillin/tazobactam, and ticarcillin/clavulanic acid
\item \code{\link[=carbapenems]{carbapenems()}} can select: \cr biapenem, doripenem, ertapenem, imipenem, imipenem/EDTA, imipenem/relebactam, meropenem, meropenem/nacubactam, meropenem/vaborbactam, panipenem, razupenem, ritipenem, ritipenem acoxil, and tebipenem \item \code{\link[=carbapenems]{carbapenems()}} can select: \cr biapenem, doripenem, ertapenem, imipenem, imipenem/EDTA, imipenem/relebactam, meropenem, meropenem/nacubactam, meropenem/vaborbactam, panipenem, razupenem, ritipenem, ritipenem acoxil, and tebipenem

27
man/esbl_isolates.Rd Normal file
View File

@@ -0,0 +1,27 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/data.R
\docType{data}
\name{esbl_isolates}
\alias{esbl_isolates}
\title{Data Set with 500 ESBL Isolates}
\format{
A \link[tibble:tibble]{tibble} with 500 observations and 19 variables:
\itemize{
\item \code{esbl}\cr Logical indicator if the isolate is ESBL-producing
\item \code{genus}\cr Genus of the microorganism
\item \code{AMC:COL}\cr MIC values for 17 antimicrobial agents, transformed to class \code{\link{mic}} (see \code{\link[=as.mic]{as.mic()}})
}
}
\usage{
esbl_isolates
}
\description{
A data set containing 500 microbial isolates with MIC values of common antibiotics and a binary \code{esbl} column for extended-spectrum beta-lactamase (ESBL) production. This data set contains randomised fictitious data but reflects reality and can be used to practise AMR-related machine learning, e.g., classification modelling with \href{https://amr-for-r.org/articles/AMR_with_tidymodels.html}{tidymodels}.
}
\details{
See our \link[=amr-tidymodels]{tidymodels integration} for an example using this data set.
}
\examples{
esbl_isolates
}
\keyword{datasets}

View File

@@ -133,7 +133,7 @@ g.test(x)
} }
\references{ \references{
\enumerate{ \enumerate{
\item McDonald, J.H. 2014. \strong{Handbook of Biological Statistics (3rd ed.)}. Sparky House Publishing, Baltimore, Maryland. \url{http://www.biostathandbook.com/gtestgof.html}. \item McDonald, J.H. 2014. \strong{Handbook of Biological Statistics (3rd ed.)}. Sparky House Publishing, Baltimore, Maryland.
} }
} }
\seealso{ \seealso{

View File

@@ -9,10 +9,10 @@ ggplot_sir(data, position = NULL, x = "antibiotic",
fill = "interpretation", facet = NULL, breaks = seq(0, 1, 0.1), fill = "interpretation", facet = NULL, breaks = seq(0, 1, 0.1),
limits = NULL, translate_ab = "name", combine_SI = TRUE, limits = NULL, translate_ab = "name", combine_SI = TRUE,
minimum = 30, language = get_AMR_locale(), nrow = NULL, colours = c(S minimum = 30, language = get_AMR_locale(), nrow = NULL, colours = c(S
= "#3CAEA3", SI = "#3CAEA3", I = "#F6D55C", IR = "#ED553B", R = "#ED553B"), = "#3CAEA3", SDD = "#8FD6C4", SI = "#3CAEA3", I = "#F6D55C", IR = "#ED553B",
datalabels = TRUE, datalabels.size = 2.5, datalabels.colour = "grey15", R = "#ED553B"), datalabels = TRUE, datalabels.size = 2.5,
title = NULL, subtitle = NULL, caption = NULL, datalabels.colour = "grey15", title = NULL, subtitle = NULL,
x.title = "Antimicrobial", y.title = "Proportion", ...) caption = NULL, x.title = "Antimicrobial", y.title = "Proportion", ...)
geom_sir(position = NULL, x = c("antibiotic", "interpretation"), geom_sir(position = NULL, x = c("antibiotic", "interpretation"),
fill = "interpretation", translate_ab = "name", minimum = 30, fill = "interpretation", translate_ab = "name", minimum = 30,

View File

@@ -57,7 +57,7 @@ eucast_exceptional_phenotypes(x = NULL, only_sir_columns = any(is.sir(x)),
\item{combine_SI}{A \link{logical} to indicate whether all values of S and I must be merged into one, so resistance is only considered when isolates are R, not I. As this is the default behaviour of the \code{\link[=mdro]{mdro()}} function, it follows the redefinition by EUCAST about the interpretation of I (increased exposure) in 2019, see section 'Interpretation of S, I and R' below. When using \code{combine_SI = FALSE}, resistance is considered when isolates are R or I.} \item{combine_SI}{A \link{logical} to indicate whether all values of S and I must be merged into one, so resistance is only considered when isolates are R, not I. As this is the default behaviour of the \code{\link[=mdro]{mdro()}} function, it follows the redefinition by EUCAST about the interpretation of I (increased exposure) in 2019, see section 'Interpretation of S, I and R' below. When using \code{combine_SI = FALSE}, resistance is considered when isolates are R or I.}
\item{verbose}{A \link{logical} to turn Verbose mode on and off (default is off). In Verbose mode, the function does not return the MDRO results, but instead returns a data set in logbook form with extensive info about which isolates would be MDRO-positive, or why they are not.} \item{verbose}{A \link{logical} to turn Verbose mode on and off (default is off). In Verbose mode, the function returns a data set with the MDRO results in logbook form with extensive info about which isolates would be MDRO-positive, or why they are not.}
\item{only_sir_columns}{A \link{logical} to indicate whether only antimicrobial columns must be included that were transformed to class \link[=as.sir]{sir} on beforehand. Defaults to \code{FALSE} if no columns of \code{x} have a class \link[=as.sir]{sir}.} \item{only_sir_columns}{A \link{logical} to indicate whether only antimicrobial columns must be included that were transformed to class \link[=as.sir]{sir} on beforehand. Defaults to \code{FALSE} if no columns of \code{x} have a class \link[=as.sir]{sir}.}

View File

@@ -18,7 +18,7 @@ amr_distance_from_row(amr_distance, row)
\arguments{ \arguments{
\item{x}{A vector of class \link[=as.sir]{sir}, \link[=as.mic]{mic} or \link[=as.disk]{disk}, or a \link{data.frame} containing columns of any of these classes.} \item{x}{A vector of class \link[=as.sir]{sir}, \link[=as.mic]{mic} or \link[=as.disk]{disk}, or a \link{data.frame} containing columns of any of these classes.}
\item{...}{Variables to select. Supports \link[tidyselect:language]{tidyselect language} (such as \code{column1:column4} and \code{where(is.mic)}), and can thus also be \link[=amr_selector]{antimicrobial selectors}.} \item{...}{Variables to select. Supports \link[tidyselect:starts_with]{tidyselect language} such as \code{where(is.mic)}, \code{starts_with(...)}, or \code{column1:column4}, and can thus also be \link[=amr_selector]{antimicrobial selectors}.}
\item{combine_SI}{A \link{logical} to indicate whether all values of S, SDD, and I must be merged into one, so the input only consists of S+I vs. R (susceptible vs. resistant) - the default is \code{TRUE}.} \item{combine_SI}{A \link{logical} to indicate whether all values of S, SDD, and I must be merged into one, so the input only consists of S+I vs. R (susceptible vs. resistant) - the default is \code{TRUE}.}

View File

@@ -33,25 +33,25 @@ scale_colour_mic(keep_operators = "edges", mic_range = NULL, ...)
scale_fill_mic(keep_operators = "edges", mic_range = NULL, ...) scale_fill_mic(keep_operators = "edges", mic_range = NULL, ...)
scale_x_sir(colours_SIR = c("#3CAEA3", "#F6D55C", "#ED553B"), scale_x_sir(colours_SIR = c(S = "#3CAEA3", SDD = "#8FD6C4", I = "#F6D55C", R
language = get_AMR_locale(), eucast_I = getOption("AMR_guideline", = "#ED553B"), language = get_AMR_locale(),
"EUCAST") == "EUCAST", ...) eucast_I = getOption("AMR_guideline", "EUCAST") == "EUCAST", ...)
scale_colour_sir(colours_SIR = c("#3CAEA3", "#F6D55C", "#ED553B"), scale_colour_sir(colours_SIR = c(S = "#3CAEA3", SDD = "#8FD6C4", I =
language = get_AMR_locale(), eucast_I = getOption("AMR_guideline", "#F6D55C", R = "#ED553B"), language = get_AMR_locale(),
"EUCAST") == "EUCAST", ...) eucast_I = getOption("AMR_guideline", "EUCAST") == "EUCAST", ...)
scale_fill_sir(colours_SIR = c("#3CAEA3", "#F6D55C", "#ED553B"), scale_fill_sir(colours_SIR = c(S = "#3CAEA3", SDD = "#8FD6C4", I = "#F6D55C",
language = get_AMR_locale(), eucast_I = getOption("AMR_guideline", R = "#ED553B"), language = get_AMR_locale(),
"EUCAST") == "EUCAST", ...) eucast_I = getOption("AMR_guideline", "EUCAST") == "EUCAST", ...)
\method{plot}{mic}(x, mo = NULL, ab = NULL, \method{plot}{mic}(x, mo = NULL, ab = NULL,
guideline = getOption("AMR_guideline", "EUCAST"), guideline = getOption("AMR_guideline", "EUCAST"),
main = deparse(substitute(x)), ylab = translate_AMR("Frequency", language main = deparse(substitute(x)), ylab = translate_AMR("Frequency", language
= language), = language),
xlab = translate_AMR("Minimum Inhibitory Concentration (mg/L)", language = xlab = translate_AMR("Minimum Inhibitory Concentration (mg/L)", language =
language), colours_SIR = c("#3CAEA3", "#F6D55C", "#ED553B"), language), colours_SIR = c(S = "#3CAEA3", SDD = "#8FD6C4", I = "#F6D55C", R
language = get_AMR_locale(), expand = TRUE, = "#ED553B"), language = get_AMR_locale(), expand = TRUE,
include_PKPD = getOption("AMR_include_PKPD", TRUE), include_PKPD = getOption("AMR_include_PKPD", TRUE),
breakpoint_type = getOption("AMR_breakpoint_type", "human"), ...) breakpoint_type = getOption("AMR_breakpoint_type", "human"), ...)
@@ -60,8 +60,8 @@ scale_fill_sir(colours_SIR = c("#3CAEA3", "#F6D55C", "#ED553B"),
title = deparse(substitute(object)), ylab = translate_AMR("Frequency", title = deparse(substitute(object)), ylab = translate_AMR("Frequency",
language = language), language = language),
xlab = translate_AMR("Minimum Inhibitory Concentration (mg/L)", language = xlab = translate_AMR("Minimum Inhibitory Concentration (mg/L)", language =
language), colours_SIR = c("#3CAEA3", "#F6D55C", "#ED553B"), language), colours_SIR = c(S = "#3CAEA3", SDD = "#8FD6C4", I = "#F6D55C", R
language = get_AMR_locale(), expand = TRUE, = "#ED553B"), language = get_AMR_locale(), expand = TRUE,
include_PKPD = getOption("AMR_include_PKPD", TRUE), include_PKPD = getOption("AMR_include_PKPD", TRUE),
breakpoint_type = getOption("AMR_breakpoint_type", "human"), ...) breakpoint_type = getOption("AMR_breakpoint_type", "human"), ...)
@@ -69,8 +69,8 @@ scale_fill_sir(colours_SIR = c("#3CAEA3", "#F6D55C", "#ED553B"),
ylab = translate_AMR("Frequency", language = language), ylab = translate_AMR("Frequency", language = language),
xlab = translate_AMR("Disk diffusion diameter (mm)", language = language), xlab = translate_AMR("Disk diffusion diameter (mm)", language = language),
mo = NULL, ab = NULL, guideline = getOption("AMR_guideline", "EUCAST"), mo = NULL, ab = NULL, guideline = getOption("AMR_guideline", "EUCAST"),
colours_SIR = c("#3CAEA3", "#F6D55C", "#ED553B"), colours_SIR = c(S = "#3CAEA3", SDD = "#8FD6C4", I = "#F6D55C", R =
language = get_AMR_locale(), expand = TRUE, "#ED553B"), language = get_AMR_locale(), expand = TRUE,
include_PKPD = getOption("AMR_include_PKPD", TRUE), include_PKPD = getOption("AMR_include_PKPD", TRUE),
breakpoint_type = getOption("AMR_breakpoint_type", "human"), ...) breakpoint_type = getOption("AMR_breakpoint_type", "human"), ...)
@@ -78,8 +78,8 @@ scale_fill_sir(colours_SIR = c("#3CAEA3", "#F6D55C", "#ED553B"),
title = deparse(substitute(object)), ylab = translate_AMR("Frequency", title = deparse(substitute(object)), ylab = translate_AMR("Frequency",
language = language), xlab = translate_AMR("Disk diffusion diameter (mm)", language = language), xlab = translate_AMR("Disk diffusion diameter (mm)",
language = language), guideline = getOption("AMR_guideline", "EUCAST"), language = language), guideline = getOption("AMR_guideline", "EUCAST"),
colours_SIR = c("#3CAEA3", "#F6D55C", "#ED553B"), colours_SIR = c(S = "#3CAEA3", SDD = "#8FD6C4", I = "#F6D55C", R =
language = get_AMR_locale(), expand = TRUE, "#ED553B"), language = get_AMR_locale(), expand = TRUE,
include_PKPD = getOption("AMR_include_PKPD", TRUE), include_PKPD = getOption("AMR_include_PKPD", TRUE),
breakpoint_type = getOption("AMR_breakpoint_type", "human"), ...) breakpoint_type = getOption("AMR_breakpoint_type", "human"), ...)
@@ -90,8 +90,8 @@ scale_fill_sir(colours_SIR = c("#3CAEA3", "#F6D55C", "#ED553B"),
\method{autoplot}{sir}(object, title = deparse(substitute(object)), \method{autoplot}{sir}(object, title = deparse(substitute(object)),
xlab = translate_AMR("Antimicrobial Interpretation", language = language), xlab = translate_AMR("Antimicrobial Interpretation", language = language),
ylab = translate_AMR("Frequency", language = language), ylab = translate_AMR("Frequency", language = language), colours_SIR = c(S
colours_SIR = c("#3CAEA3", "#F6D55C", "#ED553B"), = "#3CAEA3", SDD = "#8FD6C4", I = "#F6D55C", R = "#ED553B"),
language = get_AMR_locale(), ...) language = get_AMR_locale(), ...)
facet_sir(facet = c("interpretation", "antibiotic"), nrow = NULL) facet_sir(facet = c("interpretation", "antibiotic"), nrow = NULL)
@@ -99,8 +99,8 @@ facet_sir(facet = c("interpretation", "antibiotic"), nrow = NULL)
scale_y_percent(breaks = function(x) seq(0, max(x, na.rm = TRUE), 0.1), scale_y_percent(breaks = function(x) seq(0, max(x, na.rm = TRUE), 0.1),
limits = c(0, NA)) limits = c(0, NA))
scale_sir_colours(..., aesthetics, colours_SIR = c("#3CAEA3", "#F6D55C", scale_sir_colours(..., aesthetics, colours_SIR = c(S = "#3CAEA3", SDD =
"#ED553B")) "#8FD6C4", I = "#F6D55C", R = "#ED553B"))
theme_sir() theme_sir()
@@ -210,6 +210,10 @@ if (require("ggplot2")) {
# when providing the microorganism and antibiotic, colours will show interpretations: # when providing the microorganism and antibiotic, colours will show interpretations:
autoplot(some_mic_values, mo = "Escherichia coli", ab = "cipro") autoplot(some_mic_values, mo = "Escherichia coli", ab = "cipro")
} }
if (require("ggplot2")) {
autoplot(some_mic_values, mo = "Staph aureus", ab = "Ceftaroline", guideline = "CLSI")
}
if (require("ggplot2")) { if (require("ggplot2")) {
# support for 27 languages, various guidelines, and many options # support for 27 languages, various guidelines, and many options
autoplot(some_disk_values, autoplot(some_disk_values,
@@ -267,7 +271,7 @@ if (require("ggplot2")) {
aes(group, mic) aes(group, mic)
) + ) +
geom_boxplot() + geom_boxplot() +
geom_violin(linetype = 2, colour = "grey", fill = NA) + geom_violin(linetype = 2, colour = "grey30", fill = NA) +
scale_y_mic() scale_y_mic()
} }
if (require("ggplot2")) { if (require("ggplot2")) {
@@ -279,7 +283,7 @@ if (require("ggplot2")) {
aes(group, mic) aes(group, mic)
) + ) +
geom_boxplot() + geom_boxplot() +
geom_violin(linetype = 2, colour = "grey", fill = NA) + geom_violin(linetype = 2, colour = "grey30", fill = NA) +
scale_y_mic(mic_range = c(NA, 0.25)) scale_y_mic(mic_range = c(NA, 0.25))
} }
@@ -312,7 +316,7 @@ if (require("ggplot2")) {
aes(x = group, y = mic, colour = sir) aes(x = group, y = mic, colour = sir)
) + ) +
theme_minimal() + theme_minimal() +
geom_boxplot(fill = NA, colour = "grey") + geom_boxplot(fill = NA, colour = "grey30") +
geom_jitter(width = 0.25) geom_jitter(width = 0.25)
plain plain

View File

@@ -7,19 +7,25 @@
\alias{random_sir} \alias{random_sir}
\title{Random MIC Values/Disk Zones/SIR Generation} \title{Random MIC Values/Disk Zones/SIR Generation}
\usage{ \usage{
random_mic(size = NULL, mo = NULL, ab = NULL, ...) random_mic(size = NULL, mo = NULL, ab = NULL, skew = "right",
severity = 1, ...)
random_disk(size = NULL, mo = NULL, ab = NULL, ...) random_disk(size = NULL, mo = NULL, ab = NULL, skew = "left",
severity = 1, ...)
random_sir(size = NULL, prob_SIR = c(0.33, 0.33, 0.33), ...) random_sir(size = NULL, prob_SIR = c(0.33, 0.33, 0.33), ...)
} }
\arguments{ \arguments{
\item{size}{Desired size of the returned vector. If used in a \link{data.frame} call or \code{dplyr} verb, will get the current (group) size if left blank.} \item{size}{Desired size of the returned vector. If used in a \link{data.frame} call or \code{dplyr} verb, will get the current (group) size if left blank.}
\item{mo}{Any \link{character} that can be coerced to a valid microorganism code with \code{\link[=as.mo]{as.mo()}}.} \item{mo}{Any \link{character} that can be coerced to a valid microorganism code with \code{\link[=as.mo]{as.mo()}}. Can be the same length as \code{size}.}
\item{ab}{Any \link{character} that can be coerced to a valid antimicrobial drug code with \code{\link[=as.ab]{as.ab()}}.} \item{ab}{Any \link{character} that can be coerced to a valid antimicrobial drug code with \code{\link[=as.ab]{as.ab()}}.}
\item{skew}{Direction of skew for MIC or disk values, either \code{"right"} or \code{"left"}. A left-skewed distribution has the majority of the data on the right.}
\item{severity}{Skew severity; higher values will increase the skewedness. Default is \code{2}; use \code{0} to prevent skewedness.}
\item{...}{Ignored, only in place to allow future extensions.} \item{...}{Ignored, only in place to allow future extensions.}
\item{prob_SIR}{A vector of length 3: the probabilities for "S" (1st value), "I" (2nd value) and "R" (3rd value).} \item{prob_SIR}{A vector of length 3: the probabilities for "S" (1st value), "I" (2nd value) and "R" (3rd value).}
@@ -31,17 +37,25 @@ class \code{mic} for \code{\link[=random_mic]{random_mic()}} (see \code{\link[=a
These functions can be used for generating random MIC values and disk diffusion diameters, for AMR data analysis practice. By providing a microorganism and antimicrobial drug, the generated results will reflect reality as much as possible. These functions can be used for generating random MIC values and disk diffusion diameters, for AMR data analysis practice. By providing a microorganism and antimicrobial drug, the generated results will reflect reality as much as possible.
} }
\details{ \details{
The base \R function \code{\link[=sample]{sample()}} is used for generating values. Internally, MIC and disk zone values are sampled based on clinical breakpoints defined in the \link{clinical_breakpoints} data set. To create specific generated values per bug or drug, set the \code{mo} and/or \code{ab} argument. The MICs are sampled on a log2 scale and disks linearly, using weighted probabilities. The weights are based on the \code{skew} and \code{severity} arguments:
\itemize{
Generated values are based on the EUCAST 2025 guideline as implemented in the \link{clinical_breakpoints} data set. To create specific generated values per bug or drug, set the \code{mo} and/or \code{ab} argument. \item \code{skew = "right"} places more emphasis on lower MIC or higher disk values.
\item \code{skew = "left"} places more emphasis on higher MIC or lower disk values.
\item \code{severity} controls the exponential bias applied.
}
} }
\examples{ \examples{
random_mic(25) random_mic(25)
random_disk(25) random_disk(25)
random_sir(25) random_sir(25)
# add more skewedness, make more realistic by setting a bug and/or drug:
disks <- random_disk(100, severity = 2, mo = "Escherichia coli", ab = "CIP")
plot(disks)
# `plot()` and `ggplot2::autoplot()` allow for coloured bars if `mo` and `ab` are set
plot(disks, mo = "Escherichia coli", ab = "CIP", guideline = "CLSI 2025")
\donttest{ \donttest{
# make the random generation more realistic by setting a bug and/or drug:
random_mic(25, "Klebsiella pneumoniae") # range 0.0625-64 random_mic(25, "Klebsiella pneumoniae") # range 0.0625-64
random_mic(25, "Klebsiella pneumoniae", "meropenem") # range 0.0625-16 random_mic(25, "Klebsiella pneumoniae", "meropenem") # range 0.0625-16
random_mic(25, "Streptococcus pneumoniae", "meropenem") # range 0.0625-4 random_mic(25, "Streptococcus pneumoniae", "meropenem") # range 0.0625-4

View File

@@ -41,7 +41,7 @@
--bs-success: var(--amr-green-dark) !important; --bs-success: var(--amr-green-dark) !important;
--bs-light: var(--amr-green-light) !important; --bs-light: var(--amr-green-light) !important;
/* --bs-light was this: #128f76a6; that's success with 60% alpha */ /* --bs-light was this: #128f76a6; that's bs-success with 60% alpha */
--bs-info: var(--amr-green-middle) !important; --bs-info: var(--amr-green-middle) !important;
--bs-link-color: var(--amr-green-dark) !important; --bs-link-color: var(--amr-green-dark) !important;
--bs-link-color-rgb: var(--amr-green-dark-rgb) !important; --bs-link-color-rgb: var(--amr-green-dark-rgb) !important;
@@ -104,6 +104,16 @@ body.amr-for-python * {
.navbar .algolia-autocomplete .aa-dropdown-menu { .navbar .algolia-autocomplete .aa-dropdown-menu {
background-color: var(--amr-green-dark) !important; background-color: var(--amr-green-dark) !important;
} }
.version-main {
font-weight: bold;
color: var(--bs-navbar-brand-color);
}
.version-build {
font-weight: normal;
opacity: 0.75;
font-size: 0.85em;
}
input[type="search"] { input[type="search"] {
color: var(--bs-tertiary-bg) !important; color: var(--bs-tertiary-bg) !important;
background-color: var(--amr-green-light) !important; background-color: var(--amr-green-light) !important;
@@ -149,6 +159,7 @@ this shows on top of every sidebar to the right
margin-top: 10px; margin-top: 10px;
border: 2px dashed var(--amr-green-dark); border: 2px dashed var(--amr-green-dark);
text-align: center; text-align: center;
background: var(--bs-body-bg);
} }
.amr-gpt-assistant * { .amr-gpt-assistant * {
width: 90%; width: 90%;
@@ -179,6 +190,15 @@ this shows on top of every sidebar to the right
} }
} }
.template-reference-topic h3,
.template-reference-topic h3 code {
color: var(--amr-green-dark) !important;
}
.template-reference-topic h3 {
font-weight: normal;
margin-top: 2rem;
}
/* replace 'Developers' with 'Maintainers' */ /* replace 'Developers' with 'Maintainers' */
.developers h2 { .developers h2 {
display: none; display: none;

View File

@@ -29,10 +29,22 @@
# ==================================================================== # # ==================================================================== #
*/ */
$(document).ready(function() { $(function () {
// add GPT assistant info // add GPT assistant info
$('aside').prepend('<div class="amr-gpt-assistant"><a target="_blank" href="https://chat.amr-for-r.org"><img src="https://amr-for-r.org/AMRforRGPT.svg"></a></div>'); $('aside').prepend('<div class="amr-gpt-assistant"><a target="_blank" href="https://chat.amr-for-r.org"><img src="https://amr-for-r.org/AMRforRGPT.svg"></a></div>');
// split version number in navbar into main version and build number
$('.nav-text').each(function () {
const $el = $(this);
const text = $.trim($el.text());
const lastDotIndex = text.lastIndexOf('.');
if (lastDotIndex > -1) {
const main = text.substring(0, lastDotIndex);
const build = text.substring(lastDotIndex);
$el.html(`<span class="version-main">${main}</span><span class="version-build">${build}</span>`);
}
});
// replace 'Developers' with 'Maintainers' on the main page, and "Contributors" on the Authors page // replace 'Developers' with 'Maintainers' on the main page, and "Contributors" on the Authors page
$(".developers h2").text("Maintainers"); $(".developers h2").text("Maintainers");
$(".template-citation-authors h1:nth(0)").text("Contributors and Citation"); $(".template-citation-authors h1:nth(0)").text("Contributors and Citation");

View File

@@ -63,10 +63,12 @@ test_that("test-zzz.R", {
"progress_bar" = "progress", "progress_bar" = "progress",
"read_html" = "xml2", "read_html" = "xml2",
"right_join" = "dplyr", "right_join" = "dplyr",
"select" = "dplyr",
"semi_join" = "dplyr", "semi_join" = "dplyr",
"showQuestion" = "rstudioapi", "showQuestion" = "rstudioapi",
"symbol" = "cli", "symbol" = "cli",
"tibble" = "tibble", "tibble" = "tibble",
"where" = "tidyselect",
"write.xlsx" = "openxlsx" "write.xlsx" = "openxlsx"
) )
@@ -127,6 +129,24 @@ test_that("test-zzz.R", {
"type_sum" = "pillar", "type_sum" = "pillar",
# readxl # readxl
"read_excel" = "readxl", "read_excel" = "readxl",
# recipes
"add_step" = "recipes",
"bake" = "recipes",
"check_new_data" = "recipes",
"check_type" = "recipes",
"has_role" = "recipes",
"is_trained" = "recipes",
"prep" = "recipes",
"print_step" = "recipes",
"rand_id" = "recipes",
"recipe" = "recipes",
"recipes_eval_select" = "recipes",
"sel2char" = "recipes",
"step" = "recipes",
"step_center" = "recipes",
"tidy" = "recipes",
# rlang
"enquos" = "rlang",
# rmarkdown # rmarkdown
"html_vignette" = "rmarkdown", "html_vignette" = "rmarkdown",
# skimr # skimr

View File

@@ -28,6 +28,13 @@ Antimicrobial resistance (AMR) is a global health crisis, and understanding resi
In this post, we will explore how to use the `tidymodels` framework to predict resistance patterns in the `example_isolates` dataset in two examples. In this post, we will explore how to use the `tidymodels` framework to predict resistance patterns in the `example_isolates` dataset in two examples.
This post contains the following examples:
1. Using Antimicrobial Selectors
2. Predicting ESBL Presence Using Raw MICs
3. Predicting AMR Over Time
## Example 1: Using Antimicrobial Selectors ## Example 1: Using Antimicrobial Selectors
By leveraging the power of `tidymodels` and the `AMR` package, well build a reproducible machine learning workflow to predict the Gramstain of the microorganism to two important antibiotic classes: aminoglycosides and beta-lactams. By leveraging the power of `tidymodels` and the `AMR` package, well build a reproducible machine learning workflow to predict the Gramstain of the microorganism to two important antibiotic classes: aminoglycosides and beta-lactams.
@@ -208,10 +215,150 @@ This workflow is extensible to other antimicrobial classes and resistance patter
--- ---
## Example 2: Predicting ESBL Presence Using Raw MICs
## Example 2: Predicting AMR Over Time In this second example, we demonstrate how to use `<mic>` columns directly in `tidymodels` workflows using AMR-specific recipe steps. This includes a transformation to `log2` scale using `step_mic_log2()`, which prepares MIC values for use in classification models.
In this second example, we aim to predict antimicrobial resistance (AMR) trends over time using `tidymodels`. We will model resistance to three antibiotics (amoxicillin `AMX`, amoxicillin-clavulanic acid `AMC`, and ciprofloxacin `CIP`), based on historical data grouped by year and hospital ward. This approach and idea formed the basis for the publication [DOI: 10.3389/fmicb.2025.1582703](https://doi.org/10.3389/fmicb.2025.1582703) to model the presence of extended-spectrum beta-lactamases (ESBL).
### **Objective**
Our goal is to:
1. Use raw MIC values to predict whether a bacterial isolate produces ESBL.
2. Apply AMR-aware preprocessing in a `tidymodels` recipe.
3. Train a classification model and evaluate its predictive performance.
### **Data Preparation**
We use the `esbl_isolates` dataset that comes with the AMR package.
```{r}
# Load required libraries
library(AMR)
library(tidymodels)
# View the esbl_isolates data set
esbl_isolates
# Prepare a binary outcome and convert to ordered factor
data <- esbl_isolates %>%
mutate(esbl = factor(esbl, levels = c(FALSE, TRUE), ordered = TRUE))
```
**Explanation:**
- `esbl_isolates`: Contains MIC test results and ESBL status for each isolate.
- `mutate(esbl = ...)`: Converts the target column to an ordered factor for classification.
### **Defining the Workflow**
#### 1. Preprocessing with a Recipe
We use our `step_mic_log2()` function to log2-transform MIC values, ensuring that MICs are numeric and properly scaled. All MIC predictors can easily and agnostically selected using the new `all_mic_predictors()`:
```{r}
# Split into training and testing sets
set.seed(123)
split <- initial_split(data)
training_data <- training(split)
testing_data <- testing(split)
# Define the recipe
mic_recipe <- recipe(esbl ~ ., data = training_data) %>%
remove_role(genus, old_role = "predictor") %>% # Remove non-informative variable
step_mic_log2(all_mic_predictors()) #%>% # Log2 transform all MIC predictors
# prep()
mic_recipe
```
**Explanation:**
- `remove_role()`: Removes irrelevant variables like genus.
- `step_mic_log2()`: Applies `log2(as.numeric(...))` to all MIC predictors in one go.
- `prep()`: Finalises the recipe based on training data.
#### 2. Specifying the Model
We use a simple logistic regression to model ESBL presence, though recent models such as xgboost ([link to `parsnip` manual](https://parsnip.tidymodels.org/reference/details_boost_tree_xgboost.html)) could be much more precise.
```{r}
# Define the model
model <- logistic_reg(mode = "classification") %>%
set_engine("glm")
model
```
**Explanation:**
- `logistic_reg()`: Specifies a binary classification model.
- `set_engine("glm")`: Uses the base R GLM engine.
#### 3. Building the Workflow
```{r}
# Create workflow
workflow_model <- workflow() %>%
add_recipe(mic_recipe) %>%
add_model(model)
workflow_model
```
### **Training and Evaluating the Model**
```{r}
# Fit the model
fitted <- fit(workflow_model, training_data)
# Generate predictions
predictions <- predict(fitted, testing_data) %>%
bind_cols(testing_data)
# Evaluate model performance
our_metrics <- metric_set(accuracy, kap, ppv, npv)
metrics <- our_metrics(predictions, truth = esbl, estimate = .pred_class)
metrics
```
**Explanation:**
- `fit()`: Trains the model on the processed training data.
- `predict()`: Produces predictions for unseen test data.
- `metric_set()`: Allows evaluating multiple classification metrics.
It appears we can predict ESBL gene presence with a positive predictive value (PPV) of `r round(metrics$.estimate[3], 3) * 100`% and a negative predictive value (NPV) of `r round(metrics$.estimate[4], 3) * 100` using a simplistic logistic regression model.
### **Visualising Predictions**
We can visualise predictions by comparing predicted and actual ESBL status.
```{r}
library(ggplot2)
ggplot(predictions, aes(x = esbl, fill = .pred_class)) +
geom_bar(position = "stack") +
labs(title = "Predicted vs Actual ESBL Status",
x = "Actual ESBL",
y = "Count") +
theme_minimal()
```
### **Conclusion**
In this example, we showcased how the new `AMR`-specific recipe steps simplify working with `<mic>` columns in `tidymodels`. The `step_mic_log2()` transformation converts ordered MICs to log2-transformed numerics, improving compatibility with classification models.
This pipeline enables realistic, reproducible, and interpretable modelling of antimicrobial resistance data.
---
## Example 3: Predicting AMR Over Time
In this third example, we aim to predict antimicrobial resistance (AMR) trends over time using `tidymodels`. We will model resistance to three antibiotics (amoxicillin `AMX`, amoxicillin-clavulanic acid `AMC`, and ciprofloxacin `CIP`), based on historical data grouped by year and hospital ward.
### **Objective** ### **Objective**

View File

@@ -28,7 +28,7 @@ Note: to keep the package size as small as possible, we only include this vignet
The `AMR` package is a peer-reviewed, [free and open-source](https://amr-for-r.org/#copyright) R package with [zero dependencies](https://en.wikipedia.org/wiki/Dependency_hell) to simplify the analysis and prediction of Antimicrobial Resistance (AMR) and to work with microbial and antimicrobial data and properties, by using evidence-based methods. **Our aim is to provide a standard** for clean and reproducible AMR data analysis, that can therefore empower epidemiological analyses to continuously enable surveillance and treatment evaluation in any setting. We are a team of [many different researchers](https://amr-for-r.org/authors.html) from around the globe to make this a successful and durable project! The `AMR` package is a peer-reviewed, [free and open-source](https://amr-for-r.org/#copyright) R package with [zero dependencies](https://en.wikipedia.org/wiki/Dependency_hell) to simplify the analysis and prediction of Antimicrobial Resistance (AMR) and to work with microbial and antimicrobial data and properties, by using evidence-based methods. **Our aim is to provide a standard** for clean and reproducible AMR data analysis, that can therefore empower epidemiological analyses to continuously enable surveillance and treatment evaluation in any setting. We are a team of [many different researchers](https://amr-for-r.org/authors.html) from around the globe to make this a successful and durable project!
This work was published in the Journal of Statistical Software (Volume 104(3); \doi{10.18637/jss.v104.i03}) and formed the basis of two PhD theses (\doi{10.33612/diss.177417131} and \doi{10.33612/diss.192486375}). This work was published in the Journal of Statistical Software (Volume 104(3); [DOI 10.18637/jss.v104.i03](https://doi.org/10.18637/jss.v104.i03)) and formed the basis of two PhD theses ([DOI 10.33612/diss.177417131](https://doi.org/10.33612/diss.177417131) and [DOI 10.33612/diss.192486375](https://doi.org/10.33612/diss.192486375)).
After installing this package, R knows [**`r AMR:::format_included_data_number(AMR::microorganisms)` distinct microbial species**](https://amr-for-r.org/reference/microorganisms.html) (updated June 2024) and all [**`r AMR:::format_included_data_number(NROW(AMR::antimicrobials) + NROW(AMR::antivirals))` antimicrobial and antiviral drugs**](https://amr-for-r.org/reference/antimicrobials.html) by name and code (including ATC, EARS-Net, ASIARS-Net, PubChem, LOINC and SNOMED CT), and knows all about valid SIR and MIC values. The integral clinical breakpoint guidelines from CLSI `r min(as.integer(gsub("[^0-9]", "", subset(AMR::clinical_breakpoints, grepl("CLSI", guideline))$guideline)))`-`r max(as.integer(gsub("[^0-9]", "", subset(AMR::clinical_breakpoints, grepl("CLSI", guideline))$guideline)))` and EUCAST `r min(as.integer(gsub("[^0-9]", "", subset(AMR::clinical_breakpoints, grepl("EUCAST", guideline))$guideline)))`-`r max(as.integer(gsub("[^0-9]", "", subset(AMR::clinical_breakpoints, grepl("EUCAST", guideline))$guideline)))` are included, even with epidemiological cut-off (ECOFF) values. It supports and can read any data format, including WHONET data. This package works on Windows, macOS and Linux with all versions of R since R-3.0 (April 2013). **It was designed to work in any setting, including those with very limited resources**. It was created for both routine data analysis and academic research at the Faculty of Medical Sciences of the [University of Groningen](https://www.rug.nl) and the [University Medical Center Groningen](https://www.umcg.nl). After installing this package, R knows [**`r AMR:::format_included_data_number(AMR::microorganisms)` distinct microbial species**](https://amr-for-r.org/reference/microorganisms.html) (updated June 2024) and all [**`r AMR:::format_included_data_number(NROW(AMR::antimicrobials) + NROW(AMR::antivirals))` antimicrobial and antiviral drugs**](https://amr-for-r.org/reference/antimicrobials.html) by name and code (including ATC, EARS-Net, ASIARS-Net, PubChem, LOINC and SNOMED CT), and knows all about valid SIR and MIC values. The integral clinical breakpoint guidelines from CLSI `r min(as.integer(gsub("[^0-9]", "", subset(AMR::clinical_breakpoints, grepl("CLSI", guideline))$guideline)))`-`r max(as.integer(gsub("[^0-9]", "", subset(AMR::clinical_breakpoints, grepl("CLSI", guideline))$guideline)))` and EUCAST `r min(as.integer(gsub("[^0-9]", "", subset(AMR::clinical_breakpoints, grepl("EUCAST", guideline))$guideline)))`-`r max(as.integer(gsub("[^0-9]", "", subset(AMR::clinical_breakpoints, grepl("EUCAST", guideline))$guideline)))` are included, even with epidemiological cut-off (ECOFF) values. It supports and can read any data format, including WHONET data. This package works on Windows, macOS and Linux with all versions of R since R-3.0 (April 2013). **It was designed to work in any setting, including those with very limited resources**. It was created for both routine data analysis and academic research at the Faculty of Medical Sciences of the [University of Groningen](https://www.rug.nl) and the [University Medical Center Groningen](https://www.umcg.nl).