2021-02-25 10:33:08 +01:00
# ==================================================================== #
# TITLE #
2022-10-05 09:12:22 +02:00
# AMR: An R Package for Working with Antimicrobial Resistance Data #
2021-02-25 10:33:08 +01:00
# #
# SOURCE #
# https://github.com/msberends/AMR #
# #
2022-10-05 09:12:22 +02:00
# CITE AS #
# Berends MS, Luz CF, Friedrich AW, Sinha BNM, Albers CJ, Glasner C #
# (2022). AMR: An R Package for Working with Antimicrobial Resistance #
# Data. Journal of Statistical Software, 104(3), 1-31. #
# doi:10.18637/jss.v104.i03 #
# #
2022-12-27 15:16:15 +01:00
# Developed at the University of Groningen and the University Medical #
# Center Groningen in The Netherlands, in collaboration with many #
# colleagues from around the world, see our website. #
2021-02-25 10:33:08 +01:00
# #
# This R package is free software; you can freely use and distribute #
# it for both personal and commercial purposes under the terms of the #
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
# the Free Software Foundation. #
# We created this package for both routine data analysis and academic #
# research and it was publicly released in the hope that it will be #
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
# #
# Visit our website for the full manual and a complete tutorial about #
# how to conduct AMR data analysis: https://msberends.github.io/AMR/ #
# ==================================================================== #
#' Plotting for Classes `rsi`, `mic` and `disk`
2022-08-28 10:31:50 +02:00
#'
2021-06-22 12:16:42 +02:00
#' Functions to plot classes `rsi`, `mic` and `disk`, with support for base \R and `ggplot2`.
2022-08-21 16:37:20 +02:00
2021-11-01 13:51:13 +01:00
#' @param x,object values created with [as.mic()], [as.disk()] or [as.rsi()] (or their `random_*` variants, such as [random_mic()])
2021-02-25 10:33:08 +01:00
#' @param mo any (vector of) text that can be coerced to a valid microorganism code with [as.mo()]
2022-11-13 13:44:25 +01:00
#' @param ab any (vector of) text that can be coerced to a valid antimicrobial drug code with [as.ab()]
2021-02-25 10:33:08 +01:00
#' @param guideline interpretation guideline to use, defaults to the latest included EUCAST guideline, see *Details*
2021-07-12 20:24:49 +02:00
#' @param main,title title of the plot
#' @param xlab,ylab axis title
2021-02-25 10:33:08 +01:00
#' @param colours_RSI colours to use for filling in the bars, must be a vector of three values (in the order R, S and I). The default colours are colour-blind friendly.
2021-12-12 09:42:03 +01:00
#' @param language language to be used to translate 'Susceptible', 'Increased exposure'/'Intermediate' and 'Resistant', defaults to system language (see [get_AMR_locale()]) and can be overwritten by setting the option `AMR_locale`, e.g. `options(AMR_locale = "de")`, see [translate]. Use `language = NULL` or `language = ""` to prevent translation.
2021-05-12 18:15:03 +02:00
#' @param expand a [logical] to indicate whether the range on the x axis should be expanded between the lowest and highest value. For MIC values, intermediate values will be factors of 2 starting from the highest MIC value. For disk diameters, the whole diameter range will be filled.
2021-02-25 12:31:12 +01:00
#' @details
#' The interpretation of "I" will be named "Increased exposure" for all EUCAST guidelines since 2019, and will be named "Intermediate" in all other cases.
2022-08-28 10:31:50 +02:00
#'
2021-02-25 12:31:12 +01:00
#' For interpreting MIC values as well as disk diffusion diameters, supported guidelines to be used as input for the `guideline` argument are: `r vector_and(AMR::rsi_translation$guideline, quotes = TRUE, reverse = TRUE)`.
2022-08-28 10:31:50 +02:00
#'
2021-02-25 10:33:08 +01:00
#' Simply using `"CLSI"` or `"EUCAST"` as input will automatically select the latest version of that guideline.
#' @name plot
#' @rdname plot
2021-07-12 20:24:49 +02:00
#' @return The `autoplot()` functions return a [`ggplot`][ggplot2::ggplot()] model that is extendible with any `ggplot2` function.
2022-08-28 10:31:50 +02:00
#'
2021-11-01 13:51:13 +01:00
#' The `fortify()` functions return a [data.frame] as an extension for usage in the [ggplot2::ggplot()] function.
#' @param ... arguments passed on to methods
2022-08-28 10:31:50 +02:00
#' @examples
2021-02-25 10:33:08 +01:00
#' some_mic_values <- random_mic(size = 100)
#' some_disk_values <- random_disk(size = 100, mo = "Escherichia coli", ab = "cipro")
2021-02-26 12:11:29 +01:00
#' some_rsi_values <- random_rsi(50, prob_RSI = c(0.30, 0.55, 0.05))
2022-08-28 10:31:50 +02:00
#'
2021-02-25 10:33:08 +01:00
#' plot(some_mic_values)
#' plot(some_disk_values)
2021-02-26 12:11:29 +01:00
#' plot(some_rsi_values)
2022-08-28 10:31:50 +02:00
#'
2021-02-25 10:33:08 +01:00
#' # when providing the microorganism and antibiotic, colours will show interpretations:
#' plot(some_mic_values, mo = "S. aureus", ab = "ampicillin")
#' plot(some_disk_values, mo = "Escherichia coli", ab = "cipro")
2022-08-21 17:22:34 +02:00
#' plot(some_disk_values, mo = "Escherichia coli", ab = "cipro", language = "uk")
2022-08-28 10:31:50 +02:00
#'
2021-05-24 09:00:11 +02:00
#' \donttest{
2021-02-25 10:33:08 +01:00
#' if (require("ggplot2")) {
2021-07-12 20:24:49 +02:00
#' autoplot(some_mic_values)
2022-08-29 09:35:36 +02:00
#' }
#' if (require("ggplot2")) {
2021-07-12 20:24:49 +02:00
#' autoplot(some_disk_values, mo = "Escherichia coli", ab = "cipro")
2022-08-29 09:35:36 +02:00
#' }
#' if (require("ggplot2")) {
2021-07-12 20:24:49 +02:00
#' autoplot(some_rsi_values)
2021-02-25 10:33:08 +01:00
#' }
2021-05-24 09:00:11 +02:00
#' }
2021-02-25 10:33:08 +01:00
NULL
#' @method plot mic
2021-02-25 12:31:12 +01:00
#' @importFrom graphics barplot axis mtext legend
2021-02-25 10:33:08 +01:00
#' @export
#' @rdname plot
plot.mic <- function ( x ,
mo = NULL ,
ab = NULL ,
guideline = " EUCAST" ,
2022-05-10 21:34:30 +02:00
main = deparse ( substitute ( x ) ) ,
2021-07-12 20:24:49 +02:00
ylab = " Frequency" ,
xlab = " Minimum Inhibitory Concentration (mg/L)" ,
2021-02-25 10:33:08 +01:00
colours_RSI = c ( " #ED553B" , " #3CAEA3" , " #F6D55C" ) ,
2021-12-12 09:42:03 +01:00
language = get_AMR_locale ( ) ,
2021-02-25 10:33:08 +01:00
expand = TRUE ,
... ) {
meet_criteria ( mo , allow_class = c ( " mo" , " character" ) , allow_NULL = TRUE )
meet_criteria ( ab , allow_class = c ( " ab" , " character" ) , allow_NULL = TRUE )
meet_criteria ( guideline , allow_class = " character" , has_length = 1 )
2021-07-12 20:24:49 +02:00
meet_criteria ( main , allow_class = " character" , has_length = 1 , allow_NULL = TRUE )
meet_criteria ( ylab , allow_class = " character" , has_length = 1 )
meet_criteria ( xlab , allow_class = " character" , has_length = 1 )
2021-02-25 10:33:08 +01:00
meet_criteria ( colours_RSI , allow_class = " character" , has_length = c ( 1 , 3 ) )
2022-10-05 09:12:22 +02:00
language <- validate_language ( language )
2021-03-04 23:28:32 +01:00
meet_criteria ( expand , allow_class = " logical" , has_length = 1 )
2022-08-28 10:31:50 +02:00
2021-04-07 08:37:42 +02:00
# translate if not specifically set
if ( missing ( ylab ) ) {
2022-08-19 12:33:14 +02:00
ylab <- translate_into_language ( ylab , language = language )
2021-04-07 08:37:42 +02:00
}
if ( missing ( xlab ) ) {
2022-08-19 12:33:14 +02:00
xlab <- translate_into_language ( xlab , language = language )
2021-04-07 08:37:42 +02:00
}
2022-08-28 10:31:50 +02:00
2021-02-25 10:33:08 +01:00
if ( length ( colours_RSI ) == 1 ) {
colours_RSI <- rep ( colours_RSI , 3 )
}
main <- gsub ( " +" , " " , paste0 ( main , collapse = " " ) )
2022-08-28 10:31:50 +02:00
2021-02-25 10:33:08 +01:00
x <- plot_prepare_table ( x , expand = expand )
2022-08-28 10:31:50 +02:00
cols_sub <- plot_colours_subtitle_guideline (
x = x ,
mo = mo ,
ab = ab ,
guideline = guideline ,
colours_RSI = colours_RSI ,
fn = as.mic ,
language = language ,
...
)
2021-02-25 10:33:08 +01:00
barplot ( x ,
2022-08-28 10:31:50 +02:00
col = cols_sub $ cols ,
main = main ,
ylim = c ( 0 , max ( x ) * ifelse ( any ( colours_RSI %in% cols_sub $ cols ) , 1.1 , 1 ) ) ,
ylab = ylab ,
xlab = xlab ,
axes = FALSE
)
2021-03-07 13:52:39 +01:00
axis ( 2 , seq ( 0 , max ( x ) ) )
2021-02-25 10:33:08 +01:00
if ( ! is.null ( cols_sub $ sub ) ) {
mtext ( side = 3 , line = 0.5 , adj = 0.5 , cex = 0.75 , cols_sub $ sub )
}
2022-08-28 10:31:50 +02:00
2021-02-25 10:33:08 +01:00
if ( any ( colours_RSI %in% cols_sub $ cols ) ) {
legend_txt <- character ( 0 )
legend_col <- character ( 0 )
2021-03-07 13:52:39 +01:00
if ( any ( cols_sub $ cols == colours_RSI [2 ] & cols_sub $ count > 0 ) ) {
2021-02-25 10:33:08 +01:00
legend_txt <- " Susceptible"
legend_col <- colours_RSI [2 ]
}
2021-03-07 13:52:39 +01:00
if ( any ( cols_sub $ cols == colours_RSI [3 ] & cols_sub $ count > 0 ) ) {
2021-02-25 12:31:12 +01:00
legend_txt <- c ( legend_txt , plot_name_of_I ( cols_sub $ guideline ) )
2021-02-25 10:33:08 +01:00
legend_col <- c ( legend_col , colours_RSI [3 ] )
}
2021-03-07 13:52:39 +01:00
if ( any ( cols_sub $ cols == colours_RSI [1 ] & cols_sub $ count > 0 ) ) {
2021-02-25 10:33:08 +01:00
legend_txt <- c ( legend_txt , " Resistant" )
legend_col <- c ( legend_col , colours_RSI [1 ] )
}
2022-08-28 10:31:50 +02:00
2021-04-07 08:37:42 +02:00
legend ( " top" ,
2022-08-28 10:31:50 +02:00
x.intersp = 0.5 ,
legend = translate_into_language ( legend_txt , language = language ) ,
fill = legend_col ,
horiz = TRUE ,
cex = 0.75 ,
box.lwd = 0 ,
box.col = " #FFFFFF55" ,
bg = " #FFFFFF55"
)
2021-02-25 10:33:08 +01:00
}
}
#' @method barplot mic
#' @export
#' @noRd
barplot.mic <- function ( height ,
mo = NULL ,
ab = NULL ,
guideline = " EUCAST" ,
2022-05-10 21:34:30 +02:00
main = deparse ( substitute ( height ) ) ,
2021-07-12 20:24:49 +02:00
ylab = " Frequency" ,
xlab = " Minimum Inhibitory Concentration (mg/L)" ,
2021-02-25 10:33:08 +01:00
colours_RSI = c ( " #ED553B" , " #3CAEA3" , " #F6D55C" ) ,
2021-12-12 09:42:03 +01:00
language = get_AMR_locale ( ) ,
2021-02-25 10:33:08 +01:00
expand = TRUE ,
... ) {
2021-03-04 23:28:32 +01:00
meet_criteria ( main , allow_class = " character" , has_length = 1 , allow_NULL = TRUE )
2021-02-25 10:33:08 +01:00
meet_criteria ( ylab , allow_class = " character" , has_length = 1 )
meet_criteria ( xlab , allow_class = " character" , has_length = 1 )
meet_criteria ( mo , allow_class = c ( " mo" , " character" ) , allow_NULL = TRUE )
meet_criteria ( ab , allow_class = c ( " ab" , " character" ) , allow_NULL = TRUE )
meet_criteria ( guideline , allow_class = " character" , has_length = 1 )
meet_criteria ( colours_RSI , allow_class = " character" , has_length = c ( 1 , 3 ) )
2022-10-05 09:12:22 +02:00
language <- validate_language ( language )
2021-03-04 23:28:32 +01:00
meet_criteria ( expand , allow_class = " logical" , has_length = 1 )
2022-08-28 10:31:50 +02:00
2021-04-07 08:37:42 +02:00
# translate if not specifically set
if ( missing ( ylab ) ) {
2022-08-19 12:33:14 +02:00
ylab <- translate_into_language ( ylab , language = language )
2021-04-07 08:37:42 +02:00
}
if ( missing ( xlab ) ) {
2022-08-19 12:33:14 +02:00
xlab <- translate_into_language ( xlab , language = language )
2021-04-07 08:37:42 +02:00
}
2022-08-28 10:31:50 +02:00
2021-02-25 10:33:08 +01:00
main <- gsub ( " +" , " " , paste0 ( main , collapse = " " ) )
2022-08-28 10:31:50 +02:00
plot (
x = height ,
main = main ,
ylab = ylab ,
xlab = xlab ,
mo = mo ,
ab = ab ,
guideline = guideline ,
colours_RSI = colours_RSI ,
...
)
2021-02-25 10:33:08 +01:00
}
2021-07-12 22:12:28 +02:00
#' @method autoplot mic
2021-02-25 10:33:08 +01:00
#' @rdname plot
# will be exported using s3_register() in R/zzz.R
2021-07-12 20:24:49 +02:00
autoplot.mic <- function ( object ,
mo = NULL ,
ab = NULL ,
guideline = " EUCAST" ,
2022-08-19 12:33:14 +02:00
title = deparse ( substitute ( object ) ) ,
2021-07-12 20:24:49 +02:00
ylab = " Frequency" ,
xlab = " Minimum Inhibitory Concentration (mg/L)" ,
colours_RSI = c ( " #ED553B" , " #3CAEA3" , " #F6D55C" ) ,
2021-12-12 09:42:03 +01:00
language = get_AMR_locale ( ) ,
2021-07-12 20:24:49 +02:00
expand = TRUE ,
... ) {
2021-02-25 10:33:08 +01:00
stop_ifnot_installed ( " ggplot2" )
meet_criteria ( mo , allow_class = c ( " mo" , " character" ) , allow_NULL = TRUE )
meet_criteria ( ab , allow_class = c ( " ab" , " character" ) , allow_NULL = TRUE )
meet_criteria ( guideline , allow_class = " character" , has_length = 1 )
2021-07-12 20:24:49 +02:00
meet_criteria ( title , allow_class = " character" , allow_NULL = TRUE )
meet_criteria ( ylab , allow_class = " character" , has_length = 1 )
meet_criteria ( xlab , allow_class = " character" , has_length = 1 )
2021-02-25 10:33:08 +01:00
meet_criteria ( colours_RSI , allow_class = " character" , has_length = c ( 1 , 3 ) )
2022-10-05 09:12:22 +02:00
language <- validate_language ( language )
2021-03-04 23:28:32 +01:00
meet_criteria ( expand , allow_class = " logical" , has_length = 1 )
2022-08-28 10:31:50 +02:00
2021-04-07 08:37:42 +02:00
# translate if not specifically set
if ( missing ( ylab ) ) {
2022-08-19 12:33:14 +02:00
ylab <- translate_into_language ( ylab , language = language )
2021-04-07 08:37:42 +02:00
}
if ( missing ( xlab ) ) {
2022-08-19 12:33:14 +02:00
xlab <- translate_into_language ( xlab , language = language )
2021-04-07 08:37:42 +02:00
}
2022-08-28 10:31:50 +02:00
2021-03-04 23:28:32 +01:00
if ( " main" %in% names ( list ( ... ) ) ) {
title <- list ( ... ) $ main
}
if ( ! is.null ( title ) ) {
title <- gsub ( " +" , " " , paste0 ( title , collapse = " " ) )
}
2022-08-28 10:31:50 +02:00
2021-07-12 20:24:49 +02:00
x <- plot_prepare_table ( object , expand = expand )
2022-08-28 10:31:50 +02:00
cols_sub <- plot_colours_subtitle_guideline (
x = x ,
mo = mo ,
ab = ab ,
guideline = guideline ,
colours_RSI = colours_RSI ,
fn = as.mic ,
language = language ,
...
)
2021-02-25 10:33:08 +01:00
df <- as.data.frame ( x , stringsAsFactors = TRUE )
colnames ( df ) <- c ( " mic" , " count" )
df $ cols <- cols_sub $ cols
df $ cols [df $ cols == colours_RSI [1 ] ] <- " Resistant"
df $ cols [df $ cols == colours_RSI [2 ] ] <- " Susceptible"
2021-02-25 12:31:12 +01:00
df $ cols [df $ cols == colours_RSI [3 ] ] <- plot_name_of_I ( cols_sub $ guideline )
2022-08-19 12:33:14 +02:00
df $ cols <- factor ( translate_into_language ( df $ cols , language = language ) ,
2022-08-28 10:31:50 +02:00
levels = translate_into_language ( c ( " Susceptible" , plot_name_of_I ( cols_sub $ guideline ) , " Resistant" ) ,
language = language
) ,
ordered = TRUE
)
2021-07-12 20:24:49 +02:00
p <- ggplot2 :: ggplot ( df )
2022-08-28 10:31:50 +02:00
2021-02-25 10:33:08 +01:00
if ( any ( colours_RSI %in% cols_sub $ cols ) ) {
2022-08-28 10:31:50 +02:00
vals <- c (
" Resistant" = colours_RSI [1 ] ,
" Susceptible" = colours_RSI [2 ] ,
" Susceptible, incr. exp." = colours_RSI [3 ] ,
" Intermediate" = colours_RSI [3 ]
)
2022-08-19 12:33:14 +02:00
names ( vals ) <- translate_into_language ( names ( vals ) , language = language )
2021-02-25 10:33:08 +01:00
p <- p +
2022-08-28 10:31:50 +02:00
ggplot2 :: geom_col ( ggplot2 :: aes ( x = mic , y = count , fill = cols ) ) +
2021-07-04 22:10:46 +02:00
# limits = force is needed because of a ggplot2 >= 3.3.4 bug (#4511)
2022-08-28 10:31:50 +02:00
ggplot2 :: scale_fill_manual (
values = vals ,
name = NULL ,
limits = force
)
2021-02-25 10:33:08 +01:00
} else {
p <- p +
2021-02-26 12:11:29 +01:00
ggplot2 :: geom_col ( ggplot2 :: aes ( x = mic , y = count ) )
2021-02-25 10:33:08 +01:00
}
2022-08-28 10:31:50 +02:00
2021-02-25 10:33:08 +01:00
p +
ggplot2 :: labs ( title = title , x = xlab , y = ylab , subtitle = cols_sub $ sub )
}
2021-11-01 13:51:13 +01:00
#' @method fortify mic
#' @rdname plot
# will be exported using s3_register() in R/zzz.R
fortify.mic <- function ( object , ... ) {
2022-08-28 10:31:50 +02:00
stats :: setNames (
as.data.frame ( plot_prepare_table ( object , expand = FALSE ) ) ,
c ( " x" , " y" )
)
2021-11-01 13:51:13 +01:00
}
2021-06-14 22:04:04 +02:00
2021-02-25 10:33:08 +01:00
#' @method plot disk
#' @export
2021-02-25 12:31:12 +01:00
#' @importFrom graphics barplot axis mtext legend
2021-02-25 10:33:08 +01:00
#' @rdname plot
plot.disk <- function ( x ,
2022-05-10 21:34:30 +02:00
main = deparse ( substitute ( x ) ) ,
2021-02-25 10:33:08 +01:00
ylab = " Frequency" ,
xlab = " Disk diffusion diameter (mm)" ,
mo = NULL ,
ab = NULL ,
guideline = " EUCAST" ,
colours_RSI = c ( " #ED553B" , " #3CAEA3" , " #F6D55C" ) ,
2021-12-12 09:42:03 +01:00
language = get_AMR_locale ( ) ,
2021-02-25 10:33:08 +01:00
expand = TRUE ,
... ) {
2021-03-04 23:28:32 +01:00
meet_criteria ( main , allow_class = " character" , has_length = 1 , allow_NULL = TRUE )
2021-02-25 10:33:08 +01:00
meet_criteria ( ylab , allow_class = " character" , has_length = 1 )
meet_criteria ( xlab , allow_class = " character" , has_length = 1 )
meet_criteria ( mo , allow_class = c ( " mo" , " character" ) , allow_NULL = TRUE )
meet_criteria ( ab , allow_class = c ( " ab" , " character" ) , allow_NULL = TRUE )
meet_criteria ( guideline , allow_class = " character" , has_length = 1 )
meet_criteria ( colours_RSI , allow_class = " character" , has_length = c ( 1 , 3 ) )
2022-10-05 09:12:22 +02:00
language <- validate_language ( language )
2021-03-04 23:28:32 +01:00
meet_criteria ( expand , allow_class = " logical" , has_length = 1 )
2022-08-28 10:31:50 +02:00
2021-04-07 08:37:42 +02:00
# translate if not specifically set
if ( missing ( ylab ) ) {
2022-08-19 12:33:14 +02:00
ylab <- translate_into_language ( ylab , language = language )
2021-04-07 08:37:42 +02:00
}
if ( missing ( xlab ) ) {
2022-08-19 12:33:14 +02:00
xlab <- translate_into_language ( xlab , language = language )
2021-04-07 08:37:42 +02:00
}
2022-08-28 10:31:50 +02:00
2021-02-25 10:33:08 +01:00
if ( length ( colours_RSI ) == 1 ) {
colours_RSI <- rep ( colours_RSI , 3 )
}
main <- gsub ( " +" , " " , paste0 ( main , collapse = " " ) )
2022-08-28 10:31:50 +02:00
2021-02-25 10:33:08 +01:00
x <- plot_prepare_table ( x , expand = expand )
2022-08-28 10:31:50 +02:00
cols_sub <- plot_colours_subtitle_guideline (
x = x ,
mo = mo ,
ab = ab ,
guideline = guideline ,
colours_RSI = colours_RSI ,
fn = as.disk ,
language = language ,
...
)
2021-02-25 10:33:08 +01:00
barplot ( x ,
2022-08-28 10:31:50 +02:00
col = cols_sub $ cols ,
main = main ,
ylim = c ( 0 , max ( x ) * ifelse ( any ( colours_RSI %in% cols_sub $ cols ) , 1.1 , 1 ) ) ,
ylab = ylab ,
xlab = xlab ,
axes = FALSE
)
2021-02-25 10:33:08 +01:00
axis ( 2 , seq ( 0 , max ( x ) ) )
if ( ! is.null ( cols_sub $ sub ) ) {
mtext ( side = 3 , line = 0.5 , adj = 0.5 , cex = 0.75 , cols_sub $ sub )
}
2022-08-28 10:31:50 +02:00
2021-02-25 10:33:08 +01:00
if ( any ( colours_RSI %in% cols_sub $ cols ) ) {
legend_txt <- character ( 0 )
legend_col <- character ( 0 )
2021-03-07 13:52:39 +01:00
if ( any ( cols_sub $ cols == colours_RSI [1 ] & cols_sub $ count > 0 ) ) {
2021-02-25 10:33:08 +01:00
legend_txt <- " Resistant"
legend_col <- colours_RSI [1 ]
}
2021-03-07 13:52:39 +01:00
if ( any ( cols_sub $ cols == colours_RSI [3 ] & cols_sub $ count > 0 ) ) {
2021-02-25 12:31:12 +01:00
legend_txt <- c ( legend_txt , plot_name_of_I ( cols_sub $ guideline ) )
2021-02-25 10:33:08 +01:00
legend_col <- c ( legend_col , colours_RSI [3 ] )
}
2021-03-07 13:52:39 +01:00
if ( any ( cols_sub $ cols == colours_RSI [2 ] & cols_sub $ count > 0 ) ) {
2021-02-25 10:33:08 +01:00
legend_txt <- c ( legend_txt , " Susceptible" )
legend_col <- c ( legend_col , colours_RSI [2 ] )
}
2022-08-28 10:31:50 +02:00
legend ( " top" ,
x.intersp = 0.5 ,
legend = translate_into_language ( legend_txt , language = language ) ,
fill = legend_col ,
horiz = TRUE ,
cex = 0.75 ,
box.lwd = 0 ,
box.col = " #FFFFFF55" ,
bg = " #FFFFFF55"
)
2021-02-25 10:33:08 +01:00
}
}
#' @method barplot disk
#' @export
#' @noRd
barplot.disk <- function ( height ,
2022-05-10 21:34:30 +02:00
main = deparse ( substitute ( height ) ) ,
2021-02-25 10:33:08 +01:00
ylab = " Frequency" ,
xlab = " Disk diffusion diameter (mm)" ,
mo = NULL ,
ab = NULL ,
guideline = " EUCAST" ,
colours_RSI = c ( " #ED553B" , " #3CAEA3" , " #F6D55C" ) ,
2021-12-12 09:42:03 +01:00
language = get_AMR_locale ( ) ,
2021-02-25 10:33:08 +01:00
expand = TRUE ,
... ) {
2021-03-04 23:28:32 +01:00
meet_criteria ( main , allow_class = " character" , has_length = 1 , allow_NULL = TRUE )
2021-02-25 10:33:08 +01:00
meet_criteria ( ylab , allow_class = " character" , has_length = 1 )
meet_criteria ( xlab , allow_class = " character" , has_length = 1 )
meet_criteria ( mo , allow_class = c ( " mo" , " character" ) , allow_NULL = TRUE )
meet_criteria ( ab , allow_class = c ( " ab" , " character" ) , allow_NULL = TRUE )
meet_criteria ( guideline , allow_class = " character" , has_length = 1 )
meet_criteria ( colours_RSI , allow_class = " character" , has_length = c ( 1 , 3 ) )
2022-10-05 09:12:22 +02:00
language <- validate_language ( language )
2021-03-04 23:28:32 +01:00
meet_criteria ( expand , allow_class = " logical" , has_length = 1 )
2022-08-28 10:31:50 +02:00
2021-04-07 08:37:42 +02:00
# translate if not specifically set
if ( missing ( ylab ) ) {
2022-08-19 12:33:14 +02:00
ylab <- translate_into_language ( ylab , language = language )
2021-04-07 08:37:42 +02:00
}
if ( missing ( xlab ) ) {
2022-08-19 12:33:14 +02:00
xlab <- translate_into_language ( xlab , language = language )
2021-04-07 08:37:42 +02:00
}
2022-08-28 10:31:50 +02:00
2021-02-25 10:33:08 +01:00
main <- gsub ( " +" , " " , paste0 ( main , collapse = " " ) )
2022-08-28 10:31:50 +02:00
plot (
x = height ,
main = main ,
ylab = ylab ,
xlab = xlab ,
mo = mo ,
ab = ab ,
guideline = guideline ,
colours_RSI = colours_RSI ,
...
)
2021-02-25 10:33:08 +01:00
}
2021-07-12 20:24:49 +02:00
#' @method autoplot disk
2021-02-25 10:33:08 +01:00
#' @rdname plot
# will be exported using s3_register() in R/zzz.R
2021-07-12 20:24:49 +02:00
autoplot.disk <- function ( object ,
mo = NULL ,
ab = NULL ,
2022-08-19 12:33:14 +02:00
title = deparse ( substitute ( object ) ) ,
2021-07-12 20:24:49 +02:00
ylab = " Frequency" ,
xlab = " Disk diffusion diameter (mm)" ,
guideline = " EUCAST" ,
colours_RSI = c ( " #ED553B" , " #3CAEA3" , " #F6D55C" ) ,
2021-12-12 09:42:03 +01:00
language = get_AMR_locale ( ) ,
2021-07-12 20:24:49 +02:00
expand = TRUE ,
... ) {
2021-02-25 10:33:08 +01:00
stop_ifnot_installed ( " ggplot2" )
2021-03-04 23:28:32 +01:00
meet_criteria ( title , allow_class = " character" , allow_NULL = TRUE )
2021-02-25 10:33:08 +01:00
meet_criteria ( ylab , allow_class = " character" , has_length = 1 )
meet_criteria ( xlab , allow_class = " character" , has_length = 1 )
meet_criteria ( mo , allow_class = c ( " mo" , " character" ) , allow_NULL = TRUE )
meet_criteria ( ab , allow_class = c ( " ab" , " character" ) , allow_NULL = TRUE )
meet_criteria ( guideline , allow_class = " character" , has_length = 1 )
meet_criteria ( colours_RSI , allow_class = " character" , has_length = c ( 1 , 3 ) )
2022-10-05 09:12:22 +02:00
language <- validate_language ( language )
2021-03-04 23:28:32 +01:00
meet_criteria ( expand , allow_class = " logical" , has_length = 1 )
2022-08-28 10:31:50 +02:00
2021-04-07 08:37:42 +02:00
# translate if not specifically set
if ( missing ( ylab ) ) {
2022-08-19 12:33:14 +02:00
ylab <- translate_into_language ( ylab , language = language )
2021-04-07 08:37:42 +02:00
}
if ( missing ( xlab ) ) {
2022-08-19 12:33:14 +02:00
xlab <- translate_into_language ( xlab , language = language )
2021-04-07 08:37:42 +02:00
}
2022-08-28 10:31:50 +02:00
2021-03-04 23:28:32 +01:00
if ( " main" %in% names ( list ( ... ) ) ) {
title <- list ( ... ) $ main
}
if ( ! is.null ( title ) ) {
title <- gsub ( " +" , " " , paste0 ( title , collapse = " " ) )
}
2022-08-28 10:31:50 +02:00
2021-07-12 20:24:49 +02:00
x <- plot_prepare_table ( object , expand = expand )
2022-08-28 10:31:50 +02:00
cols_sub <- plot_colours_subtitle_guideline (
x = x ,
mo = mo ,
ab = ab ,
guideline = guideline ,
colours_RSI = colours_RSI ,
fn = as.disk ,
language = language ,
...
)
2021-02-25 10:33:08 +01:00
df <- as.data.frame ( x , stringsAsFactors = TRUE )
colnames ( df ) <- c ( " disk" , " count" )
df $ cols <- cols_sub $ cols
2022-08-28 10:31:50 +02:00
2021-02-25 10:33:08 +01:00
df $ cols [df $ cols == colours_RSI [1 ] ] <- " Resistant"
df $ cols [df $ cols == colours_RSI [2 ] ] <- " Susceptible"
2021-02-25 12:31:12 +01:00
df $ cols [df $ cols == colours_RSI [3 ] ] <- plot_name_of_I ( cols_sub $ guideline )
2022-08-19 12:33:14 +02:00
df $ cols <- factor ( translate_into_language ( df $ cols , language = language ) ,
2022-08-28 10:31:50 +02:00
levels = translate_into_language ( c ( " Susceptible" , plot_name_of_I ( cols_sub $ guideline ) , " Resistant" ) ,
language = language
) ,
ordered = TRUE
)
2021-07-12 20:24:49 +02:00
p <- ggplot2 :: ggplot ( df )
2022-08-28 10:31:50 +02:00
2021-02-25 10:33:08 +01:00
if ( any ( colours_RSI %in% cols_sub $ cols ) ) {
2022-08-28 10:31:50 +02:00
vals <- c (
" Resistant" = colours_RSI [1 ] ,
" Susceptible" = colours_RSI [2 ] ,
" Susceptible, incr. exp." = colours_RSI [3 ] ,
" Intermediate" = colours_RSI [3 ]
)
2022-08-19 12:33:14 +02:00
names ( vals ) <- translate_into_language ( names ( vals ) , language = language )
2021-02-25 10:33:08 +01:00
p <- p +
2022-08-28 10:31:50 +02:00
ggplot2 :: geom_col ( ggplot2 :: aes ( x = disk , y = count , fill = cols ) ) +
2021-07-04 22:10:46 +02:00
# limits = force is needed because of a ggplot2 >= 3.3.4 bug (#4511)
2022-08-28 10:31:50 +02:00
ggplot2 :: scale_fill_manual (
values = vals ,
name = NULL ,
limits = force
)
2021-02-25 10:33:08 +01:00
} else {
p <- p +
2021-02-26 12:11:29 +01:00
ggplot2 :: geom_col ( ggplot2 :: aes ( x = disk , y = count ) )
2021-02-25 10:33:08 +01:00
}
2022-08-28 10:31:50 +02:00
2021-02-25 10:33:08 +01:00
p +
2021-02-25 12:31:12 +01:00
ggplot2 :: labs ( title = title , x = xlab , y = ylab , subtitle = cols_sub $ sub )
2021-02-25 10:33:08 +01:00
}
2021-11-01 13:51:13 +01:00
#' @method fortify disk
#' @rdname plot
# will be exported using s3_register() in R/zzz.R
fortify.disk <- function ( object , ... ) {
2022-08-28 10:31:50 +02:00
stats :: setNames (
as.data.frame ( plot_prepare_table ( object , expand = FALSE ) ) ,
c ( " x" , " y" )
)
2021-11-01 13:51:13 +01:00
}
2021-02-25 10:33:08 +01:00
#' @method plot rsi
#' @export
#' @importFrom graphics plot text axis
#' @rdname plot
plot.rsi <- function ( x ,
ylab = " Percentage" ,
xlab = " Antimicrobial Interpretation" ,
2022-05-10 21:34:30 +02:00
main = deparse ( substitute ( x ) ) ,
2022-08-19 12:33:14 +02:00
language = get_AMR_locale ( ) ,
2021-02-25 10:33:08 +01:00
... ) {
meet_criteria ( ylab , allow_class = " character" , has_length = 1 )
meet_criteria ( xlab , allow_class = " character" , has_length = 1 )
2021-03-04 23:28:32 +01:00
meet_criteria ( main , allow_class = " character" , has_length = 1 , allow_NULL = TRUE )
2022-08-28 10:31:50 +02:00
2022-08-19 12:33:14 +02:00
# translate if not specifically set
if ( missing ( ylab ) ) {
ylab <- translate_into_language ( ylab , language = language )
}
if ( missing ( xlab ) ) {
xlab <- translate_into_language ( xlab , language = language )
}
2022-08-28 10:31:50 +02:00
2021-02-25 10:33:08 +01:00
data <- as.data.frame ( table ( x ) , stringsAsFactors = FALSE )
colnames ( data ) <- c ( " x" , " n" )
data $ s <- round ( ( data $ n / sum ( data $ n ) ) * 100 , 1 )
2022-08-28 10:31:50 +02:00
2021-02-25 10:33:08 +01:00
if ( ! " S" %in% data $ x ) {
data <- rbind ( data , data.frame ( x = " S" , n = 0 , s = 0 , stringsAsFactors = FALSE ) ,
2022-08-28 10:31:50 +02:00
stringsAsFactors = FALSE
)
2021-02-25 10:33:08 +01:00
}
if ( ! " I" %in% data $ x ) {
data <- rbind ( data , data.frame ( x = " I" , n = 0 , s = 0 , stringsAsFactors = FALSE ) ,
2022-08-28 10:31:50 +02:00
stringsAsFactors = FALSE
)
2021-02-25 10:33:08 +01:00
}
if ( ! " R" %in% data $ x ) {
data <- rbind ( data , data.frame ( x = " R" , n = 0 , s = 0 , stringsAsFactors = FALSE ) ,
2022-08-28 10:31:50 +02:00
stringsAsFactors = FALSE
)
2021-02-25 10:33:08 +01:00
}
2022-08-28 10:31:50 +02:00
2021-02-26 12:11:29 +01:00
data $ x <- factor ( data $ x , levels = c ( " S" , " I" , " R" ) , ordered = TRUE )
2022-08-28 10:31:50 +02:00
2021-02-25 10:33:08 +01:00
ymax <- pm_if_else ( max ( data $ s ) > 95 , 105 , 100 )
2022-08-28 10:31:50 +02:00
plot (
x = data $ x ,
y = data $ s ,
lwd = 2 ,
ylim = c ( 0 , ymax ) ,
ylab = ylab ,
xlab = xlab ,
main = main ,
axes = FALSE
)
2021-02-25 10:33:08 +01:00
# x axis
axis ( side = 1 , at = 1 : pm_n_distinct ( data $ x ) , labels = levels ( data $ x ) , lwd = 0 )
# y axis, 0-100%
axis ( side = 2 , at = seq ( 0 , 100 , 5 ) )
2022-08-28 10:31:50 +02:00
text (
x = data $ x ,
y = data $ s + 4 ,
labels = paste0 ( data $ s , " % (n = " , data $ n , " )" )
)
2021-02-25 10:33:08 +01:00
}
#' @method barplot rsi
#' @importFrom graphics barplot axis
#' @export
#' @noRd
barplot.rsi <- function ( height ,
2022-05-10 21:34:30 +02:00
main = deparse ( substitute ( height ) ) ,
2021-02-25 10:33:08 +01:00
xlab = " Antimicrobial Interpretation" ,
ylab = " Frequency" ,
colours_RSI = c ( " #ED553B" , " #3CAEA3" , " #F6D55C" ) ,
2021-12-12 09:42:03 +01:00
language = get_AMR_locale ( ) ,
2021-02-25 10:33:08 +01:00
expand = TRUE ,
... ) {
meet_criteria ( xlab , allow_class = " character" , has_length = 1 )
2021-03-04 23:28:32 +01:00
meet_criteria ( main , allow_class = " character" , has_length = 1 , allow_NULL = TRUE )
2021-02-25 10:33:08 +01:00
meet_criteria ( ylab , allow_class = " character" , has_length = 1 )
meet_criteria ( colours_RSI , allow_class = " character" , has_length = c ( 1 , 3 ) )
2022-10-05 09:12:22 +02:00
language <- validate_language ( language )
2021-03-04 23:28:32 +01:00
meet_criteria ( expand , allow_class = " logical" , has_length = 1 )
2022-08-28 10:31:50 +02:00
2021-04-07 08:37:42 +02:00
# translate if not specifically set
if ( missing ( ylab ) ) {
2022-08-19 12:33:14 +02:00
ylab <- translate_into_language ( ylab , language = language )
2021-04-07 08:37:42 +02:00
}
if ( missing ( xlab ) ) {
2022-08-19 12:33:14 +02:00
xlab <- translate_into_language ( xlab , language = language )
2021-04-07 08:37:42 +02:00
}
2022-08-28 10:31:50 +02:00
2021-02-25 10:33:08 +01:00
if ( length ( colours_RSI ) == 1 ) {
colours_RSI <- rep ( colours_RSI , 3 )
2021-04-30 13:18:48 +02:00
} else {
colours_RSI <- c ( colours_RSI [2 ] , colours_RSI [3 ] , colours_RSI [1 ] )
2021-02-25 10:33:08 +01:00
}
main <- gsub ( " +" , " " , paste0 ( main , collapse = " " ) )
2022-08-28 10:31:50 +02:00
2021-02-25 10:33:08 +01:00
x <- table ( height )
2021-02-26 12:11:29 +01:00
x <- x [c ( 1 , 2 , 3 ) ]
2021-02-25 10:33:08 +01:00
barplot ( x ,
2022-08-28 10:31:50 +02:00
col = colours_RSI ,
xlab = xlab ,
main = main ,
ylab = ylab ,
axes = FALSE
)
2021-02-25 10:33:08 +01:00
axis ( 2 , seq ( 0 , max ( x ) ) )
}
2021-02-26 12:11:29 +01:00
2021-07-12 20:24:49 +02:00
#' @method autoplot rsi
2021-02-26 12:11:29 +01:00
#' @rdname plot
# will be exported using s3_register() in R/zzz.R
2021-07-12 20:24:49 +02:00
autoplot.rsi <- function ( object ,
2022-08-19 12:33:14 +02:00
title = deparse ( substitute ( object ) ) ,
2021-07-12 20:24:49 +02:00
xlab = " Antimicrobial Interpretation" ,
ylab = " Frequency" ,
colours_RSI = c ( " #ED553B" , " #3CAEA3" , " #F6D55C" ) ,
2021-12-12 09:42:03 +01:00
language = get_AMR_locale ( ) ,
2021-07-12 20:24:49 +02:00
... ) {
2021-02-26 12:11:29 +01:00
stop_ifnot_installed ( " ggplot2" )
2021-03-04 23:28:32 +01:00
meet_criteria ( title , allow_class = " character" , allow_NULL = TRUE )
2021-02-26 12:11:29 +01:00
meet_criteria ( ylab , allow_class = " character" , has_length = 1 )
meet_criteria ( xlab , allow_class = " character" , has_length = 1 )
meet_criteria ( colours_RSI , allow_class = " character" , has_length = c ( 1 , 3 ) )
2022-08-28 10:31:50 +02:00
2021-04-07 08:37:42 +02:00
# translate if not specifically set
if ( missing ( ylab ) ) {
2022-08-19 12:33:14 +02:00
ylab <- translate_into_language ( ylab , language = language )
2021-04-07 08:37:42 +02:00
}
if ( missing ( xlab ) ) {
2022-08-19 12:33:14 +02:00
xlab <- translate_into_language ( xlab , language = language )
2021-04-07 08:37:42 +02:00
}
2022-08-28 10:31:50 +02:00
2021-03-04 23:28:32 +01:00
if ( " main" %in% names ( list ( ... ) ) ) {
title <- list ( ... ) $ main
}
if ( ! is.null ( title ) ) {
title <- gsub ( " +" , " " , paste0 ( title , collapse = " " ) )
}
2022-08-28 10:31:50 +02:00
2021-02-26 12:11:29 +01:00
if ( length ( colours_RSI ) == 1 ) {
colours_RSI <- rep ( colours_RSI , 3 )
}
2022-08-28 10:31:50 +02:00
2021-07-12 20:24:49 +02:00
df <- as.data.frame ( table ( object ) , stringsAsFactors = TRUE )
2021-02-26 12:11:29 +01:00
colnames ( df ) <- c ( " rsi" , " count" )
2021-07-12 20:24:49 +02:00
ggplot2 :: ggplot ( df ) +
2022-08-28 10:31:50 +02:00
ggplot2 :: geom_col ( ggplot2 :: aes ( x = rsi , y = count , fill = rsi ) ) +
2021-07-04 22:10:46 +02:00
# limits = force is needed because of a ggplot2 >= 3.3.4 bug (#4511)
2022-08-28 10:31:50 +02:00
ggplot2 :: scale_fill_manual (
values = c (
" R" = colours_RSI [1 ] ,
" S" = colours_RSI [2 ] ,
" I" = colours_RSI [3 ]
) ,
limits = force
) +
2021-02-26 12:11:29 +01:00
ggplot2 :: labs ( title = title , x = xlab , y = ylab ) +
ggplot2 :: theme ( legend.position = " none" )
}
2021-04-07 08:37:42 +02:00
2021-11-01 13:51:13 +01:00
#' @method fortify rsi
#' @rdname plot
# will be exported using s3_register() in R/zzz.R
fortify.rsi <- function ( object , ... ) {
2022-08-28 10:31:50 +02:00
stats :: setNames (
as.data.frame ( table ( object ) ) ,
c ( " x" , " y" )
)
2021-11-01 13:51:13 +01:00
}
2021-04-07 08:37:42 +02:00
plot_prepare_table <- function ( x , expand ) {
2021-05-12 18:15:03 +02:00
x <- x [ ! is.na ( x ) ]
stop_if ( length ( x ) == 0 , " no observations to plot" , call = FALSE )
2021-04-07 08:37:42 +02:00
if ( is.mic ( x ) ) {
if ( expand == TRUE ) {
# expand range for MIC by adding factors of 2 from lowest to highest so all MICs in between also print
2021-07-12 12:28:41 +02:00
valid_lvls <- levels ( x )
2021-04-07 08:37:42 +02:00
extra_range <- max ( x ) / 2
while ( min ( extra_range ) / 2 > min ( x ) ) {
extra_range <- c ( min ( extra_range ) / 2 , extra_range )
}
nms <- extra_range
extra_range <- rep ( 0 , length ( extra_range ) )
names ( extra_range ) <- nms
x <- table ( droplevels ( x , as.mic = FALSE ) )
2021-07-12 12:28:41 +02:00
extra_range <- extra_range [ ! names ( extra_range ) %in% names ( x ) & names ( extra_range ) %in% valid_lvls ]
2021-04-07 08:37:42 +02:00
x <- as.table ( c ( x , extra_range ) )
} else {
x <- table ( droplevels ( x , as.mic = FALSE ) )
}
x <- x [order ( as.double ( as.mic ( names ( x ) ) ) ) ]
} else if ( is.disk ( x ) ) {
if ( expand == TRUE ) {
# expand range for disks from lowest to highest so all mm's in between also print
extra_range <- rep ( 0 , max ( x ) - min ( x ) - 1 )
names ( extra_range ) <- seq ( min ( x ) + 1 , max ( x ) - 1 )
x <- table ( x )
extra_range <- extra_range [ ! names ( extra_range ) %in% names ( x ) ]
x <- as.table ( c ( x , extra_range ) )
} else {
x <- table ( x )
}
x <- x [order ( as.double ( names ( x ) ) ) ]
}
as.table ( x )
}
plot_name_of_I <- function ( guideline ) {
2021-04-23 09:59:36 +02:00
if ( guideline %unlike% " CLSI" && as.double ( gsub ( " [^0-9]+" , " " , guideline ) ) >= 2019 ) {
2021-04-07 08:37:42 +02:00
# interpretation since 2019
2021-07-23 21:42:11 +02:00
" Susceptible, incr. exp."
2021-04-07 08:37:42 +02:00
} else {
# interpretation until 2019
" Intermediate"
}
}
plot_colours_subtitle_guideline <- function ( x , mo , ab , guideline , colours_RSI , fn , language , ... ) {
guideline <- get_guideline ( guideline , AMR :: rsi_translation )
if ( ! is.null ( mo ) && ! is.null ( ab ) ) {
# interpret and give colour based on MIC values
mo <- as.mo ( mo )
ab <- as.ab ( ab )
rsi <- suppressWarnings ( suppressMessages ( as.rsi ( fn ( names ( x ) ) , mo = mo , ab = ab , guideline = guideline , ... ) ) )
cols <- character ( length = length ( rsi ) )
cols [is.na ( rsi ) ] <- " #BEBEBE"
cols [rsi == " R" ] <- colours_RSI [1 ]
cols [rsi == " S" ] <- colours_RSI [2 ]
cols [rsi == " I" ] <- colours_RSI [3 ]
moname <- mo_name ( mo , language = language )
abname <- ab_name ( ab , language = language )
if ( all ( cols == " #BEBEBE" ) ) {
2022-08-28 10:31:50 +02:00
message_ (
" No " , guideline , " interpretations found for " ,
ab_name ( ab , language = NULL , tolower = TRUE ) , " in " , moname
)
2021-04-07 08:37:42 +02:00
guideline_txt <- " "
} else {
2022-05-10 21:34:30 +02:00
guideline_txt <- guideline
if ( isTRUE ( list ( ... ) $ uti ) ) {
guideline_txt <- paste ( " UTIs," , guideline_txt )
}
guideline_txt <- paste0 ( " (" , guideline_txt , " )" )
2021-04-07 08:37:42 +02:00
}
2022-08-28 10:31:50 +02:00
sub <- bquote ( .(abname ) ~ " -" ~ italic ( .(moname ) ) ~ .(guideline_txt ) )
2021-04-07 08:37:42 +02:00
} else {
cols <- " #BEBEBE"
sub <- NULL
}
list ( cols = cols , count = as.double ( x ) , sub = sub , guideline = guideline )
}