diff --git a/DESCRIPTION b/DESCRIPTION index 06cfaf99..38933095 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,5 +1,5 @@ Package: AMR -Version: 1.7.1.9012 +Version: 1.7.1.9013 Date: 2021-07-04 Title: Antimicrobial Resistance Data Analysis Authors@R: c( diff --git a/NEWS.md b/NEWS.md index 3bff0fa0..18bdce54 100755 --- a/NEWS.md +++ b/NEWS.md @@ -1,4 +1,4 @@ -# `AMR` 1.7.1.9012 +# `AMR` 1.7.1.9013 ## Last updated: 4 July 2021 ### Changed @@ -16,6 +16,8 @@ * `as.rsi()` can now correct for textual input (such as "Susceptible", "Resistant") in Dutch, English, French, German, Italian, Portuguese and Spanish * When warnings are throws because of too few isolates in any `count_*()`, `proportion_*()` function (or `resistant()` or `susceptible()`), the `dplyr` group will be shown, if available * Taxonomic names now print in italic in tibbles, if created with `mo_name()`, `mo_fullname()`, `mo_shortname()`, `mo_genus()` or `mo_family()` +* `ab_name()` gained argument `snake_case`, which is useful for column renaming +* Fix for legends created with `scale_rsi_colours()` when using `ggplot2` v3.3.4 or higher (this is `ggplot2` bug #4511, soon to be fixed) # `AMR` 1.7.1 diff --git a/R/ab_class_selectors.R b/R/ab_class_selectors.R index c9fdbb99..a7c3bc40 100644 --- a/R/ab_class_selectors.R +++ b/R/ab_class_selectors.R @@ -30,7 +30,7 @@ #' @param ab_class an antimicrobial class, such as `"carbapenems"`. The columns `group`, `atc_group1` and `atc_group2` of the [antibiotics] data set will be searched (case-insensitive) for this value. #' @param only_rsi_columns a [logical] to indicate whether only columns of class `` must be selected (defaults to `FALSE`), see [as.rsi()] #' @details -#' These functions can be used in data set calls for selecting columns and filtering rows. They are heavily inspired by the [Tidyverse selection helpers](https://tidyselect.r-lib.org/reference/language.html), but also work in base \R and not only in `dplyr` verbs. Nonetheless, they are very convenient to use with `dplyr` functions such as [`select()`][dplyr::select()], [`filter()`][dplyr::filter()] and [`summarise()`][dplyr::summarise()], see *Examples*. +#' These functions can be used in data set calls for selecting columns and filtering rows. They are heavily inspired by the [Tidyverse selection helpers][tidyselect::language] such as [`everything()`][tidyselect::everything()], but also work in base \R and not only in `dplyr` verbs. Nonetheless, they are very convenient to use with `dplyr` functions such as [`select()`][dplyr::select()], [`filter()`][dplyr::filter()] and [`summarise()`][dplyr::summarise()], see *Examples*. #' #' All columns in the data in which these functions are called will be searched for known antibiotic names, abbreviations, brand names, and codes (ATC, EARS-Net, WHO, etc.) in the [antibiotics] data set. This means that a selector such as [aminoglycosides()] will pick up column names like 'gen', 'genta', 'J01GB03', 'tobra', 'Tobracin', etc. Use the [ab_class()] function to filter/select on a manually defined antibiotic class. #' @@ -124,149 +124,168 @@ #' } ab_class <- function(ab_class, only_rsi_columns = FALSE) { - meet_criteria(ab_class, allow_class = "character", has_length = 1) + meet_criteria(ab_class, allow_class = "character", has_length = 1, allow_NULL = TRUE) + meet_criteria(only_rsi_columns, allow_class = "logical", has_length = 1) ab_selector(NULL, only_rsi_columns = only_rsi_columns, ab_class = ab_class) } #' @rdname antibiotic_class_selectors #' @export aminoglycosides <- function(only_rsi_columns = FALSE) { + meet_criteria(only_rsi_columns, allow_class = "logical", has_length = 1) ab_selector("aminoglycosides", only_rsi_columns = only_rsi_columns) } #' @rdname antibiotic_class_selectors #' @export aminopenicillins <- function(only_rsi_columns = FALSE) { + meet_criteria(only_rsi_columns, allow_class = "logical", has_length = 1) ab_selector("aminopenicillins", only_rsi_columns = only_rsi_columns) } #' @rdname antibiotic_class_selectors #' @export betalactams <- function(only_rsi_columns = FALSE) { + meet_criteria(only_rsi_columns, allow_class = "logical", has_length = 1) ab_selector("betalactams", only_rsi_columns = only_rsi_columns) } #' @rdname antibiotic_class_selectors #' @export carbapenems <- function(only_rsi_columns = FALSE) { + meet_criteria(only_rsi_columns, allow_class = "logical", has_length = 1) ab_selector("carbapenems", only_rsi_columns = only_rsi_columns) } #' @rdname antibiotic_class_selectors #' @export cephalosporins <- function(only_rsi_columns = FALSE) { + meet_criteria(only_rsi_columns, allow_class = "logical", has_length = 1) ab_selector("cephalosporins", only_rsi_columns = only_rsi_columns) } #' @rdname antibiotic_class_selectors #' @export cephalosporins_1st <- function(only_rsi_columns = FALSE) { + meet_criteria(only_rsi_columns, allow_class = "logical", has_length = 1) ab_selector("cephalosporins_1st", only_rsi_columns = only_rsi_columns) } #' @rdname antibiotic_class_selectors #' @export cephalosporins_2nd <- function(only_rsi_columns = FALSE) { + meet_criteria(only_rsi_columns, allow_class = "logical", has_length = 1) ab_selector("cephalosporins_2nd", only_rsi_columns = only_rsi_columns) } #' @rdname antibiotic_class_selectors #' @export cephalosporins_3rd <- function(only_rsi_columns = FALSE) { + meet_criteria(only_rsi_columns, allow_class = "logical", has_length = 1) ab_selector("cephalosporins_3rd", only_rsi_columns = only_rsi_columns) } #' @rdname antibiotic_class_selectors #' @export cephalosporins_4th <- function(only_rsi_columns = FALSE) { + meet_criteria(only_rsi_columns, allow_class = "logical", has_length = 1) ab_selector("cephalosporins_4th", only_rsi_columns = only_rsi_columns) } #' @rdname antibiotic_class_selectors #' @export cephalosporins_5th <- function(only_rsi_columns = FALSE) { + meet_criteria(only_rsi_columns, allow_class = "logical", has_length = 1) ab_selector("cephalosporins_5th", only_rsi_columns = only_rsi_columns) } #' @rdname antibiotic_class_selectors #' @export fluoroquinolones <- function(only_rsi_columns = FALSE) { + meet_criteria(only_rsi_columns, allow_class = "logical", has_length = 1) ab_selector("fluoroquinolones", only_rsi_columns = only_rsi_columns) } #' @rdname antibiotic_class_selectors #' @export glycopeptides <- function(only_rsi_columns = FALSE) { + meet_criteria(only_rsi_columns, allow_class = "logical", has_length = 1) ab_selector("glycopeptides", only_rsi_columns = only_rsi_columns) } #' @rdname antibiotic_class_selectors #' @export lincosamides <- function(only_rsi_columns = FALSE) { + meet_criteria(only_rsi_columns, allow_class = "logical", has_length = 1) ab_selector("lincosamides", only_rsi_columns = only_rsi_columns) } #' @rdname antibiotic_class_selectors #' @export lipoglycopeptides <- function(only_rsi_columns = FALSE) { + meet_criteria(only_rsi_columns, allow_class = "logical", has_length = 1) ab_selector("lipoglycopeptides", only_rsi_columns = only_rsi_columns) } #' @rdname antibiotic_class_selectors #' @export macrolides <- function(only_rsi_columns = FALSE) { + meet_criteria(only_rsi_columns, allow_class = "logical", has_length = 1) ab_selector("macrolides", only_rsi_columns = only_rsi_columns) } #' @rdname antibiotic_class_selectors #' @export oxazolidinones <- function(only_rsi_columns = FALSE) { + meet_criteria(only_rsi_columns, allow_class = "logical", has_length = 1) ab_selector("oxazolidinones", only_rsi_columns = only_rsi_columns) } #' @rdname antibiotic_class_selectors #' @export penicillins <- function(only_rsi_columns = FALSE) { + meet_criteria(only_rsi_columns, allow_class = "logical", has_length = 1) ab_selector("penicillins", only_rsi_columns = only_rsi_columns) } #' @rdname antibiotic_class_selectors #' @export polymyxins <- function(only_rsi_columns = FALSE) { + meet_criteria(only_rsi_columns, allow_class = "logical", has_length = 1) ab_selector("polymyxins", only_rsi_columns = only_rsi_columns) } #' @rdname antibiotic_class_selectors #' @export streptogramins <- function(only_rsi_columns = FALSE) { + meet_criteria(only_rsi_columns, allow_class = "logical", has_length = 1) ab_selector("streptogramins", only_rsi_columns = only_rsi_columns) } #' @rdname antibiotic_class_selectors #' @export quinolones <- function(only_rsi_columns = FALSE) { + meet_criteria(only_rsi_columns, allow_class = "logical", has_length = 1) ab_selector("quinolones", only_rsi_columns = only_rsi_columns) } #' @rdname antibiotic_class_selectors #' @export tetracyclines <- function(only_rsi_columns = FALSE) { + meet_criteria(only_rsi_columns, allow_class = "logical", has_length = 1) ab_selector("tetracyclines", only_rsi_columns = only_rsi_columns) } #' @rdname antibiotic_class_selectors #' @export ureidopenicillins <- function(only_rsi_columns = FALSE) { + meet_criteria(only_rsi_columns, allow_class = "logical", has_length = 1) ab_selector("ureidopenicillins", only_rsi_columns = only_rsi_columns) } ab_selector <- function(function_name, only_rsi_columns, ab_class = NULL) { - meet_criteria(function_name, allow_class = "character", has_length = 1, allow_NULL = TRUE, .call_depth = 1) - meet_criteria(only_rsi_columns, allow_class = "logical", has_length = 1, .call_depth = 1) - meet_criteria(ab_class, allow_class = "character", has_length = 1, allow_NULL = TRUE, .call_depth = 1) - # get_current_data() has to run each time, for cases where e.g., filter() and select() are used in same call # but it only takes a couple of milliseconds vars_df <- get_current_data(arg_name = NA, call = -3) diff --git a/R/ab_property.R b/R/ab_property.R index 9e789117..73add9b6 100644 --- a/R/ab_property.R +++ b/R/ab_property.R @@ -29,6 +29,7 @@ #' @inheritSection lifecycle Stable Lifecycle #' @param x any (vector of) text that can be coerced to a valid antibiotic code with [as.ab()] #' @param tolower a [logical] to indicate whether the first [character] of every output should be transformed to a lower case [character]. This will lead to e.g. "polymyxin B" and not "polymyxin b". +#' @param snake_case a [logical] to indicate whether the names should be returned in so-called [snake case](https://en.wikipedia.org/wiki/Snake_case): in lower case and all spaces/slashes replaced with an underscore (`_`). This is useful for column renaming. #' @param property one of the column names of one of the [antibiotics] data set #' @param language language of the returned text, defaults to system language (see [get_locale()]) and can also be set with `getOption("AMR_locale")`. Use `language = NULL` or `language = ""` to prevent translation. #' @param administration way of administration, either `"oral"` or `"iv"` @@ -88,10 +89,11 @@ #' ab_atc("cephtriaxone") #' ab_atc("cephthriaxone") #' ab_atc("seephthriaaksone") -ab_name <- function(x, language = get_locale(), tolower = FALSE, ...) { +ab_name <- function(x, language = get_locale(), tolower = FALSE, snake_case = FALSE, ...) { meet_criteria(x, allow_NA = TRUE) meet_criteria(language, has_length = 1, is_in = c(LANGUAGES_SUPPORTED, ""), allow_NULL = TRUE, allow_NA = TRUE) meet_criteria(tolower, allow_class = "logical", has_length = 1) + meet_criteria(snake_case, allow_class = "logical", has_length = 1) x <- translate_AMR(ab_validate(x = x, property = "name", ...), language = language, only_affect_ab_names = TRUE) if (tolower == TRUE) { @@ -99,6 +101,9 @@ ab_name <- function(x, language = get_locale(), tolower = FALSE, ...) { # as we want "polymyxin B", not "polymyxin b" x <- gsub("^([A-Z])", "\\L\\1", x, perl = TRUE) } + if (snake_case == TRUE) { + x <- tolower(gsub("[^a-zA-Z0-9]+", "_", x)) + } x } diff --git a/R/ggplot_rsi.R b/R/ggplot_rsi.R index b80dee75..481cb391 100755 --- a/R/ggplot_rsi.R +++ b/R/ggplot_rsi.R @@ -370,7 +370,6 @@ scale_rsi_colours <- function(..., aesthetics = "fill") { stop_ifnot_installed("ggplot2") meet_criteria(aesthetics, allow_class = "character", is_in = c("alpha", "colour", "color", "fill", "linetype", "shape", "size")) - # behaviour until AMR pkg v1.5.0 and also when coming from ggplot_rsi() if ("colours" %in% names(list(...))) { original_cols <- c(S = "#3CAEA3", @@ -379,7 +378,9 @@ scale_rsi_colours <- function(..., IR = "#ED553B", R = "#ED553B") colours <- replace(original_cols, names(list(...)$colours), list(...)$colours) - return(ggplot2::scale_fill_manual(values = colours)) + # 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)) } if (identical(unlist(list(...)), FALSE)) { return(invisible()) @@ -411,7 +412,9 @@ scale_rsi_colours <- function(..., dots[dots == "I"] <- "#F6D55C" dots[dots == "R"] <- "#ED553B" cols <- replace(original_cols, names(dots), dots) - ggplot2::scale_discrete_manual(aesthetics = aesthetics, values = cols) + # limits = force is needed in ggplot2 3.3.4 and 3.3.5, see here; + # https://github.com/tidyverse/ggplot2/issues/4511#issuecomment-866185530 + ggplot2::scale_discrete_manual(aesthetics = aesthetics, values = cols, limits = force) } #' @rdname ggplot_rsi diff --git a/R/plot.R b/R/plot.R index a60a69dc..c209a991 100644 --- a/R/plot.R +++ b/R/plot.R @@ -276,8 +276,10 @@ ggplot.mic <- function(data, names(vals) <- translate_AMR(names(vals), language = language) p <- p + ggplot2::geom_col(ggplot2::aes(x = mic, y = count, fill = cols)) + + # limits = force is needed because of a ggplot2 >= 3.3.4 bug (#4511) ggplot2::scale_fill_manual(values = vals, - name = NULL) + name = NULL, + limits = force) } else { p <- p + ggplot2::geom_col(ggplot2::aes(x = mic, y = count)) @@ -500,8 +502,10 @@ ggplot.disk <- function(data, names(vals) <- translate_AMR(names(vals), language = language) p <- p + ggplot2::geom_col(ggplot2::aes(x = disk, y = count, fill = cols)) + + # limits = force is needed because of a ggplot2 >= 3.3.4 bug (#4511) ggplot2::scale_fill_manual(values = vals, - name = NULL) + name = NULL, + limits = force) } else { p <- p + ggplot2::geom_col(ggplot2::aes(x = disk, y = count)) @@ -660,9 +664,11 @@ ggplot.rsi <- function(data, p + ggplot2::geom_col(ggplot2::aes(x = rsi, y = count, fill = rsi)) + + # limits = force is needed because of a ggplot2 >= 3.3.4 bug (#4511) ggplot2::scale_fill_manual(values = c("R" = colours_RSI[1], "S" = colours_RSI[2], - "I" = colours_RSI[3])) + + "I" = colours_RSI[3]), + limits = force) + ggplot2::labs(title = title, x = xlab, y = ylab) + ggplot2::theme(legend.position = "none") } diff --git a/data-raw/AMR_latest.tar.gz b/data-raw/AMR_latest.tar.gz index 710b3b95..3ca36cf9 100644 Binary files a/data-raw/AMR_latest.tar.gz and b/data-raw/AMR_latest.tar.gz differ diff --git a/docs/404.html b/docs/404.html index 50a019da..bd5ebcce 100644 --- a/docs/404.html +++ b/docs/404.html @@ -81,7 +81,7 @@ AMR (for R) - 1.7.1.9012 + 1.7.1.9013 diff --git a/docs/LICENSE-text.html b/docs/LICENSE-text.html index bbf8de67..04ce1862 100644 --- a/docs/LICENSE-text.html +++ b/docs/LICENSE-text.html @@ -81,7 +81,7 @@ AMR (for R) - 1.7.1.9012 + 1.7.1.9013 diff --git a/docs/articles/AMR.html b/docs/articles/AMR.html index fa7113c9..5fe8eef4 100644 --- a/docs/articles/AMR.html +++ b/docs/articles/AMR.html @@ -39,7 +39,7 @@ AMR (for R) - 1.7.1 + 1.7.1.9013 @@ -47,14 +47,14 @@
  • Function betalactams() as additional antbiotic column selector and function filter_betalactams() as additional antbiotic column filter. The group of betalactams consists of all carbapenems, cephalosporins and penicillins.
  • -
  • A ggplot() method for resistance_predict() +
  • A ggplot() method for resistance_predict()
  • @@ -424,7 +427,7 @@ #> Filtering on oxazolidinones: value in column `LNZ` (linezolid) is either "R", "S" or "I"
  • Support for custom MDRO guidelines, using the new custom_mdro_guideline() function, please see mdro() for additional info

  • -
  • ggplot() generics for classes <mic> and <disk>

  • +
  • ggplot() generics for classes <mic> and <disk>

  • Function mo_is_yeast(), which determines whether a microorganism is a member of the taxonomic class Saccharomycetes or the taxonomic order Saccharomycetales:

    @@ -481,7 +484,7 @@
     
  • Plotting of MIC and disk diffusion values now support interpretation colouring if you supply the microorganism and antimicrobial agent
  • All colours were updated to colour-blind friendly versions for values R, S and I for all plot methods (also applies to tibble printing)
  • Interpretation of MIC and disk diffusion values to R/SI will now be translated if the system language is German, Dutch or Spanish (see translate)
  • -
  • Plotting is now possible with base R using plot() and with ggplot2 using ggplot() on any vector of MIC and disk diffusion values
  • +
  • Plotting is now possible with base R using plot() and with ggplot2 using ggplot() on any vector of MIC and disk diffusion values
  • Updated SNOMED codes to US Edition of SNOMED CT from 1 September 2020 and added the source to the help page of the microorganisms data set
  • @@ -833,7 +836,7 @@

    Making this package independent of especially the tidyverse (e.g. packages dplyr and tidyr) tremendously increases sustainability on the long term, since tidyverse functions change quite often. Good for users, but hard for package maintainers. Most of our functions are replaced with versions that only rely on base R, which keeps this package fully functional for many years to come, without requiring a lot of maintenance to keep up with other packages anymore. Another upside it that this package can now be used with all versions of R since R-3.0.0 (April 2013). Our package is being used in settings where the resources are very limited. Fewer dependencies on newer software is helpful for such settings.

    Negative effects of this change are:

    @@ -1432,7 +1435,7 @@ This works for all drug combinations, such as ampicillin/sulbactam, ceftazidime/
  • The age() function gained a new argument exact to determine ages with decimals
  • Removed deprecated functions guess_mo(), guess_atc(), EUCAST_rules(), interpretive_reading(), rsi()
  • -
  • Frequency tables (freq()): +
  • Frequency tables (freq()): @@ -1457,7 +1460,7 @@ This works for all drug combinations, such as ampicillin/sulbactam, ceftazidime/
  • Added ceftazidim intrinsic resistance to Streptococci
  • Changed default settings for age_groups(), to let groups of fives and tens end with 100+ instead of 120+
  • -
  • Fix for freq() for when all values are NA +
  • Fix for freq() for when all values are NA
  • Fix for first_isolate() for when dates are missing
  • Improved speed of guess_ab_col() @@ -1696,7 +1699,7 @@ This works for all drug combinations, such as ampicillin/sulbactam, ceftazidime/
  • -
  • Frequency tables (freq() function): +
  • Frequency tables (freq() function):