mirror of
https://github.com/msberends/AMR.git
synced 2026-03-30 23:35:56 +02:00
Compare commits
21 Commits
claude/rev
...
9f73571832
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9f73571832 | ||
| d28671c34d | |||
|
|
51f689b069 | ||
|
|
1dabd4df3d | ||
|
|
5173009625 | ||
|
|
80e267f0d1 | ||
|
|
05d3ca941f | ||
|
|
ec310ed76b | ||
|
|
3e4983ff93 | ||
|
|
7218812c99 | ||
|
|
eae14d44bf | ||
|
|
11c175ae19 | ||
|
|
ec3b12b937 | ||
|
|
5ecbc9001e | ||
|
|
8760c6d85a | ||
|
|
3928a3de55 | ||
|
|
10c00ff606 | ||
|
|
b7edf3e548 | ||
|
|
0cc154257a | ||
|
|
4798d2c55e | ||
|
|
ad31fba556 |
11
CLAUDE.md
11
CLAUDE.md
@@ -152,16 +152,7 @@ All PRs are **squash-merged**, so each PR lands as exactly **one commit** on the
|
||||
|
||||
#### Computing the correct version number
|
||||
|
||||
**First, ensure `git` and `gh` are installed** — both are required for the version computation and for pushing changes. Install them if missing before doing anything else:
|
||||
|
||||
```bash
|
||||
which git || apt-get install -y git
|
||||
which gh || apt-get install -y gh
|
||||
# Also ensure all tags are fetched so git describe works
|
||||
git fetch --tags
|
||||
```
|
||||
|
||||
Then run the following from the repo root to determine the version string to use:
|
||||
Run the following from the repo root to determine the version string to use:
|
||||
|
||||
```bash
|
||||
currenttag=$(git describe --tags --abbrev=0 | sed 's/v//')
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Package: AMR
|
||||
Version: 3.0.1.9040
|
||||
Date: 2026-03-24
|
||||
Version: 3.0.1.9039
|
||||
Date: 2026-03-19
|
||||
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
|
||||
@@ -63,8 +63,7 @@ Suggests:
|
||||
tidyselect,
|
||||
tinytest,
|
||||
vctrs,
|
||||
xml2,
|
||||
usethis
|
||||
xml2
|
||||
VignetteBuilder: knitr,rmarkdown
|
||||
URL: https://amr-for-r.org, https://github.com/msberends/AMR
|
||||
BugReports: https://github.com/msberends/AMR/issues
|
||||
|
||||
13
NEWS.md
13
NEWS.md
@@ -1,4 +1,4 @@
|
||||
# AMR 3.0.1.9040
|
||||
# AMR 3.0.1.9039
|
||||
|
||||
### New
|
||||
* Integration with the **tidymodels** framework to allow seamless use of SIR, MIC and disk data in modelling pipelines via `recipes`
|
||||
@@ -23,7 +23,6 @@
|
||||
* Fixed a bug in `as.ab()` where certain AB codes containing "PH" or "TH" (such as `ETH`, `MTH`, `PHE`, `PHN`, `STH`, `THA`, `THI1`) would incorrectly return `NA` when combined in a vector with any untranslatable value (#245)
|
||||
* Fixed a bug in `antibiogram()` for when no antimicrobials are set
|
||||
* Fixed a bug in `as.sir()` where for numeric input the arguments `S`, `I`, and `R` would not be considered (#244)
|
||||
* Fixed a bug in plotting MIC values when `keep_operators = "all"`
|
||||
* Fixed some foreign translations of antimicrobial drugs
|
||||
* Fixed a bug for printing column names to the console when using `mutate_at(vars(...), as.mic)` (#249)
|
||||
* Fixed a bug to disregard `NI` for susceptibility proportion functions
|
||||
@@ -31,7 +30,10 @@
|
||||
* Fixed SIR and MIC coercion of combined values, e.g. `as.sir("<= 0.002; S") ` or `as.mic("S; 0.002")` (#252)
|
||||
|
||||
### Updates
|
||||
* Extensive `cli` integration for better message handling and clickable links in messages and warnings (#191, #265)
|
||||
* Replaced all bare backtick-quoted text in `message_()`, `warning_()`, and `stop_()` calls with proper cli inline markup (`{.arg}`, `{.cls}`, `{.fun}`, `{.pkg}`, `{.code}`); rewrote `print.ab` to use a cli named-vector with `*` bullets and code highlighting when cli is available
|
||||
* Added `format_inline_()` helper that formats a cli-markup string and returns it (rather than emitting it), using `cli::format_inline()` when available and `cli_to_plain()` otherwise; used this in `.onAttach` to replace the duplicated cli/non-cli startup message pattern
|
||||
* All inline `{variable}` / `{expression}` in messaging calls are now pre-evaluated via `paste0()`, so users without cli or glue never see raw template syntax
|
||||
* All `"in `funcname()`:"` patterns in `warning_()`/`message_()`/`stop_()` replaced with `{.help [{.fun funcname}](AMR::funcname)}` for clickable help links
|
||||
* `mdro()` now infers resistance for a _missing_ base drug column from an _available_ corresponding drug+inhibitor combination showing resistance (e.g., piperacillin is absent but required, while piperacillin/tazobactam available and resistant). Can be set with the new argument `infer_from_combinations`, which defaults to `TRUE` (#209). Note that this can yield a higher MDRO detection (which is a good thing as it has become more reliable).
|
||||
* `susceptibility()` and `resistance()` gained the argument `guideline`, which defaults to EUCAST, for interpreting the 'I' category correctly.
|
||||
* Added to the `antimicrobials` data set: cefepime/taniborbactam (`FTA`), ceftibuten/avibactam (`CTA`), clorobiocin (`CLB`), kasugamycin (`KAS`), ostreogrycin (`OST`), taniborbactam (`TAN`), thiostrepton (`THS`), xeruborbactam (`XER`), and zorbamycin (`ZOR`)
|
||||
@@ -46,6 +48,11 @@
|
||||
* Removed the `"inverse"` option, which has now become redundant
|
||||
* `ab_group()` now returns values consist with the AMR selectors (#246)
|
||||
* Added two new `NA` objects, `NA_ab_` and `NA_mo_`, analogous to base R's `NA_character_` and `NA_integer_`, for use in pipelines that require typed missing values
|
||||
* `message_()`, `warning_()`, `stop_()` now use `cli` markup when available, with plain-text fallback; removed `add_fn` parameter from `message_()`, `warning_()`, `word_wrap()`
|
||||
* New internal `cli_to_plain()` converts `cli` markup to plain text for non-cli path
|
||||
* All internal call sites updated to `cli` glue syntax
|
||||
* CI dev-version and old-tinytest workflows now only run on `main` branch pushes
|
||||
* Single-quoted literal values in messaging calls replaced with `{.val}`, `{.cls}`, `{.field}`, or `{.code}` markup throughout
|
||||
|
||||
|
||||
# AMR 3.0.1
|
||||
|
||||
@@ -253,9 +253,12 @@ search_type_in_df <- function(x, type, info = TRUE, add_col_prefix = TRUE) {
|
||||
# WHONET support
|
||||
found <- sort(colnames(x)[colnames_formatted %like_case% "^(specimen date|specimen_date|spec_date)"])
|
||||
if (!inherits(pm_pull(x, found), c("Date", "POSIXct"))) {
|
||||
stop_("Found column {.field ", font_bold(found), "} to be used as input for {.arg ", ifelse(add_col_prefix, "col_", ""), type,
|
||||
"}, but this column contains no valid dates. Transform its values to valid dates first.",
|
||||
call = FALSE
|
||||
stop(
|
||||
font_red(paste0(
|
||||
"Found column '", font_bold(found), "' to be used as input for `", ifelse(add_col_prefix, "col_", ""), type,
|
||||
"`, but this column contains no valid dates. Transform its values to valid dates first."
|
||||
)),
|
||||
call. = FALSE
|
||||
)
|
||||
}
|
||||
} else if (any(vapply(FUN.VALUE = logical(1), x, function(x) inherits(x, c("Date", "POSIXct"))))) {
|
||||
@@ -302,7 +305,7 @@ search_type_in_df <- function(x, type, info = TRUE, add_col_prefix = TRUE) {
|
||||
# this column should contain logicals
|
||||
if (!is.logical(x[, found, drop = TRUE])) {
|
||||
message_(
|
||||
"Column {.field ", font_bold(found), "} found as input for {.arg ", ifelse(add_col_prefix, "col_", ""), type,
|
||||
"Column '", font_bold(found), "' found as input for {.arg ", ifelse(add_col_prefix, "col_", ""), type,
|
||||
"}, but this column does not contain {.code TRUE}/{.code FALSE} values and was ignored."
|
||||
)
|
||||
found <- NULL
|
||||
@@ -314,9 +317,9 @@ search_type_in_df <- function(x, type, info = TRUE, add_col_prefix = TRUE) {
|
||||
|
||||
if (!is.null(found) && isTRUE(info)) {
|
||||
if (message_not_thrown_before("search_in_type", type)) {
|
||||
msg <- paste0("Using column {.field ", font_bold(found), "} as input for {.arg ", ifelse(add_col_prefix, "col_", ""), type, "}.")
|
||||
msg <- paste0("Using column '", font_bold(found), "' as input for `", ifelse(add_col_prefix, "col_", ""), type, "`.")
|
||||
if (type %in% c("keyantibiotics", "keyantimicrobials", "specimen")) {
|
||||
msg <- paste(msg, "Use {.arg ", paste0(ifelse(add_col_prefix, "col_", ""), type), "= FALSE} to prevent this.")
|
||||
msg <- paste(msg, "Use", font_bold(paste0(ifelse(add_col_prefix, "col_", ""), type), "= FALSE"), "to prevent this.")
|
||||
}
|
||||
message_(msg)
|
||||
}
|
||||
@@ -380,6 +383,27 @@ pkg_is_available <- function(pkg, also_load = FALSE, min_version = NULL) {
|
||||
isTRUE(out)
|
||||
}
|
||||
|
||||
highlight_code <- function(code) {
|
||||
if (pkg_is_available("cli", min_version = "3.0.0")) {
|
||||
cli::code_highlight(code)
|
||||
} else {
|
||||
code
|
||||
}
|
||||
}
|
||||
|
||||
# Format a cli-markup string for output, with a plain-text fallback when cli is
|
||||
# unavailable. Unlike message_() / warning_() / stop_(), this function returns
|
||||
# the formatted string rather than emitting it, so it can be passed to any
|
||||
# output function (e.g. packageStartupMessage()).
|
||||
format_inline_ <- function(...) {
|
||||
msg <- paste0(c(...), collapse = "")
|
||||
if (pkg_is_available("cli", min_version = "3.0.0")) {
|
||||
cli::format_inline(msg)
|
||||
} else {
|
||||
cli_to_plain(msg, envir = parent.frame())
|
||||
}
|
||||
}
|
||||
|
||||
import_fn <- function(name, pkg, error_on_fail = TRUE) {
|
||||
if (isTRUE(error_on_fail)) {
|
||||
stop_ifnot_installed(pkg)
|
||||
@@ -405,30 +429,6 @@ import_fn <- function(name, pkg, error_on_fail = TRUE) {
|
||||
)
|
||||
}
|
||||
|
||||
highlight_code <- function(code) {
|
||||
if (pkg_is_available("cli", min_version = "3.0.0")) {
|
||||
cli::code_highlight(code)
|
||||
} else {
|
||||
code
|
||||
}
|
||||
}
|
||||
|
||||
# Format a cli-markup string for output, with a plain-text fallback when cli is
|
||||
# unavailable. Unlike message_() / warning_() / stop_(), this function returns
|
||||
# the formatted string rather than emitting it, so it can be passed to any
|
||||
# output function (e.g. packageStartupMessage()).
|
||||
format_inline_ <- function(...) {
|
||||
msg <- paste0(c(...), collapse = "")
|
||||
if (pkg_is_available("cli", min_version = "3.0.0")) {
|
||||
if (!cli::ansi_has_hyperlink_support()) {
|
||||
msg <- simplify_help_markup(msg)
|
||||
}
|
||||
cli::format_inline(msg)
|
||||
} else {
|
||||
cli_to_plain(msg, envir = parent.frame())
|
||||
}
|
||||
}
|
||||
|
||||
# Convert cli glue markup to plain text for the non-cli fallback path.
|
||||
# Called by message_(), warning_(), and stop_() when cli is not available.
|
||||
cli_to_plain <- function(msg, envir = parent.frame()) {
|
||||
@@ -552,46 +552,15 @@ word_wrap <- function(...,
|
||||
gsub("(\n| )+$", "", wrapped)
|
||||
}
|
||||
|
||||
simplify_help_markup <- function(msg) {
|
||||
# {.help [{.fun fn}](pkg::fn)} -> {.code fn()}
|
||||
# {.help [display](topic)} -> {.code display}
|
||||
msg <- gsub(
|
||||
"\\{\\.help \\[\\{\\.fun ([^}]+)\\}\\]\\([^)]+\\)\\}",
|
||||
"{.code \\1()}",
|
||||
msg,
|
||||
perl = TRUE
|
||||
)
|
||||
msg <- gsub(
|
||||
"\\{\\.help \\[([^]]+)\\]\\([^)]+\\)\\}",
|
||||
"{.code \\1}",
|
||||
msg,
|
||||
perl = TRUE
|
||||
)
|
||||
# {.topic [display](topic)} -> {.code ?display}
|
||||
msg <- gsub(
|
||||
"\\{\\.topic \\[([^]]+)\\]\\([^)]+\\)\\}",
|
||||
"{.code ?\\1}",
|
||||
msg,
|
||||
perl = TRUE
|
||||
)
|
||||
msg
|
||||
}
|
||||
|
||||
message_ <- function(...,
|
||||
appendLF = TRUE,
|
||||
as_note = TRUE) {
|
||||
if (pkg_is_available("cli", min_version = "3.0.0")) {
|
||||
msg <- paste0(c(...), collapse = "")
|
||||
if (!cli::ansi_has_hyperlink_support()) {
|
||||
msg <- simplify_help_markup(msg)
|
||||
}
|
||||
if (isTRUE(as_note)) {
|
||||
cli::cli_inform(c("i" = msg), .envir = parent.frame())
|
||||
} else if (isTRUE(appendLF)) {
|
||||
cli::cli_inform(msg, .envir = parent.frame())
|
||||
} else {
|
||||
# This mirrors what rlang::inform() does internally (cat() to stderr), so it behaves consistently with cli_inform() output
|
||||
cat(format_inline_(msg), file = stderr())
|
||||
cli::cli_inform(msg, .envir = parent.frame())
|
||||
}
|
||||
} else {
|
||||
plain_msg <- cli_to_plain(paste0(c(...), collapse = ""), envir = parent.frame())
|
||||
@@ -604,9 +573,6 @@ warning_ <- function(...,
|
||||
call = FALSE) {
|
||||
if (pkg_is_available("cli", min_version = "3.0.0")) {
|
||||
msg <- paste0(c(...), collapse = "")
|
||||
if (!cli::ansi_has_hyperlink_support()) {
|
||||
msg <- simplify_help_markup(msg)
|
||||
}
|
||||
cli::cli_warn(msg, .envir = parent.frame())
|
||||
} else {
|
||||
plain_msg <- cli_to_plain(paste0(c(...), collapse = ""), envir = parent.frame())
|
||||
@@ -619,9 +585,6 @@ warning_ <- function(...,
|
||||
# - wraps text to never break lines within words (plain-text fallback)
|
||||
stop_ <- function(..., call = TRUE) {
|
||||
msg <- paste0(c(...), collapse = "")
|
||||
if (!cli::ansi_has_hyperlink_support()) {
|
||||
msg <- simplify_help_markup(msg)
|
||||
}
|
||||
if (pkg_is_available("cli", min_version = "3.0.0")) {
|
||||
if (isTRUE(call)) {
|
||||
call_obj <- sys.call(-1)
|
||||
@@ -1098,7 +1061,7 @@ get_current_data <- function(arg_name, call) {
|
||||
} else {
|
||||
examples <- ""
|
||||
}
|
||||
stop_("this function must be used inside a {.pkg dplyr} verb or {.cls data.frame} call",
|
||||
stop_("this function must be used inside a {.pkg dplyr} verb or {.code data.frame} call",
|
||||
examples,
|
||||
call = call
|
||||
)
|
||||
|
||||
30
R/ab.R
30
R/ab.R
@@ -484,7 +484,7 @@ as.ab <- function(x, flag_multiple_results = TRUE, language = get_AMR_locale(),
|
||||
}
|
||||
message_(
|
||||
"Antimicrobial translation was uncertain for ", examples,
|
||||
". If required, use {.help [{.fun add_custom_antimicrobials}](AMR::add_custom_antimicrobials)} to add custom entries."
|
||||
". If required, use `add_custom_antimicrobials()` to add custom entries."
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -529,7 +529,7 @@ NA_ab_ <- set_clean_class(NA_character_,
|
||||
#' @rawNamespace if(getRversion() >= "3.0.0") S3method(pillar::pillar_shaft, ab)
|
||||
pillar_shaft.ab <- function(x, ...) {
|
||||
out <- trimws(format(x))
|
||||
out[is.na(x)] <- pillar::style_na(NA)
|
||||
out[is.na(x)] <- font_na(NA)
|
||||
|
||||
# add the names to the drugs as mouse-over!
|
||||
if (in_rstudio()) {
|
||||
@@ -556,25 +556,25 @@ print.ab <- function(x, ...) {
|
||||
function_name <- attributes(x)$amr_selector
|
||||
if (pkg_is_available("cli", min_version = "3.0.0")) {
|
||||
cli::cli_inform(c(
|
||||
"i" = paste0("This {.cls ab} vector was retrieved using {.fun ", function_name, "}, which should normally be used inside a {.pkg dplyr} verb or {.cls data.frame} call, e.g.:"),
|
||||
paste0("\u00a0\u00a0", AMR_env$bullet_icon, " ", highlight_code(paste0("your_data %>% select(", function_name, "())"))),
|
||||
paste0("\u00a0\u00a0", AMR_env$bullet_icon, " ", highlight_code(paste0("your_data %>% select(column_a, column_b, ", function_name, "())"))),
|
||||
paste0("\u00a0\u00a0", AMR_env$bullet_icon, " ", highlight_code(paste0("your_data %>% filter(any(", function_name, "() == \"R\"))"))),
|
||||
paste0("\u00a0\u00a0", AMR_env$bullet_icon, " ", highlight_code(paste0("your_data[, ", function_name, "()]"))),
|
||||
paste0("\u00a0\u00a0", AMR_env$bullet_icon, " ", highlight_code(paste0("your_data[, c(\"column_a\", \"column_b\", ", function_name, "())]")))
|
||||
"i" = paste0("This {.cls ab} vector was retrieved using {.fun ", function_name, "}, which should normally be used inside a {.pkg dplyr} verb or {.code data.frame} call, e.g.:"),
|
||||
"*" = highlight_code(paste0("your_data %>% select(", function_name, "()")),
|
||||
"*" = highlight_code(paste0("your_data %>% select(column_a, column_b, ", function_name, "()")),
|
||||
"*" = highlight_code(paste0("your_data %>% filter(any(", function_name, "() == \"R\"))")),
|
||||
"*" = highlight_code(paste0("your_data[, ", function_name, "()]")),
|
||||
"*" = highlight_code(paste0("your_data[, c(\"column_a\", \"column_b\", ", function_name, "())]"))
|
||||
))
|
||||
} else {
|
||||
message(word_wrap(paste0(
|
||||
"This 'ab' vector was retrieved using `", function_name, "()`, which should normally be used inside a dplyr verb or data.frame call, e.g.:\n",
|
||||
"\u00a0\u00a0", AMR_env$bullet_icon, " your_data %>% select(", function_name, "())\n",
|
||||
"\u00a0\u00a0", AMR_env$bullet_icon, " your_data %>% select(column_a, column_b, ", function_name, "())\n",
|
||||
"\u00a0\u00a0", AMR_env$bullet_icon, " your_data %>% filter(any(", function_name, "() == \"R\"))\n",
|
||||
"\u00a0\u00a0", AMR_env$bullet_icon, " your_data[, ", function_name, "()]\n",
|
||||
"\u00a0\u00a0", AMR_env$bullet_icon, " your_data[, c(\"column_a\", \"column_b\", ", function_name, "())]"
|
||||
" ", AMR_env$bullet_icon, " your_data %>% select(", function_name, "())\n",
|
||||
" ", AMR_env$bullet_icon, " your_data %>% select(column_a, column_b, ", function_name, "())\n",
|
||||
" ", AMR_env$bullet_icon, " your_data %>% filter(any(", function_name, "() == \"R\"))\n",
|
||||
" ", AMR_env$bullet_icon, " your_data[, ", function_name, "()]\n",
|
||||
" ", AMR_env$bullet_icon, " your_data[, c(\"column_a\", \"column_b\", ", function_name, "())]"
|
||||
), as_note = TRUE))
|
||||
}
|
||||
}
|
||||
cat(format_inline_("Class {.cls ab}\n"))
|
||||
cat("Class 'ab'\n")
|
||||
print(as.character(x), quote = FALSE)
|
||||
}
|
||||
|
||||
@@ -718,7 +718,7 @@ get_translate_ab <- function(translate_ab) {
|
||||
} else {
|
||||
translate_ab <- tolower(translate_ab)
|
||||
stop_ifnot(translate_ab %in% colnames(AMR::antimicrobials),
|
||||
"invalid value for {.arg translate_ab}, this must be a column name of the {.help [antimicrobials](AMR::antimicrobials)} data set\n",
|
||||
"invalid value for {.arg translate_ab}, this must be a column name of the {.topic [antimicrobials](AMR::antimicrobials)} data set\n",
|
||||
"or {.code TRUE} (equals {.val name}) or {.code FALSE} to not translate at all.",
|
||||
call = FALSE
|
||||
)
|
||||
|
||||
@@ -678,7 +678,7 @@ not_intrinsic_resistant <- function(only_sir_columns = FALSE, col_mo = NULL, ver
|
||||
agents <- ab_in_data[ab_in_data %in% names(vars_df_R[which(vars_df_R)])]
|
||||
if (length(agents) > 0 &&
|
||||
message_not_thrown_before("not_intrinsic_resistant", sort(agents))) {
|
||||
agents_formatted <- paste0("{.field ", font_bold(agents, collapse = NULL), "}")
|
||||
agents_formatted <- paste0("'", font_bold(agents, collapse = NULL), "'")
|
||||
agents_names <- ab_name(names(agents), tolower = TRUE, language = NULL)
|
||||
need_name <- generalise_antibiotic_name(agents) != generalise_antibiotic_name(agents_names)
|
||||
agents_formatted[need_name] <- paste0(agents_formatted[need_name], " (", agents_names[need_name], ")")
|
||||
@@ -722,7 +722,7 @@ amr_select_exec <- function(function_name,
|
||||
if (any(untreatable %in% names(ab_in_data))) {
|
||||
if (message_not_thrown_before(function_name, "amr_class", "untreatable")) {
|
||||
warning_(
|
||||
"in {.help [{.fun ", function_name, "}](AMR::", function_name, ")}: some drugs were ignored since they cannot be used for treatment: ",
|
||||
"in `", function_name, "()`: some drugs were ignored since they cannot be used for treatment: ",
|
||||
vector_and(
|
||||
ab_name(names(ab_in_data)[names(ab_in_data) %in% untreatable],
|
||||
language = NULL,
|
||||
@@ -797,14 +797,14 @@ amr_select_exec <- function(function_name,
|
||||
if (only_treatable == TRUE) {
|
||||
if (message_not_thrown_before(function_name, "amr_class", "untreatable")) {
|
||||
message_(
|
||||
"in {.help [{.fun ", function_name, "}](AMR::", function_name, ")}: ",
|
||||
"in `", function_name, "()`: ",
|
||||
vector_and(
|
||||
paste0(
|
||||
ab_name(abx[abx %in% untreatable],
|
||||
language = NULL,
|
||||
tolower = TRUE
|
||||
),
|
||||
" ({.field ", font_bold(abx[abx %in% untreatable], collapse = NULL), "})"
|
||||
" (`", abx[abx %in% untreatable], "`)"
|
||||
),
|
||||
quotes = FALSE,
|
||||
sort = TRUE,
|
||||
@@ -837,10 +837,10 @@ amr_select_exec <- function(function_name,
|
||||
#' @export
|
||||
#' @noRd
|
||||
print.amr_selector <- function(x, ...) {
|
||||
warning_("It should never be needed to print an antimicrobial selector class. Are you using {.pkg data.table}? Then add the argument {.arg with = FALSE}, see our examples at {.help [{.fun amr_selector}](AMR::amr_selector)}.",
|
||||
warning_("It should never be needed to print an antimicrobial selector class. Are you using {.pkg data.table}? Then add the argument {.code with = FALSE}, see our examples at {.help [{.fun amr_selector}](AMR::amr_selector)}.",
|
||||
immediate = TRUE
|
||||
)
|
||||
cat(format_inline_("Class {.cls amr_selector}\n"))
|
||||
cat("Class 'amr_selector'\n")
|
||||
print(as.character(x), quote = FALSE)
|
||||
}
|
||||
|
||||
@@ -937,7 +937,7 @@ any.amr_selector_any_all <- function(..., na.rm = FALSE) {
|
||||
if (length(e1) > 1) {
|
||||
message_(
|
||||
"Assuming a filter on ", type, " ", length(e1), " ", gsub("[\\(\\)]", "", fn_name),
|
||||
". Wrap around {.fun all} or {.fun any} to prevent this note."
|
||||
". Wrap around `all()` or `any()` to prevent this note."
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -962,7 +962,7 @@ any.amr_selector_any_all <- function(..., na.rm = FALSE) {
|
||||
if (length(e1) > 1) {
|
||||
message_(
|
||||
"Assuming a filter on ", type, " ", length(e1), " ", gsub("[\\(\\)]", "", fn_name),
|
||||
". Wrap around {.fun all} or {.fun any} to prevent this note."
|
||||
". Wrap around `all()` or `any()` to prevent this note."
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1071,12 +1071,12 @@ message_agent_names <- function(function_name, agents, ab_group = NULL, examples
|
||||
message_("No antimicrobial drugs of class '", ab_group, "' found", examples, ".")
|
||||
}
|
||||
} else {
|
||||
agents_formatted <- paste0("{.field ", font_bold(agents, collapse = NULL), "}")
|
||||
agents_formatted <- paste0("'", font_bold(agents, collapse = NULL), "'")
|
||||
agents_names <- ab_name(names(agents), tolower = TRUE, language = NULL)
|
||||
need_name <- generalise_antibiotic_name(agents) != generalise_antibiotic_name(agents_names)
|
||||
agents_formatted[need_name] <- paste0(agents_formatted[need_name], " (", agents_names[need_name], ")")
|
||||
message_(
|
||||
"For {.help [", function_name, "(",
|
||||
"For `", function_name, "(",
|
||||
ifelse(function_name == "amr_class",
|
||||
paste0("\"", amr_class_args, "\""),
|
||||
ifelse(!is.null(call),
|
||||
@@ -1084,7 +1084,7 @@ message_agent_names <- function(function_name, agents, ab_group = NULL, examples
|
||||
""
|
||||
)
|
||||
),
|
||||
")](AMR::", function_name, ")} using ",
|
||||
")` using ",
|
||||
ifelse(length(agents) == 1, "column ", "columns "),
|
||||
vector_and(agents_formatted, quotes = FALSE, sort = FALSE)
|
||||
)
|
||||
|
||||
@@ -180,7 +180,7 @@ atc_online_property <- function(atc_code,
|
||||
colnames(out) <- gsub("^atc.*", "atc", tolower(colnames(out)))
|
||||
|
||||
if (length(out) == 0) {
|
||||
message_("{.help [{.fun atc_online_property}](AMR::atc_online_property)}: no properties found for ATC ", atc_code[i], ". Please check {.href ", atc_url, " this WHOCC webpage}.")
|
||||
message_("in {.help [{.fun atc_online_property}](AMR::atc_online_property)}: no properties found for ATC ", atc_code[i], ". Please check {.href ", atc_url, " this WHOCC webpage}.")
|
||||
returnvalue[i] <- NA
|
||||
next
|
||||
}
|
||||
|
||||
6
R/av.R
6
R/av.R
@@ -511,8 +511,8 @@ is.av <- function(x) {
|
||||
#' @rawNamespace if(getRversion() >= "3.0.0") S3method(pillar::pillar_shaft, av)
|
||||
pillar_shaft.av <- function(x, ...) {
|
||||
out <- trimws(format(x))
|
||||
out[!is.na(x)] <- gsub("+", pillar::style_subtle("+"), out[!is.na(x)], fixed = TRUE)
|
||||
out[is.na(x)] <- pillar::style_na(NA)
|
||||
out[!is.na(x)] <- gsub("+", font_subtle("+"), out[!is.na(x)], fixed = TRUE)
|
||||
out[is.na(x)] <- font_na(NA)
|
||||
create_pillar_column(out, align = "left", min_width = 4)
|
||||
}
|
||||
|
||||
@@ -526,7 +526,7 @@ type_sum.av <- function(x, ...) {
|
||||
#' @export
|
||||
#' @noRd
|
||||
print.av <- function(x, ...) {
|
||||
cat(format_inline_("Class {.cls av}\n"))
|
||||
cat("Class 'av'\n")
|
||||
print(as.character(x), quote = FALSE)
|
||||
}
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ bug_drug_combinations <- function(x,
|
||||
col_mo <- search_type_in_df(x = x, type = "mo")
|
||||
stop_if(is.null(col_mo), "{.arg col_mo} must be set")
|
||||
} else {
|
||||
stop_ifnot(col_mo %in% colnames(x), "column {.field ", font_bold(col_mo), "} ({.arg col_mo}) not found")
|
||||
stop_ifnot(col_mo %in% colnames(x), "column '", col_mo, "' ({.arg col_mo}) not found")
|
||||
}
|
||||
|
||||
x.bak <- x
|
||||
|
||||
@@ -166,5 +166,5 @@ clear_custom_antimicrobials <- function() {
|
||||
n2 <- nrow(AMR_env$AB_lookup)
|
||||
AMR_env$custom_ab_codes <- character(0)
|
||||
AMR_env$ab_previously_coerced <- AMR_env$ab_previously_coerced[which(AMR_env$ab_previously_coerced$ab %in% AMR_env$AB_lookup$ab), , drop = FALSE]
|
||||
message_("Cleared ", nr2char(n - n2), " custom record", ifelse(n - n2 > 1, "s", ""), " from the internal {.help [antimicrobials](AMR::antimicrobials)} data set.")
|
||||
message_("Cleared ", nr2char(n - n2), " custom record", ifelse(n - n2 > 1, "s", ""), " from the internal {.topic [antimicrobials](AMR::antimicrobials)} data set.")
|
||||
}
|
||||
|
||||
@@ -235,9 +235,9 @@ print.custom_mdro_guideline <- function(x, ...) {
|
||||
for (i in seq_len(length(x))) {
|
||||
rule <- x[[i]]
|
||||
rule$query <- format_custom_query_rule(rule$query)
|
||||
cat("\u00a0\u00a0", i, ". ", font_bold("If "), font_blue(rule$query), font_bold(" then: "), font_red(rule$value), "\n", sep = "")
|
||||
cat(" ", i, ". ", font_bold("If "), font_blue(rule$query), font_bold(" then: "), font_red(rule$value), "\n", sep = "")
|
||||
}
|
||||
cat("\u00a0\u00a0", i + 1, ". ", font_bold("Otherwise: "), font_red(paste0("Negative")), "\n", sep = "")
|
||||
cat(" ", i + 1, ". ", font_bold("Otherwise: "), font_red(paste0("Negative")), "\n", sep = "")
|
||||
cat("\nUnmatched rows will return ", font_red("NA"), ".\n", sep = "")
|
||||
if (isTRUE(attributes(x)$as_factor)) {
|
||||
cat("Results will be of class 'factor', with ordered levels: ", paste0(attributes(x)$values, collapse = " < "), "\n", sep = "")
|
||||
@@ -260,7 +260,7 @@ run_custom_mdro_guideline <- function(df, guideline, info) {
|
||||
)
|
||||
if (identical(qry, "error")) {
|
||||
warning_("in {.help [{.fun custom_mdro_guideline}](AMR::custom_mdro_guideline)}: rule ", i,
|
||||
" ({.code ", as.character(guideline[[i]]$query), "}) was ignored because of this error message: ",
|
||||
" (`", as.character(guideline[[i]]$query), "`) was ignored because of this error message: ",
|
||||
AMR_env$err_msg,
|
||||
call = FALSE
|
||||
)
|
||||
|
||||
@@ -128,7 +128,7 @@
|
||||
#' }
|
||||
add_custom_microorganisms <- function(x) {
|
||||
meet_criteria(x, allow_class = "data.frame")
|
||||
stop_ifnot("genus" %in% tolower(colnames(x)), "{.arg x} must contain column {.code genus}.")
|
||||
stop_ifnot("genus" %in% tolower(colnames(x)), "{.arg x} must contain column 'genus'.")
|
||||
|
||||
add_MO_lookup_to_AMR_env()
|
||||
|
||||
|
||||
8
R/disk.R
8
R/disk.R
@@ -119,9 +119,9 @@ as.disk <- function(x, na.rm = FALSE) {
|
||||
sort() %pm>%
|
||||
vector_and(quotes = TRUE)
|
||||
cur_col <- get_current_column()
|
||||
warning_("in {.help [{.fun as.disk}](AMR::as.disk)}: ", na_after - na_before, " result",
|
||||
warning_("in {.fun as.disk}: ", na_after - na_before, " result",
|
||||
ifelse(na_after - na_before > 1, "s", ""),
|
||||
ifelse(is.null(cur_col), "", paste0(" in column {.field ", font_bold(cur_col, collapse = NULL), "}")),
|
||||
ifelse(is.null(cur_col), "", paste0(" in column '", cur_col, "'")),
|
||||
" truncated (",
|
||||
round(((na_after - na_before) / length(x)) * 100),
|
||||
"%) that were invalid disk zones: ",
|
||||
@@ -162,7 +162,7 @@ is.disk <- function(x) {
|
||||
#' @rawNamespace if(getRversion() >= "3.0.0") S3method(pillar::pillar_shaft, disk)
|
||||
pillar_shaft.disk <- function(x, ...) {
|
||||
out <- trimws(format(x))
|
||||
out[is.na(x)] <- pillar::style_na(NA)
|
||||
out[is.na(x)] <- font_na(NA)
|
||||
create_pillar_column(out, align = "right", width = 2)
|
||||
}
|
||||
|
||||
@@ -170,7 +170,7 @@ pillar_shaft.disk <- function(x, ...) {
|
||||
#' @export
|
||||
#' @noRd
|
||||
print.disk <- function(x, ...) {
|
||||
cat(format_inline_("Class {.cls disk}\n"))
|
||||
cat("Class 'disk'\n")
|
||||
print(as.integer(x), quote = FALSE)
|
||||
}
|
||||
|
||||
|
||||
@@ -333,7 +333,7 @@ first_isolate <- function(x = NULL,
|
||||
check_columns_existance <- function(column, tblname = x) {
|
||||
if (!is.null(column)) {
|
||||
stop_ifnot(column %in% colnames(tblname),
|
||||
"Column {.code ", column, "} not found.",
|
||||
"Column '{column}' not found.",
|
||||
call = FALSE
|
||||
)
|
||||
}
|
||||
@@ -554,7 +554,7 @@ first_isolate <- function(x = NULL,
|
||||
format(sum(x$newvar_mo == "UNKNOWN", na.rm = TRUE),
|
||||
decimal.mark = decimal.mark, big.mark = big.mark
|
||||
),
|
||||
" isolates with a microbial ID 'UNKNOWN' (in column {.field ", font_bold(col_mo), "})"
|
||||
" isolates with a microbial ID 'UNKNOWN' (in column '", font_bold(col_mo), "')"
|
||||
)
|
||||
}
|
||||
x[which(x$newvar_mo == "UNKNOWN"), "newvar_first_isolate"] <- include_unknown
|
||||
@@ -565,7 +565,7 @@ first_isolate <- function(x = NULL,
|
||||
"Excluding ", format(sum(is.na(x$newvar_mo), na.rm = TRUE),
|
||||
decimal.mark = decimal.mark, big.mark = big.mark
|
||||
),
|
||||
" isolates with a microbial ID `NA` (in column {.field ", font_bold(col_mo), "})"
|
||||
" isolates with a microbial ID `NA` (in column '", font_bold(col_mo), "')"
|
||||
)
|
||||
}
|
||||
x[which(is.na(x$newvar_mo)), "newvar_first_isolate"] <- FALSE
|
||||
|
||||
@@ -86,7 +86,7 @@ guess_ab_col <- function(x = NULL, search_string = NULL, verbose = FALSE, only_s
|
||||
} else {
|
||||
if (isTRUE(verbose)) {
|
||||
message_(
|
||||
"Using column {.field ", font_bold(ab_result), "} as input for ", search_string,
|
||||
"Using column '", font_bold(ab_result), "' as input for ", search_string,
|
||||
" (", ab_name(search_string, language = NULL, tolower = TRUE), ")."
|
||||
)
|
||||
}
|
||||
@@ -275,7 +275,7 @@ get_column_abx <- function(x,
|
||||
for (i in seq_len(length(out))) {
|
||||
if (isTRUE(verbose) && !out[i] %in% duplicates) {
|
||||
message_(
|
||||
"Using column {.field ", font_bold(out[i]), "} as input for ", names(out)[i],
|
||||
"Using column '", font_bold(out[i]), "' as input for ", names(out)[i],
|
||||
" (", ab_name(names(out)[i], tolower = TRUE, language = NULL), ")."
|
||||
)
|
||||
}
|
||||
@@ -284,7 +284,7 @@ get_column_abx <- function(x,
|
||||
if (names(out)[i] != already_set_as) {
|
||||
message_(
|
||||
paste0(
|
||||
"Column {.field ", font_bold(out[i]), "} will not be used for ",
|
||||
"Column '", font_bold(out[i]), "' will not be used for ",
|
||||
names(out)[i], " (", suppressMessages(ab_name(names(out)[i], tolower = TRUE, language = NULL, fast_mode = TRUE)), ")",
|
||||
", as this antimicrobial has already been set."
|
||||
)
|
||||
|
||||
@@ -329,7 +329,7 @@ interpretive_rules <- function(x,
|
||||
if (!"AMP" %in% names(cols_ab) && "AMX" %in% names(cols_ab)) {
|
||||
# ampicillin column is missing, but amoxicillin is available
|
||||
if (isTRUE(info)) {
|
||||
message_("Using column {.field ", font_bold(cols_ab[names(cols_ab) == "AMX"]), "} as input for ampicillin since many EUCAST rules depend on it.")
|
||||
message_("Using column '", cols_ab[names(cols_ab) == "AMX"], "' as input for ampicillin since many EUCAST rules depend on it.")
|
||||
}
|
||||
cols_ab <- c(cols_ab, c(AMP = unname(cols_ab[names(cols_ab) == "AMX"])))
|
||||
}
|
||||
@@ -510,8 +510,8 @@ interpretive_rules <- function(x,
|
||||
|
||||
## Set base to R where base + enzyme inhibitor is R ----
|
||||
rule_current <- paste0(
|
||||
ab_enzyme$base_name[i], " ({.field ", font_bold(col_base), "}) = R if ",
|
||||
tolower(ab_enzyme$enzyme_name[i]), " ({.field ", font_bold(col_enzyme), "}) = R"
|
||||
ab_enzyme$base_name[i], " (`", col_base, "`) = R if ",
|
||||
tolower(ab_enzyme$enzyme_name[i]), " (`", col_enzyme, "`) = R"
|
||||
)
|
||||
if (isTRUE(info)) {
|
||||
cat(word_wrap(rule_current,
|
||||
@@ -551,8 +551,8 @@ interpretive_rules <- function(x,
|
||||
|
||||
## Set base + enzyme inhibitor to S where base is S ----
|
||||
rule_current <- paste0(
|
||||
ab_enzyme$enzyme_name[i], " ({.field ", font_bold(col_enzyme), "}) = S if ",
|
||||
tolower(ab_enzyme$base_name[i]), " ({.field ", font_bold(col_base), "}) = S"
|
||||
ab_enzyme$enzyme_name[i], " (`", col_enzyme, "`) = S if ",
|
||||
tolower(ab_enzyme$base_name[i]), " (`", col_base, "`) = S"
|
||||
)
|
||||
|
||||
if (isTRUE(info)) {
|
||||
@@ -662,9 +662,9 @@ interpretive_rules <- function(x,
|
||||
if (ab %in% names(cols_ab) && !ab_s %in% names(cols_ab)) {
|
||||
if (isTRUE(info)) {
|
||||
message_(
|
||||
"Using column {.field ", font_bold(cols_ab[names(cols_ab) == ab]),
|
||||
"} as ", ab_name(ab_s, language = NULL, tolower = TRUE),
|
||||
" since a column {.code ", ab_s, "} is missing but required for the chosen rules"
|
||||
"Using column '", cols_ab[names(cols_ab) == ab],
|
||||
"' as ", ab_name(ab_s, language = NULL, tolower = TRUE),
|
||||
" since a column '", ab_s, "' is missing but required for the chosen rules"
|
||||
)
|
||||
}
|
||||
cols_ab <- c(cols_ab, stats::setNames(unname(cols_ab[names(cols_ab) == ab]), ab_s))
|
||||
@@ -806,7 +806,7 @@ interpretive_rules <- function(x,
|
||||
")$"
|
||||
)
|
||||
} else if (like_is_one_of != "like") {
|
||||
stop("invalid value for column {.field like.is.one_of}", call. = FALSE)
|
||||
stop("invalid value for column 'like.is.one_of'", call. = FALSE)
|
||||
}
|
||||
|
||||
if (is.na(source_antibiotics)) {
|
||||
|
||||
2
R/mdro.R
2
R/mdro.R
@@ -476,7 +476,7 @@ mdro <- function(x = NULL,
|
||||
if (!"AMP" %in% names(cols_ab) && "AMX" %in% names(cols_ab)) {
|
||||
# ampicillin column is missing, but amoxicillin is available
|
||||
if (isTRUE(info)) {
|
||||
message_("Using column {.field ", font_bold(cols_ab[names(cols_ab) == "AMX"]), "} as input for ampicillin since many MDRO rules depend on it.")
|
||||
message_("Using column '", cols_ab[names(cols_ab) == "AMX"], "' as input for ampicillin since many MDRO rules depend on it.")
|
||||
}
|
||||
cols_ab <- c(cols_ab, c(AMP = unname(cols_ab[names(cols_ab) == "AMX"])))
|
||||
}
|
||||
|
||||
23
R/mic.R
23
R/mic.R
@@ -72,7 +72,7 @@ COMMON_MIC_VALUES <- c(
|
||||
#' ```
|
||||
#' x <- random_mic(10)
|
||||
#' x
|
||||
#' #> Class <mic>
|
||||
#' #> Class 'mic'
|
||||
#' #> [1] 16 1 8 8 64 >=128 0.0625 32 32 16
|
||||
#'
|
||||
#' is.factor(x)
|
||||
@@ -89,7 +89,7 @@ COMMON_MIC_VALUES <- c(
|
||||
#'
|
||||
#' ```
|
||||
#' x[x > 4]
|
||||
#' #> Class <mic>
|
||||
#' #> Class 'mic'
|
||||
#' #> [1] 16 8 8 64 >=128 32 32 16
|
||||
#'
|
||||
#' df <- data.frame(x, hospital = "A")
|
||||
@@ -269,9 +269,9 @@ as.mic <- function(x, na.rm = FALSE, keep_operators = "all", round_to_next_log2
|
||||
sort() %pm>%
|
||||
vector_and(quotes = TRUE)
|
||||
cur_col <- get_current_column()
|
||||
warning_("in {.help [{.fun as.mic}](AMR::as.mic)}: ", na_after - na_before, " result",
|
||||
warning_("in {.fun as.mic}: ", na_after - na_before, " result",
|
||||
ifelse(na_after - na_before > 1, "s", ""),
|
||||
ifelse(is.null(cur_col), "", paste0(" in column {.field ", font_bold(cur_col, collapse = NULL), "}")),
|
||||
ifelse(is.null(cur_col), "", paste0(" in column '", cur_col, "'")),
|
||||
" truncated (",
|
||||
round(((na_after - na_before) / length(x)) * 100),
|
||||
"%) that were invalid MICs: ",
|
||||
@@ -322,7 +322,6 @@ NA_mic_ <- set_clean_class(factor(NA, levels = VALID_MIC_LEVELS, ordered = TRUE)
|
||||
#' @export
|
||||
rescale_mic <- function(x, mic_range, keep_operators = "edges", as.mic = TRUE, round_to_next_log2 = FALSE) {
|
||||
meet_criteria(mic_range, allow_class = c("numeric", "integer", "logical", "mic"), has_length = 2, allow_NA = TRUE, allow_NULL = TRUE)
|
||||
|
||||
if (is.numeric(mic_range)) {
|
||||
mic_range <- trimws(format(mic_range, scientific = FALSE))
|
||||
mic_range <- gsub("[.]0+$", "", mic_range)
|
||||
@@ -449,12 +448,16 @@ pillar_shaft.mic <- function(x, ...) {
|
||||
crude_numbers <- as.double(x)
|
||||
operators <- gsub("[^<=>]+", "", as.character(x))
|
||||
# colourise operators
|
||||
operators[!is.na(operators) & operators != ""] <- pillar::style_subtle(operators[!is.na(operators) & operators != ""])
|
||||
operators[!is.na(operators) & operators != ""] <- font_silver(operators[!is.na(operators) & operators != ""], collapse = NULL)
|
||||
out <- trimws(paste0(operators, trimws(format(crude_numbers))))
|
||||
out[is.na(x)] <- pillar::style_na(NA)
|
||||
out[is.na(x)] <- font_na(NA)
|
||||
# make trailing zeroes less visible
|
||||
out[out %like% "[.]"] <- gsub("([.]?0+)$", pillar::style_subtle("\\1"), out[out %like% "[.]"], perl = TRUE)
|
||||
|
||||
if (is_dark()) {
|
||||
fn <- font_silver
|
||||
} else {
|
||||
fn <- font_white
|
||||
}
|
||||
out[out %like% "[.]"] <- gsub("([.]?0+)$", fn("\\1"), out[out %like% "[.]"], perl = TRUE)
|
||||
create_pillar_column(out, align = "right", width = max(nchar(font_stripstyle(out))))
|
||||
}
|
||||
|
||||
@@ -472,7 +475,7 @@ type_sum.mic <- function(x, ...) {
|
||||
#' @export
|
||||
#' @noRd
|
||||
print.mic <- function(x, ...) {
|
||||
cat(format_inline_("Class {.cls mic}"))
|
||||
cat("Class 'mic'")
|
||||
if (!identical(levels(x), VALID_MIC_LEVELS)) {
|
||||
cat(font_red(" with an outdated or altered structure - convert with `as.mic()` to update"))
|
||||
}
|
||||
|
||||
20
R/mo.R
20
R/mo.R
@@ -502,7 +502,7 @@ as.mo <- function(x,
|
||||
)
|
||||
if (any(out %in% AMR_env$MO_lookup$mo[match(post_Becker, AMR_env$MO_lookup$fullname)])) {
|
||||
if (message_not_thrown_before("as.mo", "becker")) {
|
||||
warning_("in {.help [{.fun as.mo}](AMR::as.mo)}: Becker ", font_italic("et al."), " (2014, 2019, 2020) does not contain these species named after their publication: ",
|
||||
warning_("in {.fun as.mo}: Becker ", font_italic("et al."), " (2014, 2019, 2020) does not contain these species named after their publication: ",
|
||||
vector_and(font_italic(gsub("Staphylococcus", "S.", post_Becker, fixed = TRUE), collapse = NULL), quotes = FALSE),
|
||||
". Categorisation to CoNS/CoPS was taken from the original scientific publication(s).",
|
||||
immediate = TRUE, call = FALSE
|
||||
@@ -648,13 +648,13 @@ pillar_shaft.mo <- function(x, ...) {
|
||||
add_MO_lookup_to_AMR_env()
|
||||
out <- trimws(format(x))
|
||||
# grey out the kingdom (part until first "_")
|
||||
out[!is.na(x)] <- gsub("^([A-Z]+_)(.*)", paste0(pillar::style_subtle("\\1"), "\\2"), out[!is.na(x)], perl = TRUE)
|
||||
out[!is.na(x)] <- gsub("^([A-Z]+_)(.*)", paste0(font_subtle("\\1"), "\\2"), out[!is.na(x)], perl = TRUE)
|
||||
# and grey out every _
|
||||
out[!is.na(x)] <- gsub("_", pillar::style_subtle("_"), out[!is.na(x)])
|
||||
out[!is.na(x)] <- gsub("_", font_subtle("_"), out[!is.na(x)])
|
||||
|
||||
# markup NA and UNKNOWN
|
||||
out[is.na(x)] <- pillar::style_na(" NA")
|
||||
out[x == "UNKNOWN"] <- pillar::style_na(" UNKNOWN")
|
||||
out[is.na(x)] <- font_na(" NA")
|
||||
out[x == "UNKNOWN"] <- font_na(" UNKNOWN")
|
||||
|
||||
# markup manual codes
|
||||
out[x %in% AMR_env$MO_lookup$mo & !x %in% AMR::microorganisms$mo] <- font_blue(out[x %in% AMR_env$MO_lookup$mo & !x %in% AMR::microorganisms$mo], collapse = NULL)
|
||||
@@ -673,14 +673,14 @@ pillar_shaft.mo <- function(x, ...) {
|
||||
(!is.null(df) && !all(unlist(df[, which(mo_cols), drop = FALSE]) %in% all_mos))) {
|
||||
# markup old mo codes
|
||||
out[!x %in% all_mos] <- font_italic(
|
||||
pillar::style_na(x[!x %in% all_mos],
|
||||
font_na(x[!x %in% all_mos],
|
||||
collapse = NULL
|
||||
),
|
||||
collapse = NULL
|
||||
)
|
||||
# throw a warning with the affected column name(s)
|
||||
if (!is.null(mo_cols)) {
|
||||
col <- paste0("Column ", vector_or(paste0("{.field ", font_bold(colnames(df)[mo_cols], collapse = NULL), "}"), quotes = TRUE, sort = FALSE))
|
||||
col <- paste0("Column ", vector_or(colnames(df)[mo_cols], quotes = TRUE, sort = FALSE))
|
||||
} else {
|
||||
col <- "The data"
|
||||
}
|
||||
@@ -783,7 +783,7 @@ get_skimmers.mo <- function(column) {
|
||||
#' @noRd
|
||||
print.mo <- function(x, print.shortnames = FALSE, ...) {
|
||||
add_MO_lookup_to_AMR_env()
|
||||
cat(format_inline_("Class {.cls mo}\n"))
|
||||
cat("Class 'mo'\n")
|
||||
x_names <- names(x)
|
||||
if (is.null(x_names) & print.shortnames == TRUE) {
|
||||
x_names <- tryCatch(mo_shortname(x, ...), error = function(e) NULL)
|
||||
@@ -977,8 +977,8 @@ print.mo_uncertainties <- function(x, n = 10, ...) {
|
||||
|
||||
out <- paste0(
|
||||
paste0(
|
||||
"", strrep(font_grey("-"), times = getOption("width", 100) - 1), "\n",
|
||||
"{.val ", x[i, ]$original_input, "}",
|
||||
"", strrep(font_grey("-"), times = getOption("width", 100)), "\n",
|
||||
'"', x[i, ]$original_input, '"',
|
||||
" -> ",
|
||||
paste0(
|
||||
font_bold(italicise(x[i, ]$fullname)),
|
||||
|
||||
@@ -270,6 +270,7 @@ mo_shortname <- function(x, language = get_AMR_locale(), keep_synonyms = getOpti
|
||||
}
|
||||
|
||||
|
||||
|
||||
#' @rdname mo_property
|
||||
#' @export
|
||||
mo_subspecies <- function(x, language = get_AMR_locale(), keep_synonyms = getOption("AMR_keep_synonyms", FALSE), ...) {
|
||||
@@ -1042,7 +1043,7 @@ find_mo_col <- function(fn) {
|
||||
)
|
||||
if (!is.null(df) && !is.null(mo) && is.data.frame(df)) {
|
||||
if (message_not_thrown_before(fn = fn)) {
|
||||
message_("Using column {.field ", font_bold(mo), "} as input for {.help [{.fun ", fn, "}](AMR::", fn, ")}")
|
||||
message_("Using column '", font_bold(mo), "' as input for {.help [{.fun ", fn, "}](AMR::", fn, ")}")
|
||||
}
|
||||
return(df[, mo, drop = TRUE])
|
||||
} else {
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
#'
|
||||
#' ```
|
||||
#' as.mo("lab_mo_ecoli")
|
||||
#' #> Class <mo>
|
||||
#' #> Class 'mo'
|
||||
#' #> [1] B_ESCHR_COLI
|
||||
#'
|
||||
#' mo_genus("lab_mo_kpneumoniae")
|
||||
@@ -85,7 +85,7 @@
|
||||
#' as.mo(c("Escherichia coli", "E. coli", "lab_mo_ecoli"))
|
||||
#' #> NOTE: Translation to one microorganism was guessed with uncertainty.
|
||||
#' #> Use mo_uncertainties() to review it.
|
||||
#' #> Class <mo>
|
||||
#' #> Class 'mo'
|
||||
#' #> [1] B_ESCHR_COLI B_ESCHR_COLI B_ESCHR_COLI
|
||||
#' ```
|
||||
#'
|
||||
@@ -108,7 +108,7 @@
|
||||
#' #> NOTE: Updated mo_source file '/Users/me/mo_source.rds' (0.3 kB) from
|
||||
#' #> '/Users/me/Documents/ourcodes.xlsx' (9 kB), columns
|
||||
#' #> "Organisation XYZ" and "mo"
|
||||
#' #> Class <mo>
|
||||
#' #> Class 'mo'
|
||||
#' #> [1] B_ESCHR_COLI
|
||||
#'
|
||||
#' mo_genus("lab_Staph_aureus")
|
||||
@@ -289,7 +289,7 @@ check_validity_mo_source <- function(x, refer_to_name = "`reference_df`", stop_o
|
||||
}
|
||||
if (!"mo" %in% colnames(x)) {
|
||||
if (stop_on_error == TRUE) {
|
||||
stop_(refer_to_name, " must contain a column {.code mo}", call = FALSE)
|
||||
stop_(refer_to_name, " must contain a column {.field mo}", call = FALSE)
|
||||
} else {
|
||||
return(FALSE)
|
||||
}
|
||||
@@ -313,14 +313,14 @@ check_validity_mo_source <- function(x, refer_to_name = "`reference_df`", stop_o
|
||||
}
|
||||
if (colnames(x)[1] != "mo" && nrow(x) > length(unique(x[, 1, drop = TRUE]))) {
|
||||
if (stop_on_error == TRUE) {
|
||||
stop_(refer_to_name, " contains duplicate values in column {.field ", font_bold(colnames(x)[1]), "}", call = FALSE)
|
||||
stop_(refer_to_name, " contains duplicate values in column '", colnames(x)[1], "'", call = FALSE)
|
||||
} else {
|
||||
return(FALSE)
|
||||
}
|
||||
}
|
||||
if (colnames(x)[2] != "mo" && nrow(x) > length(unique(x[, 2, drop = TRUE]))) {
|
||||
if (stop_on_error == TRUE) {
|
||||
stop_(refer_to_name, " contains duplicate values in column {.field ", font_bold(colnames(x)[2]), "}", call = FALSE)
|
||||
stop_(refer_to_name, " contains duplicate values in column '", colnames(x)[2], "'", call = FALSE)
|
||||
} else {
|
||||
return(FALSE)
|
||||
}
|
||||
|
||||
37
R/plotting.R
37
R/plotting.R
@@ -262,11 +262,11 @@ create_scale_mic <- function(aest, keep_operators, mic_range = NULL, ...) {
|
||||
}
|
||||
mics <- rescale_mic(x = as.double(as.mic(df[[aest_val]])), keep_operators = "none", mic_range = NULL, as.mic = TRUE)
|
||||
if (!is.null(self$mic_values_rescaled) && any(mics < min(self$mic_values_rescaled, na.rm = TRUE) | mics > max(self$mic_values_rescaled, na.rm = TRUE), na.rm = TRUE)) {
|
||||
warning_("The value for {.field ", font_bold(aest_val), "} is outside the plotted MIC range, consider using/updating the {.arg mic_range} argument in {.fun scale_", aest, "_mic}.")
|
||||
warning_("The value for {.field ", aest_val, "} is outside the plotted MIC range, consider using/updating the {.arg mic_range} argument in {.fun scale_", aest, "_mic}.")
|
||||
}
|
||||
out[[aest_val]] <- log2(as.double(mics))
|
||||
} else {
|
||||
self$mic_values_rescaled <- rescale_mic(x = as.character(df[[aest]]), keep_operators = keep_operators, mic_range = mic_range, as.mic = TRUE)
|
||||
self$mic_values_rescaled <- rescale_mic(x = as.double(as.mic(df[[aest]])), keep_operators = keep_operators, mic_range = mic_range, as.mic = TRUE)
|
||||
# create new breaks and labels here
|
||||
lims <- range(self$mic_values_rescaled, na.rm = TRUE)
|
||||
# support inner and outer 'mic_range' settings (e.g., the data ranges 0.5-8 and 'mic_range' is set to 0.025-32)
|
||||
@@ -280,21 +280,11 @@ create_scale_mic <- function(aest, keep_operators, mic_range = NULL, ...) {
|
||||
ind_max <- which(COMMON_MIC_VALUES >= lims[2])[which.min(abs(COMMON_MIC_VALUES[COMMON_MIC_VALUES >= lims[2]] - lims[2]))] # Closest index where COMMON_MIC_VALUES >= lims[2]
|
||||
|
||||
self$mic_values_levels <- as.mic(COMMON_MIC_VALUES[ind_min:ind_max])
|
||||
if (length(unique(self$mic_values_levels)) > 1) {
|
||||
if (keep_operators == "all" && !all(self$mic_values_rescaled %in% self$mic_values_levels, na.rm = TRUE)) {
|
||||
self$mic_values_levels <- unique(sort(c(self$mic_values_levels, self$mic_values_rescaled)))
|
||||
|
||||
# collision = same log2 position, but different string labels
|
||||
log_positions <- log2(as.double(self$mic_values_levels))
|
||||
dup_positions <- log_positions[duplicated(log_positions) | duplicated(log_positions, fromLast = TRUE)]
|
||||
colliding_labels <- as.character(self$mic_values_levels)[log_positions %in% dup_positions]
|
||||
self$warn_keep_all_operators <- length(unique(colliding_labels)) > 1
|
||||
} else if (keep_operators == "edges") {
|
||||
if (keep_operators %in% c("edges", "all") && length(unique(self$mic_values_levels)) > 1) {
|
||||
self$mic_values_levels[1] <- paste0("<=", self$mic_values_levels[1])
|
||||
self$mic_values_levels[length(self$mic_values_levels)] <- paste0(">=", self$mic_values_levels[length(self$mic_values_levels)])
|
||||
}
|
||||
}
|
||||
|
||||
self$mic_values_log <- log2(as.double(self$mic_values_rescaled))
|
||||
|
||||
if (aest == "y" && "group" %in% colnames(df)) {
|
||||
@@ -322,26 +312,7 @@ create_scale_mic <- function(aest, keep_operators, mic_range = NULL, ...) {
|
||||
}
|
||||
scale$labels <- function(..., self) {
|
||||
if (is.null(self$mic_breaks_set)) {
|
||||
if (isTRUE(self$warn_keep_all_operators)) {
|
||||
lookup <- tapply(
|
||||
as.character(self$mic_values_rescaled),
|
||||
self$mic_values_log,
|
||||
function(x) paste(unique(x), collapse = ", ")
|
||||
)
|
||||
level_log <- as.character(log2(as.double(self$mic_values_levels)))
|
||||
|
||||
if (any(grepl(", ", lookup))) {
|
||||
warning_("Using {.arg keep_operators = \"all\"} caused MIC values with different operators to share the same log2 position on the axis. These have been combined into a single label (e.g., {.val ", lookup[grepl(", ", lookup)][1], "}).", call = FALSE)
|
||||
}
|
||||
|
||||
ifelse(
|
||||
level_log %in% names(lookup),
|
||||
lookup[level_log],
|
||||
as.character(self$mic_values_levels)
|
||||
)
|
||||
} else {
|
||||
self$mic_values_levels
|
||||
}
|
||||
} else {
|
||||
breaks <- tryCatch(scale$breaks(), error = function(e) NULL)
|
||||
if (!is.null(breaks)) {
|
||||
@@ -441,7 +412,7 @@ create_scale_sir <- function(aesthetics, colours_SIR, language, eucast_I, ...) {
|
||||
|
||||
scale$labels <- function(x) {
|
||||
stop_ifnot(all(x %in% c(levels(NA_sir_), "SI", "IR", NA)),
|
||||
"Apply `scale_", aesthetics[1], "_sir()` to a variable of class {.cls sir}, see {.help [{.fun as.sir}](AMR::as.sir)}.",
|
||||
"Apply `scale_", aesthetics[1], "_sir()` to a variable of class 'sir', see {.help [{.fun as.sir}](AMR::as.sir)}.",
|
||||
call = FALSE
|
||||
)
|
||||
x <- as.character(x)
|
||||
|
||||
@@ -346,7 +346,7 @@ sir_confidence_interval <- function(...,
|
||||
if (n < minimum) {
|
||||
warning_("Introducing NA: ",
|
||||
ifelse(n == 0, "no", paste("only", n)),
|
||||
" results available for {.help [{.fun sir_confidence_interval}](AMR::sir_confidence_interval)} (whilst {.arg minimum = ", minimum, "}).",
|
||||
" results available for `sir_confidence_interval()` (`minimum` = ", minimum, ").",
|
||||
call = FALSE
|
||||
)
|
||||
if (is.character(out)) {
|
||||
|
||||
@@ -150,7 +150,7 @@ resistance_predict <- function(x,
|
||||
}
|
||||
stop_ifnot(
|
||||
col_date %in% colnames(x),
|
||||
"column {.code ", col_date, "} not found"
|
||||
"column '", col_date, "' not found"
|
||||
)
|
||||
|
||||
year <- function(x) {
|
||||
|
||||
95
R/sir.R
95
R/sir.R
@@ -471,7 +471,7 @@ is_sir_eligible <- function(x, threshold = 0.05) {
|
||||
if (!is.na(ab)) {
|
||||
# this is a valid antibiotic drug code
|
||||
message_(
|
||||
"Column {.field ", font_bold(cur_col), "} is SIR eligible (despite only having empty values), since it seems to be ",
|
||||
"Column '", font_bold(cur_col), "' is SIR eligible (despite only having empty values), since it seems to be ",
|
||||
ab_name(ab, language = NULL, tolower = TRUE), " (", ab, ")"
|
||||
)
|
||||
return(TRUE)
|
||||
@@ -601,7 +601,7 @@ as.sir.default <- function(x,
|
||||
ifelse(length(out7) > 0, paste0("7 as \"", out7, "\""), NA_character_),
|
||||
ifelse(length(out8) > 0, paste0("8 as \"", out8, "\""), NA_character_)
|
||||
)
|
||||
message_("{.help [{.fun as.sir}](AMR::as.sir)}: Interpreting input value ", vector_and(out[!is.na(out)], quotes = FALSE, sort = FALSE))
|
||||
message_("in {.help [{.fun as.sir}](AMR::as.sir)}: Interpreting input value ", vector_and(out[!is.na(out)], quotes = FALSE, sort = FALSE))
|
||||
}
|
||||
|
||||
if (na_before != na_after) {
|
||||
@@ -612,7 +612,7 @@ as.sir.default <- function(x,
|
||||
cur_col <- get_current_column()
|
||||
warning_("in {.help [{.fun as.sir}](AMR::as.sir)}: ", na_after - na_before, " result",
|
||||
ifelse(na_after - na_before > 1, "s", ""),
|
||||
ifelse(is.null(cur_col), "", paste0(" in column {.field ", font_bold(cur_col, collapse = NULL), "}")),
|
||||
ifelse(is.null(cur_col), "", paste0(" in column '", cur_col, "'")),
|
||||
" truncated (",
|
||||
round(((na_after - na_before) / length(x)) * 100),
|
||||
"%) that were invalid antimicrobial interpretations: ",
|
||||
@@ -759,10 +759,6 @@ as.sir.data.frame <- function(x,
|
||||
meet_criteria(max_cores, allow_class = c("numeric", "integer"), has_length = 1)
|
||||
x.bak <- x
|
||||
|
||||
if (isTRUE(info) && message_not_thrown_before("as.sir", "sir_interpretation_history")) {
|
||||
message_("Run {.help [{.fun sir_interpretation_history}](AMR::sir_interpretation_history)} afterwards to retrieve a logbook with all details of the breakpoint interpretations.\n\n")
|
||||
}
|
||||
|
||||
if (tryCatch(length(list(...)) > 0, error = function(e) TRUE)) {
|
||||
sel <- colnames(pm_select(x, ...))
|
||||
} else {
|
||||
@@ -839,7 +835,7 @@ as.sir.data.frame <- function(x,
|
||||
message_(
|
||||
"Assuming value", plural[1], " ",
|
||||
vector_and(col_values, quotes = TRUE),
|
||||
" in column ", paste0("{.field ", font_bold(col_specimen), "}"), " reflect", plural[2], " ", plural[3], "urinary tract infection", plural[1],
|
||||
" in column ", paste0("{.field ", col_specimen, "}"), " reflect", plural[2], " ", plural[3], "urinary tract infection", plural[1],
|
||||
".\n Use `as.sir(uti = FALSE)` to prevent this."
|
||||
)
|
||||
}
|
||||
@@ -861,7 +857,7 @@ as.sir.data.frame <- function(x,
|
||||
return(FALSE)
|
||||
}
|
||||
if (length(sel) == 0 || (length(sel) > 0 && ab %in% sel)) {
|
||||
ab_coerced <- suppressWarnings(as.ab(ab, info = FALSE))
|
||||
ab_coerced <- suppressWarnings(as.ab(ab, info = info))
|
||||
if (is.na(ab_coerced) || (length(sel) > 0 & !ab %in% sel)) {
|
||||
# not even a valid AB code
|
||||
return(FALSE)
|
||||
@@ -911,11 +907,6 @@ as.sir.data.frame <- function(x,
|
||||
}
|
||||
}
|
||||
|
||||
if (isTRUE(info)) {
|
||||
message_(as_note = FALSE) # empty line
|
||||
message_("Processing columns:", as_note = FALSE)
|
||||
}
|
||||
|
||||
run_as_sir_column <- function(i) {
|
||||
ab_col <- ab_cols[i]
|
||||
out <- list(result = NULL, log = NULL)
|
||||
@@ -978,12 +969,12 @@ as.sir.data.frame <- function(x,
|
||||
return(out)
|
||||
} else if (types[i] == "sir") {
|
||||
ab <- ab_col
|
||||
ab_coerced <- suppressWarnings(as.ab(ab, info = FALSE))
|
||||
ab_coerced <- suppressWarnings(as.ab(ab, info = info))
|
||||
show_message <- FALSE
|
||||
if (!all(x[, ab, drop = TRUE] %in% c("S", "SDD", "I", "R", "NI", NA), na.rm = TRUE)) {
|
||||
show_message <- TRUE
|
||||
if (isTRUE(info)) {
|
||||
message_("\u00a0\u00a0", AMR_env$bullet_icon, " Cleaning values in column ", paste0("{.field ", font_bold(ab), "}"), " (",
|
||||
message_("Cleaning values in column ", paste0("{.field ", ab, "}"), " (",
|
||||
ifelse(ab_coerced != toupper(ab), paste0(ab_coerced, ", "), ""),
|
||||
ab_name(ab_coerced, tolower = TRUE, info = info), ")... ",
|
||||
appendLF = FALSE,
|
||||
@@ -993,7 +984,7 @@ as.sir.data.frame <- function(x,
|
||||
} else if (!is.sir(x.bak[, ab, drop = TRUE])) {
|
||||
show_message <- TRUE
|
||||
if (isTRUE(info)) {
|
||||
message_("\u00a0\u00a0", AMR_env$bullet_icon, " Assigning class {.cls sir} to already clean column ", paste0("{.field ", font_bold(ab), "}"), " (",
|
||||
message_("Assigning class {.cls sir} to already clean column ", paste0("{.field ", ab, "}"), " (",
|
||||
ifelse(ab_coerced != toupper(ab), paste0(ab_coerced, ", "), ""),
|
||||
ab_name(ab_coerced, tolower = TRUE, language = NULL, info = info), ")... ",
|
||||
appendLF = FALSE,
|
||||
@@ -1003,7 +994,7 @@ as.sir.data.frame <- function(x,
|
||||
}
|
||||
result <- as.sir.default(x = as.character(x[, ab, drop = TRUE]))
|
||||
if (show_message == TRUE && isTRUE(info)) {
|
||||
message_(font_green_bg("\u00a0OK\u00a0"), as_note = FALSE)
|
||||
message(font_green_bg(" OK "))
|
||||
}
|
||||
out$result <- result
|
||||
out$log <- NULL
|
||||
@@ -1015,7 +1006,7 @@ as.sir.data.frame <- function(x,
|
||||
|
||||
if (isTRUE(parallel) && n_cores > 1 && length(ab_cols) > 1) {
|
||||
if (isTRUE(info)) {
|
||||
message_(as_note = FALSE)
|
||||
message()
|
||||
message_("Running in parallel mode using ", n_cores, " out of ", get_n_cores(Inf), " cores, on columns ", vector_and(font_bold(ab_cols, collapse = NULL), quotes = "'", sort = FALSE), "...", as_note = FALSE, appendLF = FALSE)
|
||||
}
|
||||
if (.Platform$OS.type == "windows" || getRversion() < "4.0.0") {
|
||||
@@ -1035,15 +1026,15 @@ as.sir.data.frame <- function(x,
|
||||
result_list <- parallel::mclapply(seq_along(ab_cols), run_as_sir_column, mc.cores = n_cores)
|
||||
}
|
||||
if (isTRUE(info)) {
|
||||
message_(font_green_bg("\u00aDONE\u00a"), as_note = FALSE)
|
||||
message_(as_note = FALSE)
|
||||
message_(font_green_bg(" DONE "), as_note = FALSE)
|
||||
message()
|
||||
message_("Run {.help [{.fun sir_interpretation_history}](AMR::sir_interpretation_history)} to retrieve a logbook with all details of the breakpoint interpretations.")
|
||||
}
|
||||
} else {
|
||||
# sequential mode (non-parallel)
|
||||
if (isTRUE(info) && n_cores > 1 && NROW(x) * NCOL(x) > 10000) {
|
||||
# give a note that parallel mode might be better
|
||||
message_(as_note = FALSE)
|
||||
message()
|
||||
message_("Running in sequential mode. Consider setting {.arg parallel} to {.code TRUE} to speed up processing on multiple cores.\n")
|
||||
}
|
||||
# this will contain a progress bar already
|
||||
@@ -1230,7 +1221,7 @@ as_sir_method <- function(method_short,
|
||||
host <- convert_host(host, lang = language)
|
||||
if (any(is.na(host) & !is.na(host.bak)) && isTRUE(info) && message_not_thrown_before("as.sir", "missing_hosts")) {
|
||||
warning_("The following animal host(s) could not be coerced: ", vector_and(host.bak[is.na(host) & !is.na(host.bak)]), immediate = TRUE)
|
||||
message_(as_note = FALSE) # new line
|
||||
message() # new line
|
||||
}
|
||||
# TODO add a switch to turn this off? In interactive sessions perhaps ask the user. Default should be On.
|
||||
# if (breakpoint_type == "animal" && isTRUE(info) && message_not_thrown_before("as.sir", "host_missing_breakpoints")) {
|
||||
@@ -1255,7 +1246,7 @@ as_sir_method <- function(method_short,
|
||||
|
||||
# get mo
|
||||
if (!is.null(current_df) && length(mo) == 1 && mo %in% colnames(current_df)) {
|
||||
mo_var_found <- paste0(" based on column {.field ", font_bold(mo), "}")
|
||||
mo_var_found <- paste0(" based on column '", font_bold(mo), "'")
|
||||
mo <- current_df[[mo]]
|
||||
} else if (length(mo) != length(x)) {
|
||||
mo_var_found <- ""
|
||||
@@ -1271,7 +1262,7 @@ as_sir_method <- function(method_short,
|
||||
silent = TRUE
|
||||
)
|
||||
if (!is.null(df) && !is.null(mo) && is.data.frame(df)) {
|
||||
mo_var_found <- paste0(" based on column {.field ", font_bold(mo), "}")
|
||||
mo_var_found <- paste0(" based on column '", font_bold(mo), "'")
|
||||
mo <- df[, mo, drop = TRUE]
|
||||
}
|
||||
},
|
||||
@@ -1324,7 +1315,7 @@ as_sir_method <- function(method_short,
|
||||
}
|
||||
|
||||
ab.bak <- trimws2(ab)
|
||||
ab <- suppressWarnings(as.ab(ab, info = FALSE))
|
||||
ab <- suppressWarnings(as.ab(ab, info = info))
|
||||
if (!is.null(list(...)$mo.bak)) {
|
||||
mo.bak <- list(...)$mo.bak
|
||||
} else {
|
||||
@@ -1360,12 +1351,12 @@ as_sir_method <- function(method_short,
|
||||
}
|
||||
if (isTRUE(add_intrinsic_resistance) && guideline_coerced %unlike% "EUCAST") {
|
||||
if (isTRUE(info) && message_not_thrown_before("as.sir", "intrinsic")) {
|
||||
message_("{.help [{.fun as.sir}](AMR::as.sir)}: using {.arg add_intrinsic_resistance} is only useful when using EUCAST guidelines, since the rules for intrinsic resistance are based on EUCAST.")
|
||||
message_("in {.help [{.fun as.sir}](AMR::as.sir)}: using {.arg add_intrinsic_resistance} is only useful when using EUCAST guidelines, since the rules for intrinsic resistance are based on EUCAST.")
|
||||
}
|
||||
}
|
||||
|
||||
# format agents ----
|
||||
agent_formatted <- paste0("{.field ", font_bold(ab.bak, collapse = NULL), "}")
|
||||
agent_formatted <- paste0("'", font_bold(ab.bak, collapse = NULL), "'")
|
||||
agent_name <- ab_name(ab, tolower = TRUE, language = NULL, info = info)
|
||||
same_ab <- generalise_antibiotic_name(ab) == generalise_antibiotic_name(agent_name)
|
||||
same_ab.bak <- generalise_antibiotic_name(ab.bak) == generalise_antibiotic_name(agent_name)
|
||||
@@ -1381,7 +1372,7 @@ as_sir_method <- function(method_short,
|
||||
)
|
||||
# this intro text will also be printed in the progress bar if the `progress` package is installed
|
||||
intro_txt <- paste0(
|
||||
"\u00a0\u00a0", AMR_env$bullet_icon, " Interpreting ", method_long, ": ", ifelse(isTRUE(list(...)$is_data.frame), "column ", ""),
|
||||
"Interpreting ", method_long, ": ", ifelse(isTRUE(list(...)$is_data.frame), "column ", ""),
|
||||
ifelse(length(unique(agent_formatted)) == 1, unique(agent_formatted), paste0(vector_and(agent_formatted, quotes = FALSE, sort = FALSE))),
|
||||
mo_var_found,
|
||||
ifelse(identical(reference_data, AMR::clinical_breakpoints),
|
||||
@@ -1399,7 +1390,7 @@ as_sir_method <- function(method_short,
|
||||
rise_warning <- FALSE
|
||||
rise_notes <- FALSE
|
||||
method_coerced <- toupper(method)
|
||||
ab_coerced <- as.ab(ab, info = FALSE)
|
||||
ab_coerced <- as.ab(ab, info = info)
|
||||
|
||||
if (identical(reference_data, AMR::clinical_breakpoints)) {
|
||||
breakpoints <- reference_data %pm>%
|
||||
@@ -1496,14 +1487,14 @@ as_sir_method <- function(method_short,
|
||||
# only print intro under 10 items, otherwise progressbar will print this and then it will be printed double
|
||||
message_(intro_txt, appendLF = FALSE, as_note = FALSE)
|
||||
}
|
||||
p <- progress_ticker(n = nrow(df_unique), n_min = 10, title = intro_txt, only_bar_percent = TRUE)
|
||||
p <- progress_ticker(n = nrow(df_unique), n_min = 10, title = font_blue(intro_txt), only_bar_percent = TRUE)
|
||||
has_progress_bar <- !is.null(import_fn("progress_bar", "progress", error_on_fail = FALSE)) && nrow(df_unique) >= 10
|
||||
on.exit(close(p))
|
||||
|
||||
if (nrow(breakpoints) == 0) {
|
||||
# apparently no breakpoints found
|
||||
if (isTRUE(info)) {
|
||||
message_(font_grey_bg(font_black(" NO BREAKPOINTS ")), as_note = FALSE)
|
||||
message(font_grey_bg(font_black(" NO BREAKPOINTS ")))
|
||||
}
|
||||
|
||||
load_mo_uncertainties(metadata_mo)
|
||||
@@ -1729,7 +1720,7 @@ as_sir_method <- function(method_short,
|
||||
pm_filter(uti == FALSE)
|
||||
notes_current <- paste0(
|
||||
notes_current, "\n",
|
||||
paste0("Breakpoints for UTI ", font_bold("and"), " non-UTI available for ", ab_formatted, " in ", mo_formatted, " - assuming ", site, ". Use argument `uti` to set which isolates are from urine. See `?as.sir`.")
|
||||
paste0("Breakpoints for UTI ", font_bold("and"), " non-UTI available for ", ab_formatted, " in ", mo_formatted, " - assuming ", site, ". Use argument {.arg uti} to set which isolates are from urine. See {.help [{.fun as.sir}](AMR::as.sir)}.")
|
||||
)
|
||||
} else if (nrow(breakpoints_current) > 1 && length(unique(breakpoints_current$site)) > 1 && all(breakpoints_current$uti == FALSE, na.rm = TRUE) && message_not_thrown_before("as.sir", "siteOther", mo_current, ab_current)) {
|
||||
# breakpoints for multiple body sites available
|
||||
@@ -1919,7 +1910,7 @@ as_sir_method <- function(method_short,
|
||||
host = vectorise_log_entry(breakpoints_current[, "host", drop = TRUE], length(rows)),
|
||||
input = vectorise_log_entry(as.character(input_clean), length(rows)),
|
||||
outcome = vectorise_log_entry(as.sir(new_sir), length(rows)),
|
||||
notes = font_stripstyle(notes_current),
|
||||
notes = font_stripstyle(notes_current), # vectorise_log_entry(paste0(font_stripstyle(notes_current), collapse = "\n"), length(rows)),
|
||||
guideline = vectorise_log_entry(guideline_current, length(rows)),
|
||||
ref_table = vectorise_log_entry(breakpoints_current[, "ref_tbl", drop = TRUE], length(rows)),
|
||||
uti = vectorise_log_entry(breakpoints_current[, "uti", drop = TRUE], length(rows)),
|
||||
@@ -1944,9 +1935,9 @@ as_sir_method <- function(method_short,
|
||||
notes <- notes[!trimws2(notes) %in% c("", NA_character_)]
|
||||
if (length(notes) > 0) {
|
||||
if (isTRUE(rise_warning)) {
|
||||
message_(font_rose_bg("\u00a0WARNING\u00a0"), as_note = FALSE)
|
||||
message(font_rose_bg(" WARNING "))
|
||||
} else {
|
||||
message_(font_yellow_bg("\u00a0NOTE\u00a0"), as_note = FALSE)
|
||||
message(font_yellow_bg(" NOTE "))
|
||||
}
|
||||
notes <- unique(notes)
|
||||
# if (isTRUE(verbose) || length(notes) == 1 || NROW(AMR_env$sir_interpretation_history) == 0) {
|
||||
@@ -1955,10 +1946,10 @@ as_sir_method <- function(method_short,
|
||||
message_(notes[i], as_note = FALSE)
|
||||
}
|
||||
} else {
|
||||
# message_(word_wrap("\u00a0\u00a0", AMR_env$bullet_icon, " There were multiple notes. Print or View `sir_interpretation_history()` to examine them, or use `as.sir(..., verbose = TRUE)` next time to directly print them here.", add_fn = font_black))
|
||||
# message(word_wrap(" ", AMR_env$bullet_icon, " There were multiple notes. Print or View `sir_interpretation_history()` to examine them, or use `as.sir(..., verbose = TRUE)` next time to directly print them here.", add_fn = font_black))
|
||||
}
|
||||
} else {
|
||||
message_(font_green_bg("\u00a0OK\u00a0"), as_note = FALSE)
|
||||
message(font_green_bg(" OK "))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2010,19 +2001,15 @@ pillar_shaft.sir <- function(x, ...) {
|
||||
if (has_colour()) {
|
||||
# colours will anyway not work when has_colour() == FALSE,
|
||||
# but then the indentation should also not be applied
|
||||
out[is.na(x)] <- pillar::style_subtle(" NA")
|
||||
out[x == "S"] <- font_green_bg(" S ") # has font_black internally
|
||||
out[x == "SDD"] <- font_green_lighter_bg(" SDD ") # has font_black internally
|
||||
if (getOption("AMR_guideline", "EUCAST")[1] == "EUCAST") {
|
||||
out[x == "I"] <- font_green_lighter_bg(" I ") # has font_black internally
|
||||
} else {
|
||||
out[x == "I"] <- font_orange_bg(" I ") # has font_black internally
|
||||
}
|
||||
out[x == "R"] <- font_rose_bg(" R ") # has font_black internally
|
||||
out[x == "NI"] <- font_grey_bg(font_black(" NI ", adapt = FALSE))
|
||||
out[x == "WT"] <- font_green_bg(" WT ") # has font_black internally
|
||||
out[x == "NWT"] <- font_rose_bg(" NWT ") # has font_black internally
|
||||
out[x == "NS"] <- font_rose_bg(" NS ") # has font_black internally
|
||||
out[is.na(x)] <- font_grey(" NA")
|
||||
out[x == "S"] <- font_green_bg(" S ")
|
||||
out[x == "SDD"] <- font_green_lighter_bg(" SDD ")
|
||||
out[x == "I"] <- font_orange_bg(" I ")
|
||||
out[x == "R"] <- font_rose_bg(" R ")
|
||||
out[x == "NI"] <- font_grey_bg(font_black(" NI "))
|
||||
out[x == "WT"] <- font_green_bg(font_black(" WT "))
|
||||
out[x == "NWT"] <- font_rose_bg(font_black(" NWT "))
|
||||
out[x == "NS"] <- font_rose_bg(font_black(" NS "))
|
||||
}
|
||||
create_pillar_column(out, align = "left", width = 5)
|
||||
}
|
||||
@@ -2100,7 +2087,7 @@ get_skimmers.sir <- function(column) {
|
||||
#' @noRd
|
||||
print.sir <- function(x, ...) {
|
||||
x_name <- deparse(substitute(x))
|
||||
cat(format_inline_("Class {.cls sir}\n"))
|
||||
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 ",
|
||||
@@ -2239,13 +2226,13 @@ check_reference_data <- function(reference_data, .call_depth) {
|
||||
class_sir <- vapply(FUN.VALUE = character(1), AMR::clinical_breakpoints, function(x) paste0("<", class(x), ">", collapse = " and "))
|
||||
class_ref <- vapply(FUN.VALUE = character(1), reference_data, function(x) paste0("<", class(x), ">", collapse = " and "))
|
||||
if (!all(names(class_sir) == names(class_ref))) {
|
||||
stop_("{.arg reference_data} must have the same column names as the {.help [clinical_breakpoints](AMR::clinical_breakpoints)} data set.", call = .call_depth)
|
||||
stop_("{.arg reference_data} must have the same column names as the {.topic [clinical_breakpoints](AMR::clinical_breakpoints)} data set.", call = .call_depth)
|
||||
}
|
||||
if (!all(class_sir == class_ref)) {
|
||||
bad_col <- names(class_ref[class_sir != class_ref][1])
|
||||
bad_cls <- gsub("<|>", "", class_ref[class_sir != class_ref][1])
|
||||
exp_cls <- gsub("<|>", "", class_sir[class_sir != class_ref][1])
|
||||
stop_("{.arg reference_data} must be the same structure as the {.help [clinical_breakpoints](AMR::clinical_breakpoints)} data set. Column ", paste0("{.field ", font_bold(bad_col, collapse = NULL), "}"), " is of class ", paste0("{.cls ", bad_cls, "}"), ", but should be of class ", paste0("{.cls ", exp_cls, "}"), call = .call_depth)
|
||||
stop_("{.arg reference_data} must be the same structure as the {.topic [clinical_breakpoints](AMR::clinical_breakpoints)} data set. Column ", paste0("{.field ", bad_col, "}"), " is of class ", paste0("{.cls ", bad_cls, "}"), ", but should be of class ", paste0("{.cls ", exp_cls, "}"), call = .call_depth)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,7 +204,7 @@ sir_calc <- function(...,
|
||||
ifelse(denominator == 0, "no", paste("only", denominator)),
|
||||
" results available",
|
||||
data_vars,
|
||||
" (whilst {.arg minimum = ", minimum, "}).",
|
||||
" (`minimum` = ", minimum, ").",
|
||||
call = FALSE
|
||||
)
|
||||
fraction <- NA_real_
|
||||
|
||||
@@ -141,32 +141,6 @@ import numpy as np
|
||||
# Import the AMR R package
|
||||
amr_r = importr('AMR')
|
||||
|
||||
def convert_to_r(value):
|
||||
"""Convert Python lists/tuples to typed R vectors.
|
||||
|
||||
rpy2's default_converter passes Python lists to R as R lists, not as
|
||||
character/numeric vectors. This causes element-wise type-check functions
|
||||
such as is.mic(), is.sir(), and is.disk() to return a logical vector
|
||||
rather than a single logical, breaking R's scalar && operator.
|
||||
|
||||
This helper converts Python lists and tuples to the appropriate R vector
|
||||
type based on the element types, so R always receives a proper vector."""
|
||||
if isinstance(value, (list, tuple)):
|
||||
if len(value) == 0:
|
||||
return StrVector([])
|
||||
# bool must be checked before int because bool is a subclass of int
|
||||
if all(isinstance(v, bool) for v in value):
|
||||
return robjects.vectors.BoolVector(value)
|
||||
if all(isinstance(v, int) for v in value):
|
||||
return IntVector(value)
|
||||
if all(isinstance(v, float) for v in value):
|
||||
return FloatVector(value)
|
||||
if all(isinstance(v, str) for v in value):
|
||||
return StrVector(value)
|
||||
# Mixed types: coerce all to string
|
||||
return StrVector([str(v) for v in value])
|
||||
return value
|
||||
|
||||
def convert_to_python(r_output):
|
||||
# Check if it's a StrVector (R character vector)
|
||||
if isinstance(r_output, StrVector):
|
||||
@@ -192,13 +166,10 @@ def convert_to_python(r_output):
|
||||
return r_output
|
||||
|
||||
def r_to_python(r_func):
|
||||
"""Decorator that converts Python list/tuple inputs to typed R vectors,
|
||||
runs the rpy2 function under a localconverter, and converts the output
|
||||
to a Python type."""
|
||||
"""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):
|
||||
args = tuple(convert_to_r(a) for a in args)
|
||||
kwargs = {k: convert_to_r(v) for k, v in kwargs.items()}
|
||||
with localconverter(default_converter + numpy2ri.converter + pandas2ri.converter):
|
||||
return convert_to_python(r_func(*args, **kwargs))
|
||||
return wrapper
|
||||
@@ -341,3 +312,4 @@ cd ../PythonPackage/AMR
|
||||
pip3 install build
|
||||
python3 -m build
|
||||
# python3 setup.py sdist bdist_wheel
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ This class for MIC values is a quite a special data type: formally it is an orde
|
||||
|
||||
\if{html}{\out{<div class="sourceCode">}}\preformatted{x <- random_mic(10)
|
||||
x
|
||||
#> Class <mic>
|
||||
#> Class 'mic'
|
||||
#> [1] 16 1 8 8 64 >=128 0.0625 32 32 16
|
||||
|
||||
is.factor(x)
|
||||
@@ -72,7 +72,7 @@ median(x)
|
||||
This makes it possible to maintain operators that often come with MIC values, such ">=" and "<=", even when filtering using \link{numeric} values in data analysis, e.g.:
|
||||
|
||||
\if{html}{\out{<div class="sourceCode">}}\preformatted{x[x > 4]
|
||||
#> Class <mic>
|
||||
#> Class 'mic'
|
||||
#> [1] 16 8 8 64 >=128 32 32 16
|
||||
|
||||
df <- data.frame(x, hospital = "A")
|
||||
|
||||
@@ -58,7 +58,7 @@ It has now created a file \code{"~/mo_source.rds"} with the contents of our Exce
|
||||
And now we can use it in our functions:
|
||||
|
||||
\if{html}{\out{<div class="sourceCode">}}\preformatted{as.mo("lab_mo_ecoli")
|
||||
#> Class <mo>
|
||||
#> Class 'mo'
|
||||
#> [1] B_ESCHR_COLI
|
||||
|
||||
mo_genus("lab_mo_kpneumoniae")
|
||||
@@ -68,7 +68,7 @@ mo_genus("lab_mo_kpneumoniae")
|
||||
as.mo(c("Escherichia coli", "E. coli", "lab_mo_ecoli"))
|
||||
#> NOTE: Translation to one microorganism was guessed with uncertainty.
|
||||
#> Use mo_uncertainties() to review it.
|
||||
#> Class <mo>
|
||||
#> Class 'mo'
|
||||
#> [1] B_ESCHR_COLI B_ESCHR_COLI B_ESCHR_COLI
|
||||
}\if{html}{\out{</div>}}
|
||||
|
||||
@@ -89,7 +89,7 @@ If we edit the Excel file by, let's say, adding row 4 like this:
|
||||
#> NOTE: Updated mo_source file '/Users/me/mo_source.rds' (0.3 kB) from
|
||||
#> '/Users/me/Documents/ourcodes.xlsx' (9 kB), columns
|
||||
#> "Organisation XYZ" and "mo"
|
||||
#> Class <mo>
|
||||
#> Class 'mo'
|
||||
#> [1] B_ESCHR_COLI
|
||||
|
||||
mo_genus("lab_Staph_aureus")
|
||||
|
||||
@@ -219,6 +219,7 @@ test_that("test-eucast_rules.R", {
|
||||
expect_inherits(eucast_dosage(c("tobra", "genta", "cipro")), "data.frame")
|
||||
|
||||
|
||||
|
||||
x <- custom_eucast_rules(
|
||||
AMC == "R" & genus == "Klebsiella" ~ aminopenicillins == "R",
|
||||
AMC == "I" & genus == "Klebsiella" ~ aminopenicillins == "I",
|
||||
|
||||
@@ -272,6 +272,8 @@ test_that("test-mo.R", {
|
||||
)
|
||||
|
||||
x <- as.mo("Sta. aur")
|
||||
# many hits
|
||||
expect_output(print(mo_uncertainties()))
|
||||
|
||||
# no viruses
|
||||
expect_equal(suppressWarnings(as.mo("Virus")), as.mo("UNKNOWN"))
|
||||
|
||||
@@ -36,7 +36,6 @@ test_that("test-zzz.R", {
|
||||
# functions used by import_fn()
|
||||
import_functions <- c(
|
||||
"%chin%" = "data.table",
|
||||
"ansi_has_hyperlink_support" = "cli",
|
||||
"anti_join" = "dplyr",
|
||||
"as.data.table" = "data.table",
|
||||
"as_tibble" = "tibble",
|
||||
@@ -80,12 +79,6 @@ test_that("test-zzz.R", {
|
||||
"freq.default" = "cleaner",
|
||||
"percentage" = "cleaner",
|
||||
# cli
|
||||
"ansi_has_hyperlink_support" = "cli",
|
||||
"cli_abort" = "cli",
|
||||
"cli_inform" = "cli",
|
||||
"cli_warn" = "cli",
|
||||
"code_highlight" = "cli",
|
||||
"format_inline" = "cli",
|
||||
"symbol" = "cli",
|
||||
# curl
|
||||
"has_internet" = "curl",
|
||||
@@ -131,8 +124,6 @@ test_that("test-zzz.R", {
|
||||
"availableCores" = "parallelly",
|
||||
# pillar
|
||||
"pillar_shaft" = "pillar",
|
||||
"style_na" = "pillar",
|
||||
"style_subtle" = "pillar",
|
||||
"tbl_format_footer" = "pillar",
|
||||
"tbl_sum" = "pillar",
|
||||
"type_sum" = "pillar",
|
||||
@@ -170,9 +161,7 @@ test_that("test-zzz.R", {
|
||||
"vec_math" = "vctrs",
|
||||
"vec_ptype2" = "vctrs",
|
||||
"vec_ptype_abbr" = "vctrs",
|
||||
"vec_ptype_full" = "vctrs",
|
||||
# usethis
|
||||
"use_course" = "usethis"
|
||||
"vec_ptype_full" = "vctrs"
|
||||
)
|
||||
|
||||
import_functions <- c(import_functions, call_functions)
|
||||
|
||||
Reference in New Issue
Block a user