mirror of
https://github.com/msberends/AMR.git
synced 2025-09-02 08:20:54 +02:00
Compare commits
12 Commits
0138e33ce9
...
sir-s3-upd
Author | SHA1 | Date | |
---|---|---|---|
d232666e49 | |||
fc72cf9324 | |||
2f866985c9 | |||
6cb724a208 | |||
49274f010b | |||
8da0f525b5 | |||
|
68442f3042 | ||
39ea5f6597 | |||
65ec098acf | |||
|
e9e3de4469 | ||
d94bdd2c6a | |||
8dab0a3730 |
87
.github/prehooks/pre-commit
vendored
87
.github/prehooks/pre-commit
vendored
@@ -68,49 +68,56 @@ echo ""
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
echo "Updating semantic versioning and date..."
|
||||
|
||||
# Get tags from remote and remove tags not on remote
|
||||
git fetch origin --prune --prune-tags --quiet
|
||||
currenttagfull=$(git describe --tags --abbrev=0)
|
||||
currenttag=$(git describe --tags --abbrev=0 | sed 's/v//')
|
||||
|
||||
# Assume main branch to be 'main' or 'master'
|
||||
defaultbranch=$(git branch | cut -c 3- | grep -E '^master$|^main$')
|
||||
if [ "$currenttag" = "" ]; then
|
||||
currenttag="0.0.1"
|
||||
currentcommit=$(git rev-list --count ${defaultbranch})
|
||||
echo "- No git tags found, creating one in format 'v(x).(y).(z)' - currently ${currentcommit} previous commits in '${defaultbranch}'"
|
||||
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
|
||||
currentcommit=$(git rev-list --count ${currenttagfull}..${defaultbranch})
|
||||
echo "- Latest tag is '${currenttagfull}', with ${currentcommit} previous commits in '${defaultbranch}'"
|
||||
fi
|
||||
|
||||
# Combine tag and commit number
|
||||
currentversion="$currenttag.$((currentcommit + 9001))"
|
||||
echo "- ${currentpkg} pkg version set to ${currentversion}"
|
||||
|
||||
# Update version number and date in DESCRIPTION
|
||||
sed -i -- "s/^Version: .*/Version: ${currentversion}/" DESCRIPTION
|
||||
sed -i -- "s/^Date: .*/Date: $(date '+%Y-%m-%d')/" DESCRIPTION
|
||||
echo "- Updated version number and date in ./DESCRIPTION"
|
||||
rm -f DESCRIPTION--
|
||||
git add DESCRIPTION
|
||||
|
||||
# Update version number in NEWS.md
|
||||
if [ -e "NEWS.md" ]; then
|
||||
if [ "$currentpkg" = "your" ]; then
|
||||
currentpkg=""
|
||||
# Version update logic begins here
|
||||
|
||||
# Get tags from remote and remove tags not on remote
|
||||
git fetch origin --prune --prune-tags --quiet
|
||||
currenttagfull=$(git describe --tags --abbrev=0)
|
||||
currenttag=$(git describe --tags --abbrev=0 | sed 's/v//')
|
||||
|
||||
# Assume main branch to be 'main' or 'master'
|
||||
defaultbranch=$(git branch | cut -c 3- | grep -E '^master$|^main$')
|
||||
if [ "$currenttag" = "" ]; then
|
||||
currenttag="0.0.1"
|
||||
currentcommit=$(git rev-list --count ${defaultbranch})
|
||||
echo "- No git tags found, creating one in format 'v(x).(y).(z)' - currently ${currentcommit} previous commits in '${defaultbranch}'"
|
||||
else
|
||||
currentcommit=$(git rev-list --count ${currenttagfull}..${defaultbranch})
|
||||
echo "- Latest tag is '${currenttagfull}', with ${currentcommit} previous commits in '${defaultbranch}'"
|
||||
fi
|
||||
sed -i -- "1s/.*/# ${currentpkg} ${currentversion}/" NEWS.md
|
||||
echo "- Updated version number in ./NEWS.md"
|
||||
rm -f NEWS.md--
|
||||
git add NEWS.md
|
||||
else
|
||||
echo "- No NEWS.md found!"
|
||||
|
||||
# Combine tag and commit number
|
||||
currentversion="$currenttag.$((currentcommit + 9001))"
|
||||
echo "- ${currentpkg} pkg version set to ${currentversion}"
|
||||
|
||||
# Update version number and date in DESCRIPTION
|
||||
sed -i -- "s/^Version: .*/Version: ${currentversion}/" DESCRIPTION
|
||||
sed -i -- "s/^Date: .*/Date: $(date '+%Y-%m-%d')/" DESCRIPTION
|
||||
echo "- Updated version number and date in ./DESCRIPTION"
|
||||
rm -f DESCRIPTION--
|
||||
git add DESCRIPTION
|
||||
|
||||
# Update version number in NEWS.md
|
||||
if [ -e "NEWS.md" ]; then
|
||||
if [ "$currentpkg" = "your" ]; then
|
||||
currentpkg=""
|
||||
fi
|
||||
sed -i -- "1s/.*/# ${currentpkg} ${currentversion}/" NEWS.md
|
||||
echo "- Updated version number in ./NEWS.md"
|
||||
rm -f NEWS.md--
|
||||
git add NEWS.md
|
||||
else
|
||||
echo "- No NEWS.md found!"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Save the version number for use in the commit-msg hook
|
||||
echo "${currentversion}" > .git/commit_version.tmp
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Save the version number for use in the commit-msg hook
|
||||
echo "${currentversion}" > .git/commit_version.tmp
|
||||
|
||||
git add data-raw/*
|
||||
git add data/*
|
||||
|
7
.github/workflows/check-old-tinytest.yaml
vendored
7
.github/workflows/check-old-tinytest.yaml
vendored
@@ -59,8 +59,15 @@ jobs:
|
||||
|
||||
env:
|
||||
R_REMOTES_NO_ERRORS_FROM_WARNINGS: true
|
||||
LANG: en_US.UTF-8
|
||||
LC_ALL: en_US.UTF-8
|
||||
|
||||
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: r-lib/actions/setup-r@v2
|
||||
|
@@ -1,6 +1,6 @@
|
||||
Package: AMR
|
||||
Version: 3.0.0.9004
|
||||
Date: 2025-06-13
|
||||
Version: 3.0.0.9017
|
||||
Date: 2025-07-28
|
||||
Title: Antimicrobial Resistance Data Analysis
|
||||
Description: Functions to simplify and standardise antimicrobial resistance (AMR)
|
||||
data analysis and to work with microbial and antimicrobial properties by
|
||||
|
@@ -12,6 +12,7 @@ S3method("[",deprecated_amr_dataset)
|
||||
S3method("[",disk)
|
||||
S3method("[",mic)
|
||||
S3method("[",mo)
|
||||
S3method("[",sir)
|
||||
S3method("[<-",ab)
|
||||
S3method("[<-",av)
|
||||
S3method("[<-",disk)
|
||||
@@ -24,6 +25,7 @@ S3method("[[",deprecated_amr_dataset)
|
||||
S3method("[[",disk)
|
||||
S3method("[[",mic)
|
||||
S3method("[[",mo)
|
||||
S3method("[[",sir)
|
||||
S3method("[[<-",ab)
|
||||
S3method("[[<-",av)
|
||||
S3method("[[<-",disk)
|
||||
@@ -99,6 +101,7 @@ S3method(print,custom_eucast_rules)
|
||||
S3method(print,custom_mdro_guideline)
|
||||
S3method(print,deprecated_amr_dataset)
|
||||
S3method(print,disk)
|
||||
S3method(print,interpreted_sir)
|
||||
S3method(print,mic)
|
||||
S3method(print,mo)
|
||||
S3method(print,mo_renamed)
|
||||
|
14
NEWS.md
14
NEWS.md
@@ -1,16 +1,24 @@
|
||||
# AMR 3.0.0.9004
|
||||
# AMR 3.0.0.9017
|
||||
|
||||
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
|
||||
- `tidyselect` helpers: `all_mic()`, `all_mic_predictors()`, `all_sir()`, `all_sir_predictors()`
|
||||
- Enables seamless use of MIC and SIR data in modelling pipelines via `recipes`
|
||||
- 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 all plotting to contain a separate colour for SDD (susceptible dose-dependent) (#223)
|
||||
* Fixed some specific Dutch translations for antimicrobials
|
||||
* 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)
|
||||
* Updated `random_mic()` and `random_disk()` to set skewedness of the distribution and allow multiple microorganisms
|
||||
|
||||
|
||||
|
@@ -63,31 +63,6 @@ pm_left_join <- function(x, y, by = NULL, suffix = c(".x", ".y")) {
|
||||
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)
|
||||
# https://github.com/nathaneastwood/poorman, MIT licensed, Nathan Eastwood, 2020
|
||||
case_when_AMR <- function(...) {
|
||||
@@ -544,7 +519,7 @@ word_wrap <- function(...,
|
||||
)
|
||||
msg <- paste0(parts, collapse = "`")
|
||||
}
|
||||
msg <- gsub("`(.+?)`", font_grey_bg("\\1"), msg)
|
||||
msg <- gsub("`(.+?)`", font_grey_bg("`\\1`"), msg)
|
||||
|
||||
# clean introduced whitespace in between fullstops
|
||||
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:
|
||||
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)) {
|
||||
error_txt <- AMR_env$meet_criteria_error_txt
|
||||
@@ -1319,6 +1294,10 @@ font_green_bg <- function(..., collapse = " ") {
|
||||
# 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)
|
||||
}
|
||||
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 = " ") {
|
||||
try_colour(font_black(..., collapse = collapse, adapt = FALSE), before = "\033[48;5;89m", after = "\033[49m", collapse = collapse)
|
||||
}
|
||||
@@ -1636,6 +1615,36 @@ get_n_cores <- function(max_cores = Inf) {
|
||||
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 ----
|
||||
|
||||
match <- function(x, table, ...) {
|
||||
@@ -1655,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 ----
|
||||
# these functions were not available in previous versions of R
|
||||
# see here for the full list: https://github.com/r-lib/backports
|
||||
|
@@ -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 <- function(.data, ...) {
|
||||
col_pos <- pm_select_positions(.data, ..., .group_pos = TRUE)
|
||||
# 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)
|
||||
}
|
||||
}
|
||||
|
||||
map_names <- names(col_pos)
|
||||
map_names_length <- nchar(map_names)
|
||||
if (any(map_names_length == 0L)) {
|
||||
|
3
R/ab.R
3
R/ab.R
@@ -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)]
|
||||
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)]
|
||||
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_(
|
||||
"Returning previously coerced ",
|
||||
ifelse(length(unique(which(x[which(previously_coerced)] %in% x_bak_clean))) > 1, "value for an antimicrobial", "values for various antimicrobials"),
|
||||
|
@@ -445,7 +445,7 @@ ab_validate <- function(x, property, ...) {
|
||||
# try to catch an error when inputting an invalid argument
|
||||
# so the 'call.' can be set to FALSE
|
||||
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])) {
|
||||
|
12
R/age.R
12
R/age.R
@@ -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 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 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.
|
||||
#' @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+
|
||||
#' 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
|
||||
#' 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(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)
|
||||
|
||||
if (any(x < 0, na.rm = TRUE)) {
|
||||
@@ -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)
|
||||
|
||||
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)) {
|
||||
agegroups <- agegroups[!is.na(agegroups)]
|
||||
}
|
||||
|
@@ -527,7 +527,7 @@ amr_selector <- function(filter,
|
||||
)
|
||||
call <- substitute(filter)
|
||||
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]
|
||||
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)])]
|
||||
|
@@ -576,6 +576,15 @@ antibiogram.default <- function(x,
|
||||
}
|
||||
antimicrobials <- unlist(antimicrobials)
|
||||
} 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
|
||||
}
|
||||
|
||||
|
@@ -264,7 +264,7 @@ av_validate <- function(x, property, ...) {
|
||||
# try to catch an error when inputting an invalid argument
|
||||
# so the 'call.' can be set to FALSE
|
||||
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])) {
|
||||
|
18
R/count.R
18
R/count.R
@@ -126,7 +126,7 @@ count_resistant <- function(..., only_all_tested = FALSE) {
|
||||
only_all_tested = only_all_tested,
|
||||
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_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_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_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_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_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_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_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,
|
||||
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)
|
||||
)
|
||||
}
|
||||
|
@@ -175,7 +175,7 @@ custom_mdro_guideline <- function(..., as_factor = TRUE) {
|
||||
|
||||
# Value
|
||||
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))
|
||||
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)) {
|
||||
qry <- tryCatch(eval(parse(text = guideline[[i]]$query), envir = df, enclos = parent.frame()),
|
||||
error = function(e) {
|
||||
AMR_env$err_msg <- e$message
|
||||
AMR_env$err_msg <- conditionMessage(e)
|
||||
return("error")
|
||||
}
|
||||
)
|
||||
|
@@ -1178,7 +1178,7 @@ edit_sir <- function(x,
|
||||
ifelse(length(rows) > 10, "...", ""),
|
||||
" while writing value '", to,
|
||||
"' to column(s) `", paste(cols, collapse = "`, `"),
|
||||
"`:\n", e$message
|
||||
"`:\n", conditionMessage(e)
|
||||
),
|
||||
call. = FALSE
|
||||
)
|
||||
|
@@ -177,6 +177,7 @@ ggplot_sir <- function(data,
|
||||
nrow = NULL,
|
||||
colours = c(
|
||||
S = "#3CAEA3",
|
||||
SDD = "#8FD6C4",
|
||||
SI = "#3CAEA3",
|
||||
I = "#F6D55C",
|
||||
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)
|
||||
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(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.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)
|
||||
@@ -245,7 +246,7 @@ ggplot_sir <- function(data,
|
||||
) +
|
||||
theme_sir()
|
||||
|
||||
if (fill == "interpretation") {
|
||||
if (fill == "interpretation" && !is.null(colours) && !isFALSE(colours)) {
|
||||
p <- suppressWarnings(p + scale_sir_colours(aesthetics = "fill", colours = colours))
|
||||
}
|
||||
|
||||
|
@@ -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.
|
||||
#' @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`.
|
||||
#' @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.
|
||||
#'
|
||||
|
2
R/mo.R
2
R/mo.R
@@ -1186,7 +1186,7 @@ parse_and_convert <- function(x) {
|
||||
parsed <- gsub('"', "", parsed, fixed = TRUE)
|
||||
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)`
|
||||
}
|
||||
out <- trimws2(out)
|
||||
|
@@ -974,7 +974,7 @@ mo_validate <- function(x, property, language, keep_synonyms = keep_synonyms, ..
|
||||
# try to catch an error when inputting an invalid argument
|
||||
# so the 'call.' can be set to FALSE
|
||||
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(...)
|
||||
|
2
R/pca.R
2
R/pca.R
@@ -99,7 +99,7 @@ pca <- function(x,
|
||||
new_list <- list(0)
|
||||
for (i in seq_len(length(dots) - 1)) {
|
||||
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 (is.character(new_list[[i]]) && new_list[[i]] %in% colnames(x)) {
|
||||
|
320
R/plotting.R
320
R/plotting.R
@@ -90,6 +90,10 @@
|
||||
#' 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")) {
|
||||
#' # support for 27 languages, various guidelines, and many options
|
||||
#' autoplot(some_disk_values,
|
||||
#' mo = "Escherichia coli", ab = "cipro",
|
||||
@@ -146,7 +150,7 @@
|
||||
#' aes(group, mic)
|
||||
#' ) +
|
||||
#' geom_boxplot() +
|
||||
#' geom_violin(linetype = 2, colour = "grey", fill = NA) +
|
||||
#' geom_violin(linetype = 2, colour = "grey30", fill = NA) +
|
||||
#' scale_y_mic()
|
||||
#' }
|
||||
#' if (require("ggplot2")) {
|
||||
@@ -158,7 +162,7 @@
|
||||
#' aes(group, mic)
|
||||
#' ) +
|
||||
#' 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))
|
||||
#' }
|
||||
#'
|
||||
@@ -191,7 +195,7 @@
|
||||
#' aes(x = group, y = mic, colour = sir)
|
||||
#' ) +
|
||||
#' theme_minimal() +
|
||||
#' geom_boxplot(fill = NA, colour = "grey") +
|
||||
#' geom_boxplot(fill = NA, colour = "grey30") +
|
||||
#' geom_jitter(width = 0.25)
|
||||
#'
|
||||
#' plain
|
||||
@@ -377,6 +381,8 @@ create_scale_sir <- function(aesthetics, colours_SIR, language, eucast_I, ...) {
|
||||
args <- list(...)
|
||||
args[c("value", "labels", "limits")] <- NULL
|
||||
|
||||
colours_SIR <- expand_SIR_colours(colours_SIR, unname = FALSE)
|
||||
|
||||
if (identical(aesthetics, "x")) {
|
||||
ggplot_fn <- ggplot2::scale_x_discrete
|
||||
} else {
|
||||
@@ -385,24 +391,19 @@ create_scale_sir <- function(aesthetics, colours_SIR, language, eucast_I, ...) {
|
||||
args,
|
||||
list(
|
||||
aesthetics = aesthetics,
|
||||
values = c(
|
||||
S = colours_SIR[1],
|
||||
SDD = colours_SIR[2],
|
||||
I = colours_SIR[2],
|
||||
R = colours_SIR[3],
|
||||
NI = "grey30"
|
||||
)
|
||||
values = c(colours_SIR, NI = "grey30")
|
||||
)
|
||||
)
|
||||
}
|
||||
scale <- do.call(ggplot_fn, args)
|
||||
|
||||
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`.",
|
||||
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)) {
|
||||
x[x == "S"] <- "(S) Susceptible"
|
||||
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 == "R"] <- "(R) Resistant"
|
||||
x[x == "SI"] <- "(S/I) Susceptible"
|
||||
x[x == "IR"] <- "(I/R) Non-susceptible"
|
||||
x[x == "NI"] <- "(NI) Non-interpretable"
|
||||
x <- translate_AMR(x, language = language)
|
||||
}
|
||||
@@ -419,7 +422,7 @@ create_scale_sir <- function(aesthetics, colours_SIR, language, eucast_I, ...) {
|
||||
}
|
||||
scale$limits <- function(x, ...) {
|
||||
# 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
|
||||
@@ -427,11 +430,16 @@ create_scale_sir <- function(aesthetics, colours_SIR, language, eucast_I, ...) {
|
||||
|
||||
#' @rdname plot
|
||||
#' @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(),
|
||||
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)
|
||||
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)
|
||||
@@ -439,11 +447,16 @@ scale_x_sir <- function(colours_SIR = c("#3CAEA3", "#F6D55C", "#ED553B"),
|
||||
|
||||
#' @rdname plot
|
||||
#' @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(),
|
||||
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)
|
||||
meet_criteria(eucast_I, allow_class = "logical", has_length = 1)
|
||||
args <- list(...)
|
||||
@@ -463,11 +476,16 @@ scale_color_sir <- scale_colour_sir
|
||||
|
||||
#' @rdname plot
|
||||
#' @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(),
|
||||
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)
|
||||
meet_criteria(eucast_I, allow_class = "logical", has_length = 1)
|
||||
args <- list(...)
|
||||
@@ -491,7 +509,12 @@ plot.mic <- function(x,
|
||||
main = deparse(substitute(x)),
|
||||
ylab = translate_AMR("Frequency", 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(),
|
||||
expand = 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(ylab, 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)
|
||||
meet_criteria(expand, allow_class = "logical", has_length = 1)
|
||||
|
||||
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 = " "))
|
||||
colours_SIR <- expand_SIR_colours(colours_SIR)
|
||||
|
||||
x <- plotrange_as_table(x, expand = expand)
|
||||
cols_sub <- plot_colours_subtitle_guideline(
|
||||
@@ -549,13 +569,17 @@ plot.mic <- function(x,
|
||||
legend_col <- colours_SIR[1]
|
||||
}
|
||||
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])
|
||||
}
|
||||
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])
|
||||
}
|
||||
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",
|
||||
x.intersp = 0.5,
|
||||
@@ -580,7 +604,12 @@ barplot.mic <- function(height,
|
||||
main = deparse(substitute(height)),
|
||||
ylab = translate_AMR("Frequency", 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(),
|
||||
expand = TRUE,
|
||||
...) {
|
||||
@@ -590,7 +619,7 @@ barplot.mic <- function(height,
|
||||
meet_criteria(mo, allow_class = c("mo", "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(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)
|
||||
meet_criteria(expand, allow_class = "logical", has_length = 1)
|
||||
|
||||
@@ -622,7 +651,12 @@ autoplot.mic <- function(object,
|
||||
title = deparse(substitute(object)),
|
||||
ylab = translate_AMR("Frequency", 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(),
|
||||
expand = 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(ylab, 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)
|
||||
meet_criteria(expand, allow_class = "logical", has_length = 1)
|
||||
|
||||
@@ -646,6 +680,8 @@ autoplot.mic <- function(object,
|
||||
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
|
||||
x <- plotrange_as_table(object, expand = expand)
|
||||
cols_sub <- plot_colours_subtitle_guideline(
|
||||
@@ -665,12 +701,14 @@ autoplot.mic <- function(object,
|
||||
colnames(df) <- c("mic", "count")
|
||||
df$cols <- cols_sub$cols
|
||||
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[3]] <- "(R) Resistant"
|
||||
df$cols[df$cols == colours_SIR[2]] <- "(SDD) Susceptible dose-dependent"
|
||||
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),
|
||||
levels = translate_into_language(
|
||||
c(
|
||||
"(S) Susceptible",
|
||||
"(SDD) Susceptible dose-dependent",
|
||||
paste("(I)", plot_name_of_I(cols_sub$guideline)),
|
||||
"(R) Resistant"
|
||||
),
|
||||
@@ -684,10 +722,10 @@ autoplot.mic <- function(object,
|
||||
vals <- c(
|
||||
"(S) Susceptible" = colours_SIR[1],
|
||||
"(SDD) Susceptible dose-dependent" = colours_SIR[2],
|
||||
"(I) Susceptible, incr. exp." = colours_SIR[2],
|
||||
"(I) Intermediate" = colours_SIR[2],
|
||||
"(R) Resistant" = colours_SIR[3],
|
||||
"(NI) Non-interpretable" = "grey"
|
||||
"(I) Susceptible, incr. exp." = colours_SIR[3],
|
||||
"(I) Intermediate" = colours_SIR[3],
|
||||
"(R) Resistant" = colours_SIR[4],
|
||||
"(NI) Non-interpretable" = "grey30"
|
||||
)
|
||||
names(vals) <- translate_into_language(names(vals), language = language)
|
||||
p <- p +
|
||||
@@ -731,7 +769,12 @@ plot.disk <- function(x,
|
||||
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 = "#ED553B"
|
||||
),
|
||||
language = get_AMR_locale(),
|
||||
expand = 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(ab, allow_class = c("ab", "character"), allow_NULL = TRUE)
|
||||
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)
|
||||
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 = " "))
|
||||
colours_SIR <- expand_SIR_colours(colours_SIR)
|
||||
|
||||
x <- plotrange_as_table(x, expand = expand)
|
||||
cols_sub <- plot_colours_subtitle_guideline(
|
||||
@@ -783,12 +824,16 @@ plot.disk <- function(x,
|
||||
if (any(colours_SIR %in% cols_sub$cols)) {
|
||||
legend_txt <- 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_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)) {
|
||||
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])
|
||||
}
|
||||
if (any(cols_sub$cols == colours_SIR[1] & cols_sub$count > 0)) {
|
||||
@@ -818,7 +863,12 @@ barplot.disk <- function(height,
|
||||
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 = "#ED553B"
|
||||
),
|
||||
language = get_AMR_locale(),
|
||||
expand = TRUE,
|
||||
...) {
|
||||
@@ -828,7 +878,7 @@ barplot.disk <- function(height,
|
||||
meet_criteria(mo, allow_class = c("mo", "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(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)
|
||||
meet_criteria(expand, allow_class = "logical", has_length = 1)
|
||||
|
||||
@@ -858,7 +908,12 @@ autoplot.disk <- function(object,
|
||||
ylab = translate_AMR("Frequency", language = language),
|
||||
xlab = translate_AMR("Disk diffusion diameter (mm)", language = language),
|
||||
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(),
|
||||
expand = 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(ab, allow_class = c("ab", "character"), allow_NULL = TRUE)
|
||||
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)
|
||||
meet_criteria(expand, allow_class = "logical", has_length = 1)
|
||||
|
||||
@@ -882,6 +937,8 @@ autoplot.disk <- function(object,
|
||||
title <- gsub(" +", " ", paste0(title, collapse = " "))
|
||||
}
|
||||
|
||||
colours_SIR <- expand_SIR_colours(colours_SIR)
|
||||
|
||||
x <- plotrange_as_table(object, expand = expand)
|
||||
cols_sub <- plot_colours_subtitle_guideline(
|
||||
x = x,
|
||||
@@ -899,10 +956,10 @@ autoplot.disk <- function(object,
|
||||
df <- as.data.frame(x, stringsAsFactors = TRUE)
|
||||
colnames(df) <- c("disk", "count")
|
||||
df$cols <- cols_sub$cols
|
||||
|
||||
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[3]] <- "(R) Resistant"
|
||||
df$cols[df$cols == colours_SIR[2]] <- "(SDD) Susceptible dose-dependent"
|
||||
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),
|
||||
levels = translate_into_language(
|
||||
c(
|
||||
@@ -920,10 +977,10 @@ autoplot.disk <- function(object,
|
||||
vals <- c(
|
||||
"(S) Susceptible" = colours_SIR[1],
|
||||
"(SDD) Susceptible dose-dependent" = colours_SIR[2],
|
||||
"(I) Susceptible, incr. exp." = colours_SIR[2],
|
||||
"(I) Intermediate" = colours_SIR[2],
|
||||
"(R) Resistant" = colours_SIR[3],
|
||||
"(NI) Non-interpretable" = "grey"
|
||||
"(I) Susceptible, incr. exp." = colours_SIR[3],
|
||||
"(I) Intermediate" = colours_SIR[3],
|
||||
"(R) Resistant" = colours_SIR[4],
|
||||
"(NI) Non-interpretable" = "grey30"
|
||||
)
|
||||
names(vals) <- translate_into_language(names(vals), language = language)
|
||||
p <- p +
|
||||
@@ -1024,22 +1081,26 @@ barplot.sir <- function(height,
|
||||
main = deparse(substitute(height)),
|
||||
xlab = translate_AMR("Antimicrobial Interpretation", 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(),
|
||||
expand = TRUE,
|
||||
...) {
|
||||
meet_criteria(xlab, allow_class = "character", has_length = 1)
|
||||
meet_criteria(main, allow_class = "character", has_length = 1, allow_NULL = TRUE)
|
||||
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)
|
||||
meet_criteria(expand, allow_class = "logical", has_length = 1)
|
||||
|
||||
if (length(colours_SIR) == 1) {
|
||||
colours_SIR <- rep(colours_SIR, 3)
|
||||
}
|
||||
colours_SIR <- expand_SIR_colours(colours_SIR)
|
||||
|
||||
# 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 = " "))
|
||||
|
||||
x <- table(height)
|
||||
@@ -1065,14 +1126,19 @@ autoplot.sir <- function(object,
|
||||
title = deparse(substitute(object)),
|
||||
xlab = translate_AMR("Antimicrobial Interpretation", 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(),
|
||||
...) {
|
||||
stop_ifnot_installed("ggplot2")
|
||||
meet_criteria(title, allow_class = "character", allow_NULL = TRUE)
|
||||
meet_criteria(ylab, 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(...))) {
|
||||
title <- list(...)$main
|
||||
@@ -1081,9 +1147,7 @@ autoplot.sir <- function(object,
|
||||
title <- gsub(" +", " ", paste0(title, collapse = " "))
|
||||
}
|
||||
|
||||
if (length(colours_SIR) == 1) {
|
||||
colours_SIR <- rep(colours_SIR, 3)
|
||||
}
|
||||
colours_SIR <- expand_SIR_colours(colours_SIR)
|
||||
|
||||
df <- as.data.frame(table(object), stringsAsFactors = TRUE)
|
||||
colnames(df) <- c("x", "n")
|
||||
@@ -1095,9 +1159,9 @@ autoplot.sir <- function(object,
|
||||
values = c(
|
||||
"S" = colours_SIR[1],
|
||||
"SDD" = colours_SIR[2],
|
||||
"I" = colours_SIR[2],
|
||||
"R" = colours_SIR[3],
|
||||
"NI" = "#888888"
|
||||
"I" = colours_SIR[3],
|
||||
"R" = colours_SIR[4],
|
||||
"NI" = "grey30"
|
||||
),
|
||||
limits = force
|
||||
) +
|
||||
@@ -1223,9 +1287,9 @@ plot_colours_subtitle_guideline <- function(x, mo, ab, guideline, colours_SIR, f
|
||||
cols[is.na(sir)] <- "#BEBEBE"
|
||||
cols[sir == "S"] <- colours_SIR[1]
|
||||
cols[sir == "SDD"] <- colours_SIR[2]
|
||||
cols[sir == "I"] <- colours_SIR[2]
|
||||
cols[sir == "R"] <- colours_SIR[3]
|
||||
cols[sir == "NI"] <- "#888888"
|
||||
cols[sir == "I"] <- colours_SIR[3]
|
||||
cols[sir == "R"] <- colours_SIR[4]
|
||||
cols[sir == "NI"] <- "grey30"
|
||||
sub <- bquote(.(abname) ~ "-" ~ italic(.(moname)) ~ .(guideline_txt))
|
||||
} else {
|
||||
cols <- "#BEBEBE"
|
||||
@@ -1284,10 +1348,15 @@ scale_y_percent <- function(breaks = function(x) seq(0, max(x, na.rm = TRUE), 0.
|
||||
#' @export
|
||||
scale_sir_colours <- function(...,
|
||||
aesthetics,
|
||||
colours_SIR = c("#3CAEA3", "#F6D55C", "#ED553B")) {
|
||||
colours_SIR = c(
|
||||
S = "#3CAEA3",
|
||||
SDD = "#8FD6C4",
|
||||
I = "#F6D55C",
|
||||
R = "#ED553B"
|
||||
)) {
|
||||
stop_ifnot_installed("ggplot2")
|
||||
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)) {
|
||||
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.")
|
||||
}
|
||||
|
||||
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(...))) {
|
||||
original_cols <- c(
|
||||
S = colours_SIR[1],
|
||||
SI = colours_SIR[1],
|
||||
I = colours_SIR[2],
|
||||
IR = colours_SIR[3],
|
||||
R = colours_SIR[3]
|
||||
)
|
||||
colours <- replace(original_cols, names(list(...)$colours), list(...)$colours)
|
||||
colours_SIR <- list(...)$colours
|
||||
}
|
||||
|
||||
colours_SIR <- expand_SIR_colours(colours_SIR, unname = FALSE)
|
||||
|
||||
# behaviour when coming from ggplot_sir()
|
||||
if ("colours" %in% names(list(...))) {
|
||||
# limits = force is needed in ggplot2 3.3.4 and 3.3.5, see here;
|
||||
# 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)) {
|
||||
return(invisible())
|
||||
}
|
||||
|
||||
names_susceptible <- c(
|
||||
"S", "SI", "IS", "S+I", "I+S", "susceptible", "Susceptible",
|
||||
unique(TRANSLATIONS[which(TRANSLATIONS$pattern == "Susceptible"),
|
||||
"replacement",
|
||||
drop = TRUE
|
||||
])
|
||||
)
|
||||
colours_SIR <- unname(colours_SIR)
|
||||
|
||||
names_susceptible <- c("S", "SI", "IS", "S+I", "I+S", "susceptible", "Susceptible")
|
||||
names_susceptible_dose_dep <- c("SDD", "susceptible dose-dependent", "Susceptible dose-dependent")
|
||||
names_incr_exposure <- c(
|
||||
"I", "intermediate", "increased exposure", "incr. exposure",
|
||||
"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
|
||||
])
|
||||
"Increased exposure", "Incr. exposure", "Susceptible, incr. exp."
|
||||
)
|
||||
names_resistant <- c("R", "IR", "RI", "R+I", "I+R", "resistant", "Resistant")
|
||||
|
||||
susceptible <- rep(colours_SIR[1], length(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
|
||||
resistant <- rep(colours_SIR[3], length(names_resistant))
|
||||
resistant <- rep(colours_SIR[4], length(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(...)
|
||||
# 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 == "I"] <- colours_SIR[2]
|
||||
dots[dots == "R"] <- colours_SIR[3]
|
||||
dots[dots == "SDD"] <- colours_SIR[2]
|
||||
dots[dots == "I"] <- colours_SIR[3]
|
||||
dots[dots == "R"] <- colours_SIR[4]
|
||||
cols <- replace(original_cols, names(dots), dots)
|
||||
# limits = force is needed in ggplot2 3.3.4 and 3.3.5, see here;
|
||||
# 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)
|
||||
}
|
||||
|
@@ -237,7 +237,7 @@ resistance <- function(...,
|
||||
only_all_tested = only_all_tested,
|
||||
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_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_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(
|
||||
sir_calc(...,
|
||||
@@ -291,7 +291,7 @@ sir_confidence_interval <- function(...,
|
||||
only_all_tested = only_all_tested,
|
||||
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) {
|
||||
@@ -347,7 +347,7 @@ proportion_R <- function(...,
|
||||
only_all_tested = only_all_tested,
|
||||
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_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_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_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_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,
|
||||
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)
|
||||
)
|
||||
}
|
||||
|
345
R/sir.R
345
R/sir.R
@@ -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 threshold Maximum fraction of invalid antimicrobial interpretations of `x`, see *Examples*.
|
||||
#' @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
|
||||
#' *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(function(x) is.mic(x) | is.disk(x), as.sir)
|
||||
#' df_wide %>% mutate(across(where(is.mic), as.sir))
|
||||
#'
|
||||
#' df_wide %>% mutate_at(vars(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:
|
||||
#' df_long %>%
|
||||
#' # given a certain data type, e.g. MIC values
|
||||
@@ -380,26 +385,15 @@ as.sir <- function(x, ...) {
|
||||
UseMethod("as.sir")
|
||||
}
|
||||
|
||||
as_sir_structure <- function(x,
|
||||
guideline = NULL,
|
||||
mo = NULL,
|
||||
ab = NULL,
|
||||
method = NULL,
|
||||
ref_tbl = NULL,
|
||||
ref_breakpoints = NULL) {
|
||||
as_sir_structure <- function(x) {
|
||||
int <- attr(x, "interpretation_details")
|
||||
structure(
|
||||
factor(as.character(unlist(unname(x))),
|
||||
levels = c("S", "SDD", "I", "R", "NI"),
|
||||
ordered = TRUE
|
||||
),
|
||||
# TODO for #170
|
||||
# guideline = guideline,
|
||||
# mo = mo,
|
||||
# ab = ab,
|
||||
# method = method,
|
||||
# ref_tbl = ref_tbl,
|
||||
# ref_breakpoints = ref_breakpoints,
|
||||
class = c("sir", "ordered", "factor")
|
||||
interpretation_details = int,
|
||||
class = c(if (!is.null(int)) "interpreted_sir" else NULL, "sir", "ordered", "factor")
|
||||
)
|
||||
}
|
||||
|
||||
@@ -722,8 +716,17 @@ as.sir.data.frame <- function(x,
|
||||
meet_criteria(info, 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)
|
||||
|
||||
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))) {
|
||||
# don't keep factors, overwriting them is hard
|
||||
if (is.factor(x[, i, drop = TRUE])) {
|
||||
@@ -803,15 +806,6 @@ as.sir.data.frame <- function(x,
|
||||
}
|
||||
|
||||
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) {
|
||||
i <<- i + 1
|
||||
check <- is.mic(y) | is.disk(y)
|
||||
@@ -863,7 +857,7 @@ as.sir.data.frame <- function(x,
|
||||
cl <- tryCatch(parallel::makeCluster(n_cores, type = "PSOCK"),
|
||||
error = function(e) {
|
||||
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)
|
||||
}
|
||||
@@ -1135,7 +1129,6 @@ as_sir_method <- function(method_short,
|
||||
current_sir_interpretation_history <- NROW(AMR_env$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)
|
||||
}
|
||||
|
||||
@@ -1553,7 +1546,7 @@ as_sir_method <- function(method_short,
|
||||
))
|
||||
|
||||
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]
|
||||
}
|
||||
|
||||
@@ -1645,32 +1638,31 @@ as_sir_method <- function(method_short,
|
||||
breakpoint_S_R = vectorise_log_entry(NA_character_, length(rows)),
|
||||
stringsAsFactors = FALSE
|
||||
)
|
||||
attr(new_sir, "interpretation_details") <- out
|
||||
out <- subset(out, !is.na(input_given))
|
||||
AMR_env$sir_interpretation_history <- rbind_AMR(AMR_env$sir_interpretation_history, out)
|
||||
notes <- c(notes, notes_current)
|
||||
df[rows, "result"] <- new_sir
|
||||
next
|
||||
}
|
||||
|
||||
# sort on host and taxonomic rank
|
||||
# (this will e.g. prefer 'species' breakpoints over 'order' breakpoints)
|
||||
if (is.na(uti_current)) {
|
||||
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)
|
||||
# if the user explicitly set uti, keep only those rows
|
||||
if (!is.na(uti_current)) {
|
||||
breakpoints_current <- breakpoints_current[breakpoints_current$uti == uti_current, , drop = FALSE]
|
||||
}
|
||||
|
||||
# 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
|
||||
site <- breakpoints_current[1L, "site", drop = FALSE] # this is the one we'll take
|
||||
if (is.na(site)) {
|
||||
@@ -1682,7 +1674,7 @@ as_sir_method <- function(method_short,
|
||||
# only UTI breakpoints available
|
||||
notes_current <- paste0(
|
||||
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)) {
|
||||
# both UTI and Non-UTI breakpoints available
|
||||
@@ -1705,7 +1697,7 @@ as_sir_method <- function(method_short,
|
||||
new_sir <- rep(as.sir("R"), length(rows))
|
||||
notes_current <- paste0(
|
||||
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) {
|
||||
# no rules available
|
||||
@@ -1713,41 +1705,48 @@ as_sir_method <- function(method_short,
|
||||
} else {
|
||||
# then run the rules
|
||||
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, "\n",
|
||||
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",
|
||||
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",
|
||||
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",
|
||||
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",
|
||||
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",
|
||||
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",
|
||||
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 +1756,7 @@ as_sir_method <- function(method_short,
|
||||
notes_current <- paste0(
|
||||
notes_current, "\n",
|
||||
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 +1795,7 @@ as_sir_method <- function(method_short,
|
||||
}
|
||||
|
||||
# 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_
|
||||
out <- data.frame(
|
||||
# recycling 1 to 2 rows does not always seem to work, which is why vectorise_log_entry() was added
|
||||
@@ -1819,6 +1818,7 @@ as_sir_method <- function(method_short,
|
||||
breakpoint_S_R = vectorise_log_entry(paste0(breakpoints_current[, "breakpoint_S", drop = TRUE], "-", breakpoints_current[, "breakpoint_R", drop = TRUE]), length(rows)),
|
||||
stringsAsFactors = FALSE
|
||||
)
|
||||
attr(new_sir, "interpretation_details") <- out
|
||||
out <- subset(out, !is.na(input_given))
|
||||
AMR_env$sir_interpretation_history <- rbind_AMR(AMR_env$sir_interpretation_history, out)
|
||||
}
|
||||
@@ -1863,20 +1863,33 @@ as_sir_method <- function(method_short,
|
||||
new_part <- new_part[order(new_part$index), , drop = FALSE]
|
||||
AMR_env$sir_interpretation_history <- rbind_AMR(old_part, new_part)
|
||||
|
||||
df$result
|
||||
as_sir_structure(df$result)
|
||||
}
|
||||
|
||||
#' @rdname as.sir
|
||||
#' @param sir_values SIR values that were interpreted from MIC or disk diffusion values using [as.sir()].
|
||||
#' @param clean A [logical] to indicate whether previously stored results should be forgotten after returning the 'logbook' with results.
|
||||
#' @export
|
||||
sir_interpretation_history <- function(clean = FALSE) {
|
||||
sir_interpretation_history <- function(sir_values = NULL, clean = FALSE) {
|
||||
# for AMR v3.0.0 and lower, the first argument was `clean`, so allow `sir_interpretation_history(TRUE)` to keep working
|
||||
if (is.logical(sir_values) && missing(clean)) {
|
||||
clean <- sir_values
|
||||
sir_values <- NULL
|
||||
warning_("For `sir_interpretation_history()`, the `clean` argument is no longer the first argument, please update your code to explicitly state 'clean': `sir_interpretation_history(clean = ", clean, ")`.")
|
||||
}
|
||||
meet_criteria(sir_values, allow_class = "sir", allow_NULL = TRUE)
|
||||
meet_criteria(clean, allow_class = "logical", has_length = 1)
|
||||
out <- AMR_env$sir_interpretation_history
|
||||
out <- out[which(!is.na(out$datetime)), , drop = FALSE]
|
||||
out$outcome <- as.sir(out$outcome)
|
||||
out$site <- as.character(out$site)
|
||||
if (isTRUE(clean)) {
|
||||
AMR_env$sir_interpretation_history <- AMR_env$sir_interpretation_history[0, , drop = FALSE]
|
||||
|
||||
if (!is.null(sir_values)) {
|
||||
out <- attr(sir_values, "interpretation_details")
|
||||
} else {
|
||||
out <- AMR_env$sir_interpretation_history
|
||||
out <- out[which(!is.na(out$datetime)), , drop = FALSE]
|
||||
out$outcome <- as.sir(out$outcome)
|
||||
out$site <- as.character(out$site)
|
||||
if (isTRUE(clean)) {
|
||||
AMR_env$sir_interpretation_history <- AMR_env$sir_interpretation_history[0, , drop = FALSE]
|
||||
}
|
||||
}
|
||||
if (pkg_is_available("tibble")) {
|
||||
out <- import_fn("as_tibble", "tibble")(out)
|
||||
@@ -1904,11 +1917,11 @@ pillar_shaft.sir <- function(x, ...) {
|
||||
# colours will anyway not work when has_colour() == FALSE,
|
||||
# but then the indentation should also not be applied
|
||||
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 == "SDD"] <- font_green_lighter_bg(" SDD ")
|
||||
out[x == "I"] <- font_orange_bg(" I ")
|
||||
out[x == "SDD"] <- font_orange_bg(" SDD ")
|
||||
out[x == "R"] <- font_rose_bg(" R ")
|
||||
out[x == "NI"] <- font_grey_bg(font_black(" NI "))
|
||||
}
|
||||
create_pillar_column(out, align = "left", width = 5)
|
||||
}
|
||||
@@ -2000,21 +2013,60 @@ get_skimmers.sir <- function(column) {
|
||||
#' @export
|
||||
#' @noRd
|
||||
print.sir <- function(x, ...) {
|
||||
x_name <- deparse(substitute(x))
|
||||
cat("Class 'sir'\n")
|
||||
# TODO for #170
|
||||
# if (!is.null(attributes(x)$guideline) && !all(is.na(attributes(x)$guideline))) {
|
||||
# cat(font_blue(word_wrap("These values were interpreted using ",
|
||||
# font_bold(vector_and(attributes(x)$guideline, quotes = FALSE)),
|
||||
# " based on ",
|
||||
# vector_and(attributes(x)$method, quotes = FALSE),
|
||||
# " values. ",
|
||||
# "Use `sir_interpretation_history(", x_name, ")` to return a full logbook.")))
|
||||
# cat("\n")
|
||||
# }
|
||||
print(as.character(x), quote = FALSE)
|
||||
}
|
||||
|
||||
#' @method print interpreted_sir
|
||||
#' @export
|
||||
#' @noRd
|
||||
print.interpreted_sir <- function(x, ...) {
|
||||
cat("Class 'sir'\n")
|
||||
print(as.character(x), quote = FALSE)
|
||||
|
||||
if (length(x) == 0) {
|
||||
return(invisible())
|
||||
}
|
||||
|
||||
int <- attr(x, "interpretation_details")
|
||||
if (NROW(int) == 0) {
|
||||
if (length(x) == 1) {
|
||||
cat(font_blue(word_wrap("Source data were lost for this interpreted value.")))
|
||||
} else {
|
||||
cat(font_blue(word_wrap("Source data were lost for these interpreted values.")))
|
||||
}
|
||||
} else {
|
||||
relevant_cols <- int[, c("guideline", "method", "ab", "mo"), drop = FALSE]
|
||||
relevant_cols <- unique(relevant_cols)
|
||||
vals1_plural <- ifelse(length(x) == 1, "This value was", "These values were")
|
||||
vals2_plural <- ifelse(length(x) == 1, "value", "values")
|
||||
method_fn <- ifelse(relevant_cols$method == "MIC", "MIC", "disk diffusion")
|
||||
if (NROW(relevant_cols) == 1) {
|
||||
in_host <- ifelse(relevant_cols$host == "human", "", paste0(" in ", relevant_cols$host))
|
||||
cat(font_blue(word_wrap(
|
||||
vals1_plural, " interpreted using ",
|
||||
relevant_cols$guideline,
|
||||
" based on the ",
|
||||
method_fn,
|
||||
" ", vals2_plural, " for ",
|
||||
ab_name(relevant_cols$ab, language = NULL, info = FALSE, tolower = TRUE), " in ",
|
||||
italicise_taxonomy(mo_name(relevant_cols$mo, language = NULL, info = FALSE), type = "ansi"),
|
||||
in_host,
|
||||
"."
|
||||
)))
|
||||
} else {
|
||||
cat(font_blue(word_wrap(
|
||||
vals1_plural, " interpreted using ",
|
||||
vector_and(relevant_cols$guideline, quotes = FALSE),
|
||||
" based on ",
|
||||
vector_and(method_fn, quotes = FALSE),
|
||||
" ", vals2_plural, "."
|
||||
)))
|
||||
}
|
||||
cat(font_blue(word_wrap("\nUse `sir_interpretation_history()` on this object to return a full logbook.\n")))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#' @method as.double sir
|
||||
#' @export
|
||||
@@ -2070,51 +2122,132 @@ summary.sir <- function(object, ...) {
|
||||
value
|
||||
}
|
||||
|
||||
#' @method [ sir
|
||||
#' @export
|
||||
#' @noRd
|
||||
"[.sir" <- function(x, ...) {
|
||||
y <- NextMethod()
|
||||
det <- attr(x, "interpretation_details")
|
||||
if (!is.null(det)) {
|
||||
subset_idx <- seq_along(x)[...]
|
||||
# safer than relying on implicit eval inside NextMethod()
|
||||
attr(y, "interpretation_details") <- det[subset_idx, , drop = FALSE]
|
||||
}
|
||||
y
|
||||
}
|
||||
#' @method [[ sir
|
||||
#' @export
|
||||
#' @noRd
|
||||
"[[.sir" <- function(x, i, ...) {
|
||||
if (length(i) != 1L) {
|
||||
stop("attempt to select more than one element with [[.", call. = FALSE)
|
||||
}
|
||||
x[i] # calls `[.sir`, ensures attr alignment
|
||||
}
|
||||
|
||||
#' @method [<- sir
|
||||
#' @export
|
||||
#' @noRd
|
||||
"[<-.sir" <- function(i, j, ..., value) {
|
||||
value <- as.sir(value)
|
||||
y <- NextMethod()
|
||||
attributes(y) <- attributes(i)
|
||||
|
||||
old_det <- attr(i, "interpretation_details")
|
||||
new_det <- attr(value, "interpretation_details")
|
||||
|
||||
len_y <- length(y)
|
||||
|
||||
# Neither i nor value have details -> do nothing
|
||||
if (is.null(old_det) && is.null(new_det)) {
|
||||
return(y)
|
||||
}
|
||||
|
||||
# Start building full_det as copy of old_det or empty
|
||||
full_det <- if (!is.null(old_det)) old_det else data.frame(row = seq_along(i))
|
||||
|
||||
# Ensure full_det has correct row count and order
|
||||
if (nrow(full_det) != length(i)) {
|
||||
attr(y, "interpretation_details") <- NULL
|
||||
return(y)
|
||||
}
|
||||
|
||||
# Which rows are being assigned?
|
||||
assign_idx <- if (missing(j)) seq_along(i) else j
|
||||
assign_idx <- as.integer(assign_idx)
|
||||
|
||||
# If new_det is missing or too short, fill it
|
||||
if (is.null(new_det)) {
|
||||
new_det <- data.frame(row = assign_idx)
|
||||
} else if (nrow(new_det) != length(value)) {
|
||||
new_det <- data.frame(row = assign_idx)
|
||||
}
|
||||
|
||||
# Add temporary .row to track positions
|
||||
full_det$.row <- seq_len(nrow(full_det))
|
||||
new_det$.row <- assign_idx
|
||||
|
||||
# Replace old rows with new rows
|
||||
full_det <- rbind(
|
||||
subset(full_det, !.row %in% assign_idx),
|
||||
new_det
|
||||
)
|
||||
full_det <- full_det[order(full_det$.row), , drop = FALSE]
|
||||
full_det$.row <- NULL
|
||||
|
||||
# Clean up: ensure right number of rows
|
||||
if (nrow(full_det) == len_y) {
|
||||
attr(y, "interpretation_details") <- full_det
|
||||
} else {
|
||||
attr(y, "interpretation_details") <- NULL
|
||||
}
|
||||
|
||||
y
|
||||
}
|
||||
#' @method [[<- sir
|
||||
#' @export
|
||||
#' @noRd
|
||||
"[[<-.sir" <- function(i, j, ..., value) {
|
||||
value <- as.sir(value)
|
||||
y <- NextMethod()
|
||||
attributes(y) <- attributes(i)
|
||||
y
|
||||
if (!is.null(det) && length(i) == 1 && nrow(det) >= i) {
|
||||
i[j] <- value
|
||||
i
|
||||
} else {
|
||||
NextMethod()
|
||||
}
|
||||
}
|
||||
#' @method c sir
|
||||
#' @export
|
||||
#' @noRd
|
||||
c.sir <- function(...) {
|
||||
lst <- list(...)
|
||||
c.sir <- function(..., recursive = FALSE) {
|
||||
lst <- lapply(
|
||||
list(...),
|
||||
function(x) {
|
||||
list(
|
||||
values = as.character(x),
|
||||
interpretation_details = attr(x, "interpretation_details")
|
||||
)
|
||||
}
|
||||
)
|
||||
x <- unlist(lapply(lst, `[[`, "values"), use.names = FALSE)
|
||||
details <- lapply(lst, `[[`, "interpretation_details")
|
||||
has_details <- vapply(details, is.data.frame, logical(1))
|
||||
if (!any(has_details)) {
|
||||
return(as_sir_structure(x))
|
||||
}
|
||||
|
||||
# TODO for #170
|
||||
# guideline <- vapply(FUN.VALUE = character(1), lst, function(x) attributes(x)$guideline %or% NA_character_)
|
||||
# mo <- vapply(FUN.VALUE = character(1), lst, function(x) attributes(x)$mo %or% NA_character_)
|
||||
# ab <- vapply(FUN.VALUE = character(1), lst, function(x) attributes(x)$ab %or% NA_character_)
|
||||
# method <- vapply(FUN.VALUE = character(1), lst, function(x) attributes(x)$method %or% NA_character_)
|
||||
# ref_tbl <- vapply(FUN.VALUE = character(1), lst, function(x) attributes(x)$ref_tbl %or% NA_character_)
|
||||
# ref_breakpoints <- vapply(FUN.VALUE = character(1), lst, function(x) attributes(x)$ref_breakpoints %or% NA_character_)
|
||||
# Pre-allocate details (no Map, no matrix allocation)
|
||||
combined_details <- do.call(rbind, lapply(seq_along(details), function(i) {
|
||||
d <- details[[i]]
|
||||
if (is.null(d)) {
|
||||
# generate NA rows of correct length, but fast
|
||||
n <- length(details[[i]])
|
||||
as.data.frame(matrix(NA, nrow = n, ncol = 0))
|
||||
} else {
|
||||
d
|
||||
}
|
||||
}))
|
||||
|
||||
out <- as.sir(unlist(lapply(list(...), as.character)))
|
||||
|
||||
# TODO for #170
|
||||
# if (!all(is.na(guideline))) {
|
||||
# attributes(out)$guideline <- guideline
|
||||
# attributes(out)$mo <- mo
|
||||
# attributes(out)$ab <- ab
|
||||
# attributes(out)$method <- method
|
||||
# attributes(out)$ref_tbl <- ref_tbl
|
||||
# attributes(out)$ref_breakpoints <- ref_breakpoints
|
||||
# }
|
||||
|
||||
out
|
||||
attr(x, "interpretation_details") <- combined_details
|
||||
as_sir_structure(x)
|
||||
}
|
||||
|
||||
#' @method unique sir
|
||||
|
14
R/sir_calc.R
14
R/sir_calc.R
@@ -244,7 +244,7 @@ sir_calc_df <- function(type, # "proportion", "count" or "both"
|
||||
translate_ab <- get_translate_ab(translate_ab)
|
||||
|
||||
data.bak <- data
|
||||
# select only groups and antimicrobials
|
||||
# select only groups and antibiotics
|
||||
if (is_null_or_grouped_tbl(data)) {
|
||||
data_has_groups <- TRUE
|
||||
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)
|
||||
if (isTRUE(combine_SI)) {
|
||||
for (i in seq_len(ncol(data))) {
|
||||
if (is.sir(data[, i, drop = TRUE])) {
|
||||
data[, i] <- as.character(data[, i, drop = TRUE])
|
||||
|
||||
for (i in seq_len(ncol(data))) {
|
||||
# transform SIR columns
|
||||
if (is.sir(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)) {
|
||||
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 {
|
||||
# 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
|
||||
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)
|
||||
} else {
|
||||
out$interpretation <- factor(out$interpretation, levels = c("S", "I", "R"), ordered = TRUE)
|
||||
|
@@ -47,6 +47,6 @@ sir_df <- function(data,
|
||||
combine_SI = combine_SI,
|
||||
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)
|
||||
)
|
||||
}
|
||||
|
BIN
R/sysdata.rda
BIN
R/sysdata.rda
Binary file not shown.
@@ -19,56 +19,59 @@
|
||||
#' @keywords internal
|
||||
#' @export
|
||||
#' @examples
|
||||
#' library(tidymodels)
|
||||
#' 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.
|
||||
#' # 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
|
||||
#' # 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))
|
||||
#' # 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)
|
||||
#' # 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()) %>%
|
||||
#' prep()
|
||||
#' # Create and prep a recipe with MIC log2 transformation
|
||||
#' mic_recipe <- recipe(esbl ~ ., data = training_data) %>%
|
||||
#'
|
||||
#' # View prepped recipe
|
||||
#' mic_recipe
|
||||
#' # Optionally remove non-predictive variables
|
||||
#' remove_role(genus, old_role = "predictor") %>%
|
||||
#'
|
||||
#' # 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)
|
||||
#' # Apply the log2 transformation to all MIC predictors
|
||||
#' step_mic_log2(all_mic_predictors()) %>%
|
||||
#'
|
||||
#' # Fit a logistic regression model
|
||||
#' fitted <- logistic_reg(mode = "classification") %>%
|
||||
#' set_engine("glm") %>%
|
||||
#' fit(esbl ~ ., data = out_training)
|
||||
#' # And apply the preparation steps
|
||||
#' prep()
|
||||
#'
|
||||
#' # Generate predictions on the test set
|
||||
#' predictions <- predict(fitted, out_testing) %>%
|
||||
#' bind_cols(out_testing)
|
||||
#' # View prepped recipe
|
||||
#' mic_recipe
|
||||
#'
|
||||
#' # Evaluate predictions using standard classification metrics
|
||||
#' our_metrics <- metric_set(accuracy, kap, ppv, npv)
|
||||
#' metrics <- our_metrics(predictions, truth = esbl, estimate = .pred_class)
|
||||
#' # 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)
|
||||
#'
|
||||
#' # Show performance:
|
||||
#' # - negative predictive value (NPV) of ~98%
|
||||
#' # - positive predictive value (PPV) of ~94%
|
||||
#' metrics
|
||||
#' # 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)
|
||||
|
@@ -30,7 +30,6 @@
|
||||
# These are all S3 implementations for the vctrs package,
|
||||
# that is used internally by tidyverse packages such as dplyr.
|
||||
# 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
|
||||
|
||||
|
4
R/zzz.R
4
R/zzz.R
@@ -127,7 +127,7 @@ AMR_env$cross_icon <- if (isTRUE(base::l10n_info()$`UTF-8`)) "\u00d7" else "x"
|
||||
suppressWarnings(suppressMessages(add_custom_antimicrobials(x)))
|
||||
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)))
|
||||
packageStartupMessage("OK.")
|
||||
},
|
||||
error = function(e) packageStartupMessage("Failed: ", e$message)
|
||||
error = function(e) packageStartupMessage("Failed: ", conditionMessage(e))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@@ -56,7 +56,8 @@ os.makedirs(r_lib_path, exist_ok=True)
|
||||
os.environ['R_LIBS_SITE'] = r_lib_path
|
||||
|
||||
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
|
||||
|
||||
# Import base and utils
|
||||
@@ -94,27 +95,26 @@ if r_amr_version != python_amr_version:
|
||||
print(f"AMR: Setting up R environment and AMR datasets...", flush=True)
|
||||
|
||||
# Activate the automatic conversion between R and pandas DataFrames
|
||||
pandas2ri.activate()
|
||||
with localconverter(default_converter + numpy2ri.converter + pandas2ri.converter):
|
||||
# example_isolates
|
||||
example_isolates = robjects.r('''
|
||||
df <- AMR::example_isolates
|
||||
df[] <- lapply(df, function(x) {
|
||||
if (inherits(x, c("Date", "POSIXt", "factor"))) {
|
||||
as.character(x)
|
||||
} else {
|
||||
x
|
||||
}
|
||||
})
|
||||
df <- df[, !sapply(df, is.list)]
|
||||
df
|
||||
''')
|
||||
example_isolates['date'] = pd.to_datetime(example_isolates['date'])
|
||||
|
||||
# example_isolates
|
||||
example_isolates = pandas2ri.rpy2py(robjects.r('''
|
||||
df <- AMR::example_isolates
|
||||
df[] <- lapply(df, function(x) {
|
||||
if (inherits(x, c("Date", "POSIXt", "factor"))) {
|
||||
as.character(x)
|
||||
} else {
|
||||
x
|
||||
}
|
||||
})
|
||||
df <- df[, !sapply(df, is.list)]
|
||||
df
|
||||
'''))
|
||||
example_isolates['date'] = pd.to_datetime(example_isolates['date'])
|
||||
|
||||
# microorganisms
|
||||
microorganisms = pandas2ri.rpy2py(robjects.r('AMR::microorganisms[, !sapply(AMR::microorganisms, is.list)]'))
|
||||
antimicrobials = pandas2ri.rpy2py(robjects.r('AMR::antimicrobials[, !sapply(AMR::antimicrobials, is.list)]'))
|
||||
clinical_breakpoints = pandas2ri.rpy2py(robjects.r('AMR::clinical_breakpoints[, !sapply(AMR::clinical_breakpoints, is.list)]'))
|
||||
# microorganisms
|
||||
microorganisms = robjects.r('AMR::microorganisms[, !sapply(AMR::microorganisms, is.list)]')
|
||||
antimicrobials = robjects.r('AMR::antimicrobials[, !sapply(AMR::antimicrobials, is.list)]')
|
||||
clinical_breakpoints = robjects.r('AMR::clinical_breakpoints[, !sapply(AMR::clinical_breakpoints, is.list)]')
|
||||
|
||||
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
|
||||
cat <<EOL > "$functions_file"
|
||||
import functools
|
||||
import rpy2.robjects as robjects
|
||||
from rpy2.robjects.packages import importr
|
||||
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 numpy as np
|
||||
|
||||
# Activate automatic conversion between R data frames and pandas data frames
|
||||
pandas2ri.activate()
|
||||
|
||||
# Import the AMR R package
|
||||
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
|
||||
|
||||
# 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)
|
||||
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
|
||||
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
|
||||
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
|
||||
|
||||
# Directory where the .Rd files are stored (update path as needed)
|
||||
@@ -246,11 +252,12 @@ for rd_file in "$rd_dir"/*.Rd; do
|
||||
gsub("FALSE", "False", func_args)
|
||||
gsub("NULL", "None", func_args)
|
||||
|
||||
# Write the Python function definition to the output 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 " return convert_to_python(amr_r." func_name_py "(" func_args "))" >> "'"$functions_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 " \"\"\"Please see our website of the R package for the full manual: https://amr-for-r.org\"\"\"" >> "'"$functions_file"'"
|
||||
print " return amr_r." func_name_py "(" func_args ")" >> "'"$functions_file"'"
|
||||
|
||||
print "from .functions import " func_name_py >> "'"$init_file"'"
|
||||
}
|
||||
' "$rd_file"
|
||||
|
@@ -288,7 +288,7 @@ for (page in LETTERS) {
|
||||
url <- paste0("https://lpsn.dsmz.de/genus?page=", page)
|
||||
x <- tryCatch(read_html(url),
|
||||
error = function(e) {
|
||||
message("Waiting 10 seconds because of error: ", e$message)
|
||||
message("Waiting 10 seconds because of error: ", conditionMessage(e))
|
||||
Sys.sleep(10)
|
||||
read_html(url)
|
||||
})
|
||||
|
@@ -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
|
||||
# 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)
|
||||
# }
|
||||
# }
|
||||
|
@@ -283,7 +283,7 @@ for (i in 2:length(sheets_to_analyse)) {
|
||||
guideline_name = guideline_name
|
||||
)
|
||||
),
|
||||
error = function(e) message(e$message)
|
||||
error = function(e) message(conditionMessage(e))
|
||||
)
|
||||
}
|
||||
|
||||
|
Binary file not shown.
@@ -133,7 +133,7 @@ ggplot(data.frame(mic = some_mic_values,
|
||||
sir = interpretation),
|
||||
aes(x = group, y = mic, colour = sir)) +
|
||||
theme_minimal() +
|
||||
geom_boxplot(fill = NA, colour = "grey") +
|
||||
geom_boxplot(fill = NA, colour = "grey30") +
|
||||
geom_jitter(width = 0.25) +
|
||||
|
||||
# NEW scale function: plot MIC values to x, y, colour or fill
|
||||
|
62
index.md
62
index.md
@@ -27,12 +27,12 @@
|
||||
|
||||
<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 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>
|
||||
|
||||
</div>
|
||||
@@ -171,14 +171,14 @@ example_isolates %>%
|
||||
select(bacteria,
|
||||
aminoglycosides(),
|
||||
carbapenems())
|
||||
#> ℹ Using column 'mo' as input for mo_fullname()
|
||||
#> ℹ Using column 'mo' as input for mo_is_gram_negative()
|
||||
#> ℹ Using column 'mo' as input for mo_is_intrinsic_resistant()
|
||||
#> ℹ Using column 'mo' as input for `mo_fullname()`
|
||||
#> ℹ Using column 'mo' as input for `mo_is_gram_negative()`
|
||||
#> ℹ Using column 'mo' as input for `mo_is_intrinsic_resistant()`
|
||||
#> ℹ Determining intrinsic resistance based on 'EUCAST Expected Resistant
|
||||
#> Phenotypes' v1.2 (2023). This note will be shown once per session.
|
||||
#> ℹ For aminoglycosides() using columns 'GEN' (gentamicin), 'TOB'
|
||||
#> ℹ For `aminoglycosides()` using columns 'GEN' (gentamicin), 'TOB'
|
||||
#> (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
|
||||
#> bacteria GEN TOB AMK KAN IPM MEM
|
||||
#> <chr> <sir> <sir> <sir> <sir> <sir> <sir>
|
||||
@@ -215,9 +215,9 @@ output format automatically (such as markdown, LaTeX, HTML, etc.).
|
||||
``` r
|
||||
antibiogram(example_isolates,
|
||||
antimicrobials = c(aminoglycosides(), carbapenems()))
|
||||
#> ℹ For aminoglycosides() using columns 'GEN' (gentamicin), 'TOB'
|
||||
#> ℹ For `aminoglycosides()` using columns 'GEN' (gentamicin), 'TOB'
|
||||
#> (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 |
|
||||
@@ -289,7 +289,7 @@ ggplot(data.frame(mic = some_mic_values,
|
||||
sir = interpretation),
|
||||
aes(x = group, y = mic, colour = sir)) +
|
||||
theme_minimal() +
|
||||
geom_boxplot(fill = NA, colour = "grey") +
|
||||
geom_boxplot(fill = NA, colour = "grey30") +
|
||||
geom_jitter(width = 0.25) +
|
||||
|
||||
# NEW scale function: plot MIC values to x, y, colour or fill
|
||||
@@ -321,9 +321,9 @@ example_isolates %>%
|
||||
#> # A tibble: 3 × 5
|
||||
#> ward GEN_total_R GEN_conf_int TOB_total_R TOB_conf_int
|
||||
#> <chr> <dbl> <chr> <dbl> <chr>
|
||||
#> 1 Clinical 0.2289362 0.205-0.254 0.3147503 0.284-0.347
|
||||
#> 2 ICU 0.2902655 0.253-0.33 0.4004739 0.353-0.449
|
||||
#> 3 Outpatient 0.2 0.131-0.285 0.3676471 0.254-0.493
|
||||
#> 1 Clinical 0.229 0.205-0.254 0.315 0.284-0.347
|
||||
#> 2 ICU 0.290 0.253-0.33 0.400 0.353-0.449
|
||||
#> 3 Outpatient 0.2 0.131-0.285 0.368 0.254-0.493
|
||||
```
|
||||
|
||||
Or use [antimicrobial
|
||||
@@ -340,44 +340,44 @@ out <- example_isolates %>%
|
||||
# calculate AMR using resistance(), over all aminoglycosides and polymyxins:
|
||||
summarise(across(c(aminoglycosides(), polymyxins()),
|
||||
resistance))
|
||||
#> ℹ For aminoglycosides() using columns 'GEN' (gentamicin), 'TOB'
|
||||
#> ℹ For `aminoglycosides()` using columns 'GEN' (gentamicin), 'TOB'
|
||||
#> (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()`.
|
||||
#> ℹ In argument: `across(c(aminoglycosides(), polymyxins()), resistance)`.
|
||||
#> ℹ In group 3: `ward = "Outpatient"`.
|
||||
#> Caused by warning:
|
||||
#> ! Introducing NA: only 23 results available for KAN in group: ward =
|
||||
#> "Outpatient" (minimum = 30).
|
||||
#> "Outpatient" (`minimum` = 30).
|
||||
out
|
||||
#> # A tibble: 3 × 6
|
||||
#> ward GEN TOB AMK KAN COL
|
||||
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
|
||||
#> 1 Clinical 0.2289362 0.3147503 0.6258993 1 0.7802956
|
||||
#> 2 ICU 0.2902655 0.4004739 0.6624473 1 0.8574144
|
||||
#> 3 Outpatient 0.2 0.3676471 0.6052632 NA 0.8888889
|
||||
#> ward GEN TOB AMK KAN COL
|
||||
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
|
||||
#> 1 Clinical 0.229 0.315 0.626 1 0.780
|
||||
#> 2 ICU 0.290 0.400 0.662 1 0.857
|
||||
#> 3 Outpatient 0.2 0.368 0.605 NA 0.889
|
||||
```
|
||||
|
||||
``` r
|
||||
# transform the antibiotic columns to names:
|
||||
out %>% set_ab_names()
|
||||
#> # A tibble: 3 × 6
|
||||
#> ward gentamicin tobramycin amikacin kanamycin colistin
|
||||
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
|
||||
#> 1 Clinical 0.2289362 0.3147503 0.6258993 1 0.7802956
|
||||
#> 2 ICU 0.2902655 0.4004739 0.6624473 1 0.8574144
|
||||
#> 3 Outpatient 0.2 0.3676471 0.6052632 NA 0.8888889
|
||||
#> ward gentamicin tobramycin amikacin kanamycin colistin
|
||||
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
|
||||
#> 1 Clinical 0.229 0.315 0.626 1 0.780
|
||||
#> 2 ICU 0.290 0.400 0.662 1 0.857
|
||||
#> 3 Outpatient 0.2 0.368 0.605 NA 0.889
|
||||
```
|
||||
|
||||
``` r
|
||||
# transform the antibiotic column to ATC codes:
|
||||
out %>% set_ab_names(property = "atc")
|
||||
#> # A tibble: 3 × 6
|
||||
#> ward J01GB03 J01GB01 J01GB06 J01GB04 J01XB01
|
||||
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
|
||||
#> 1 Clinical 0.2289362 0.3147503 0.6258993 1 0.7802956
|
||||
#> 2 ICU 0.2902655 0.4004739 0.6624473 1 0.8574144
|
||||
#> 3 Outpatient 0.2 0.3676471 0.6052632 NA 0.8888889
|
||||
#> ward J01GB03 J01GB01 J01GB06 J01GB04 J01XB01
|
||||
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
|
||||
#> 1 Clinical 0.229 0.315 0.626 1 0.780
|
||||
#> 2 ICU 0.290 0.400 0.662 1 0.857
|
||||
#> 3 Outpatient 0.2 0.368 0.605 NA 0.889
|
||||
```
|
||||
|
||||
## What else can you do with this package?
|
||||
|
@@ -4,20 +4,23 @@
|
||||
\alias{age_groups}
|
||||
\title{Split Ages into Age Groups}
|
||||
\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{
|
||||
\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{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.}
|
||||
}
|
||||
\value{
|
||||
Ordered \link{factor}
|
||||
}
|
||||
\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{
|
||||
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+
|
||||
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
|
||||
age_groups(ages, 1:10 * 10)
|
||||
|
@@ -65,56 +65,59 @@ Pre-processing pipeline steps include:
|
||||
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{
|
||||
library(tidymodels)
|
||||
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.
|
||||
# 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
|
||||
# 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))
|
||||
# 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)
|
||||
# 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()) \%>\%
|
||||
prep()
|
||||
# Create and prep a recipe with MIC log2 transformation
|
||||
mic_recipe <- recipe(esbl ~ ., data = training_data) \%>\%
|
||||
|
||||
# View prepped recipe
|
||||
mic_recipe
|
||||
# Optionally remove non-predictive variables
|
||||
remove_role(genus, old_role = "predictor") \%>\%
|
||||
|
||||
# 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)
|
||||
# Apply the log2 transformation to all MIC predictors
|
||||
step_mic_log2(all_mic_predictors()) \%>\%
|
||||
|
||||
# Fit a logistic regression model
|
||||
fitted <- logistic_reg(mode = "classification") \%>\%
|
||||
set_engine("glm") \%>\%
|
||||
fit(esbl ~ ., data = out_training)
|
||||
# And apply the preparation steps
|
||||
prep()
|
||||
|
||||
# Generate predictions on the test set
|
||||
predictions <- predict(fitted, out_testing) \%>\%
|
||||
bind_cols(out_testing)
|
||||
# View prepped recipe
|
||||
mic_recipe
|
||||
|
||||
# Evaluate predictions using standard classification metrics
|
||||
our_metrics <- metric_set(accuracy, kap, ppv, npv)
|
||||
metrics <- our_metrics(predictions, truth = esbl, estimate = .pred_class)
|
||||
# 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)
|
||||
|
||||
# Show performance:
|
||||
# - negative predictive value (NPV) of ~98\%
|
||||
# - positive predictive value (PPV) of ~94\%
|
||||
metrics
|
||||
# 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()}}
|
||||
|
@@ -70,12 +70,14 @@ is_sir_eligible(x, threshold = 0.05)
|
||||
language = get_AMR_locale(), verbose = FALSE, info = interactive(),
|
||||
parallel = FALSE, max_cores = -1, conserve_capped_values = NULL)
|
||||
|
||||
sir_interpretation_history(clean = FALSE)
|
||||
sir_interpretation_history(sir_values = NULL, clean = FALSE)
|
||||
}
|
||||
\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{...}{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}.}
|
||||
|
||||
@@ -145,6 +147,8 @@ The default \code{"standard"} setting ensures cautious handling of uncertain val
|
||||
|
||||
\item{max_cores}{Maximum number of cores to use if \code{parallel = TRUE}. Use a negative value to subtract that number from the available number of cores, e.g. a value of \code{-2} on an 8-core machine means that at most 6 cores will be used. Defaults to \code{-1}. There will never be used more cores than variables to analyse. The available number of cores are detected using \code{\link[parallelly:availableCores]{parallelly::availableCores()}} if that package is installed, and base \R's \code{\link[parallel:detectCores]{parallel::detectCores()}} otherwise.}
|
||||
|
||||
\item{sir_values}{SIR values that were interpreted from MIC or disk diffusion values using \code{\link[=as.sir]{as.sir()}}.}
|
||||
|
||||
\item{clean}{A \link{logical} to indicate whether previously stored results should be forgotten after returning the 'logbook' with results.}
|
||||
}
|
||||
\value{
|
||||
@@ -314,9 +318,12 @@ if (require("dplyr")) {
|
||||
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(across(where(is.mic), as.sir))
|
||||
|
||||
df_wide \%>\% mutate_at(vars(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:
|
||||
df_long \%>\%
|
||||
# given a certain data type, e.g. MIC values
|
||||
|
@@ -9,10 +9,10 @@ ggplot_sir(data, position = NULL, x = "antibiotic",
|
||||
fill = "interpretation", facet = NULL, breaks = seq(0, 1, 0.1),
|
||||
limits = NULL, translate_ab = "name", combine_SI = TRUE,
|
||||
minimum = 30, language = get_AMR_locale(), nrow = NULL, colours = c(S
|
||||
= "#3CAEA3", SI = "#3CAEA3", I = "#F6D55C", IR = "#ED553B", R = "#ED553B"),
|
||||
datalabels = TRUE, datalabels.size = 2.5, datalabels.colour = "grey15",
|
||||
title = NULL, subtitle = NULL, caption = NULL,
|
||||
x.title = "Antimicrobial", y.title = "Proportion", ...)
|
||||
= "#3CAEA3", SDD = "#8FD6C4", SI = "#3CAEA3", I = "#F6D55C", IR = "#ED553B",
|
||||
R = "#ED553B"), datalabels = TRUE, datalabels.size = 2.5,
|
||||
datalabels.colour = "grey15", title = NULL, subtitle = NULL,
|
||||
caption = NULL, x.title = "Antimicrobial", y.title = "Proportion", ...)
|
||||
|
||||
geom_sir(position = NULL, x = c("antibiotic", "interpretation"),
|
||||
fill = "interpretation", translate_ab = "name", minimum = 30,
|
||||
|
@@ -18,7 +18,7 @@ amr_distance_from_row(amr_distance, row)
|
||||
\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{...}{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}.}
|
||||
|
||||
|
52
man/plot.Rd
52
man/plot.Rd
@@ -33,25 +33,25 @@ scale_colour_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"),
|
||||
language = get_AMR_locale(), eucast_I = getOption("AMR_guideline",
|
||||
"EUCAST") == "EUCAST", ...)
|
||||
scale_x_sir(colours_SIR = c(S = "#3CAEA3", SDD = "#8FD6C4", I = "#F6D55C", R
|
||||
= "#ED553B"), language = get_AMR_locale(),
|
||||
eucast_I = getOption("AMR_guideline", "EUCAST") == "EUCAST", ...)
|
||||
|
||||
scale_colour_sir(colours_SIR = c("#3CAEA3", "#F6D55C", "#ED553B"),
|
||||
language = get_AMR_locale(), eucast_I = getOption("AMR_guideline",
|
||||
"EUCAST") == "EUCAST", ...)
|
||||
scale_colour_sir(colours_SIR = c(S = "#3CAEA3", SDD = "#8FD6C4", I =
|
||||
"#F6D55C", R = "#ED553B"), language = get_AMR_locale(),
|
||||
eucast_I = getOption("AMR_guideline", "EUCAST") == "EUCAST", ...)
|
||||
|
||||
scale_fill_sir(colours_SIR = c("#3CAEA3", "#F6D55C", "#ED553B"),
|
||||
language = get_AMR_locale(), eucast_I = getOption("AMR_guideline",
|
||||
"EUCAST") == "EUCAST", ...)
|
||||
scale_fill_sir(colours_SIR = c(S = "#3CAEA3", SDD = "#8FD6C4", I = "#F6D55C",
|
||||
R = "#ED553B"), language = get_AMR_locale(),
|
||||
eucast_I = getOption("AMR_guideline", "EUCAST") == "EUCAST", ...)
|
||||
|
||||
\method{plot}{mic}(x, mo = NULL, ab = NULL,
|
||||
guideline = getOption("AMR_guideline", "EUCAST"),
|
||||
main = deparse(substitute(x)), ylab = translate_AMR("Frequency", language
|
||||
= language),
|
||||
xlab = translate_AMR("Minimum Inhibitory Concentration (mg/L)", language =
|
||||
language), colours_SIR = c("#3CAEA3", "#F6D55C", "#ED553B"),
|
||||
language = get_AMR_locale(), expand = TRUE,
|
||||
language), colours_SIR = c(S = "#3CAEA3", SDD = "#8FD6C4", I = "#F6D55C", R
|
||||
= "#ED553B"), language = get_AMR_locale(), expand = TRUE,
|
||||
include_PKPD = getOption("AMR_include_PKPD", TRUE),
|
||||
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",
|
||||
language = language),
|
||||
xlab = translate_AMR("Minimum Inhibitory Concentration (mg/L)", language =
|
||||
language), colours_SIR = c("#3CAEA3", "#F6D55C", "#ED553B"),
|
||||
language = get_AMR_locale(), expand = TRUE,
|
||||
language), colours_SIR = c(S = "#3CAEA3", SDD = "#8FD6C4", I = "#F6D55C", R
|
||||
= "#ED553B"), language = get_AMR_locale(), expand = TRUE,
|
||||
include_PKPD = getOption("AMR_include_PKPD", TRUE),
|
||||
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),
|
||||
xlab = translate_AMR("Disk diffusion diameter (mm)", language = language),
|
||||
mo = NULL, ab = NULL, guideline = getOption("AMR_guideline", "EUCAST"),
|
||||
colours_SIR = c("#3CAEA3", "#F6D55C", "#ED553B"),
|
||||
language = get_AMR_locale(), expand = TRUE,
|
||||
colours_SIR = c(S = "#3CAEA3", SDD = "#8FD6C4", I = "#F6D55C", R =
|
||||
"#ED553B"), language = get_AMR_locale(), expand = TRUE,
|
||||
include_PKPD = getOption("AMR_include_PKPD", TRUE),
|
||||
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",
|
||||
language = language), xlab = translate_AMR("Disk diffusion diameter (mm)",
|
||||
language = language), guideline = getOption("AMR_guideline", "EUCAST"),
|
||||
colours_SIR = c("#3CAEA3", "#F6D55C", "#ED553B"),
|
||||
language = get_AMR_locale(), expand = TRUE,
|
||||
colours_SIR = c(S = "#3CAEA3", SDD = "#8FD6C4", I = "#F6D55C", R =
|
||||
"#ED553B"), language = get_AMR_locale(), expand = TRUE,
|
||||
include_PKPD = getOption("AMR_include_PKPD", TRUE),
|
||||
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)),
|
||||
xlab = translate_AMR("Antimicrobial Interpretation", language = language),
|
||||
ylab = translate_AMR("Frequency", language = language),
|
||||
colours_SIR = c("#3CAEA3", "#F6D55C", "#ED553B"),
|
||||
ylab = translate_AMR("Frequency", language = language), colours_SIR = c(S
|
||||
= "#3CAEA3", SDD = "#8FD6C4", I = "#F6D55C", R = "#ED553B"),
|
||||
language = get_AMR_locale(), ...)
|
||||
|
||||
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),
|
||||
limits = c(0, NA))
|
||||
|
||||
scale_sir_colours(..., aesthetics, colours_SIR = c("#3CAEA3", "#F6D55C",
|
||||
"#ED553B"))
|
||||
scale_sir_colours(..., aesthetics, colours_SIR = c(S = "#3CAEA3", SDD =
|
||||
"#8FD6C4", I = "#F6D55C", R = "#ED553B"))
|
||||
|
||||
theme_sir()
|
||||
|
||||
@@ -210,6 +210,10 @@ if (require("ggplot2")) {
|
||||
# when providing the microorganism and antibiotic, colours will show interpretations:
|
||||
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")) {
|
||||
# support for 27 languages, various guidelines, and many options
|
||||
autoplot(some_disk_values,
|
||||
@@ -267,7 +271,7 @@ if (require("ggplot2")) {
|
||||
aes(group, mic)
|
||||
) +
|
||||
geom_boxplot() +
|
||||
geom_violin(linetype = 2, colour = "grey", fill = NA) +
|
||||
geom_violin(linetype = 2, colour = "grey30", fill = NA) +
|
||||
scale_y_mic()
|
||||
}
|
||||
if (require("ggplot2")) {
|
||||
@@ -279,7 +283,7 @@ if (require("ggplot2")) {
|
||||
aes(group, mic)
|
||||
) +
|
||||
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))
|
||||
}
|
||||
|
||||
@@ -312,7 +316,7 @@ if (require("ggplot2")) {
|
||||
aes(x = group, y = mic, colour = sir)
|
||||
) +
|
||||
theme_minimal() +
|
||||
geom_boxplot(fill = NA, colour = "grey") +
|
||||
geom_boxplot(fill = NA, colour = "grey30") +
|
||||
geom_jitter(width = 0.25)
|
||||
|
||||
plain
|
||||
|
@@ -190,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' */
|
||||
.developers h2 {
|
||||
display: none;
|
||||
|
@@ -63,10 +63,12 @@ test_that("test-zzz.R", {
|
||||
"progress_bar" = "progress",
|
||||
"read_html" = "xml2",
|
||||
"right_join" = "dplyr",
|
||||
"select" = "dplyr",
|
||||
"semi_join" = "dplyr",
|
||||
"showQuestion" = "rstudioapi",
|
||||
"symbol" = "cli",
|
||||
"tibble" = "tibble",
|
||||
"where" = "tidyselect",
|
||||
"write.xlsx" = "openxlsx"
|
||||
)
|
||||
|
||||
|
Reference in New Issue
Block a user