mirror of
https://github.com/msberends/AMR.git
synced 2026-11-15 22:20:47 +01:00
(v3.1.0.9021) Show the number of tested isolates on susceptible-only bars, and split ggplot_sir() by antimicrobial if it is not shown in the plot
This commit is contained in:
1 parent
035c7e7871
commit
49a0f37713
6 files changed
+52
-11
No files matched your search
+1
-1
@@ -1,5 +1,5 @@
|
||||
Package: AMR
|
||||
Version: 3.1.0.9020
|
||||
Version: 3.1.0.9021
|
||||
Date: 2026-11-09
|
||||
Title: Antimicrobial Resistance Data Analysis
|
||||
Description: Functions to simplify and standardise antimicrobial resistance (AMR)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# AMR 3.1.0.9020
|
||||
# AMR 3.1.0.9021
|
||||
|
||||
This version fixes a critical bug in WISCA that biased all coverage estimates of `wisca()` and `antibiogram(..., wisca = TRUE)` downwards since AMR 3.0.0. Users are strongly advised to re-run their WISCA analyses.
|
||||
|
||||
@@ -21,7 +21,8 @@ This version fixes a critical bug in WISCA that biased all coverage estimates of
|
||||
* Taxonomic names are now looked up once per session, making the function considerably faster for long vectors
|
||||
* `ggplot_sir()`, `geom_sir()` and `labels_sir_count()`
|
||||
* Fixed the data labels being placed on the wrong bars with `position = "dodge"` or `position = "stack"`. They are now grouped like the bars, using the new `fill` argument of `labels_sir_count()`, which `ggplot_sir()` sets automatically
|
||||
* If the interpretation is not shown in the plot, e.g., with `fill = "species"`, only the susceptible proportion is now plotted, following the guideline: S+SDD+I for EUCAST, S+SDD for CLSI, and S with `guideline = NULL`. Previously, the bars of all interpretations were drawn on top of each other. The y axis title of `ggplot_sir()` then states the category, e.g., "Proportion SI"
|
||||
* If the interpretation is not shown in the plot, e.g., with `fill = "species"`, only the susceptible proportion is now plotted, following the guideline: S+SDD+I for EUCAST, S+SDD for CLSI, and S with `guideline = NULL`. Previously, the bars of all interpretations were drawn on top of each other. The y axis title of `ggplot_sir()` then states the category, e.g., "Proportion SI", and the data labels show the number of tested isolates
|
||||
* `ggplot_sir()` now splits the plot by antimicrobial if there is more than one and the antimicrobial is not shown in the plot, e.g., with `x = "species"`, as their bars were previously stacked on top of each other. This uses `facet = "antibiotic"` if `facet` is not set, and otherwise a grid of `facet` by antimicrobial
|
||||
* `ggplot_pca()`
|
||||
* Fixed an error when setting `groups` together with `labels`, and setting `groups` without `labels` now colours the points by these groups instead of using them as labels, as documented
|
||||
* WISCA (`wisca()` and `antibiogram(..., wisca = TRUE)`)
|
||||
|
||||
+29
-6
@@ -36,7 +36,7 @@
|
||||
#' @param fill Variable to categorise using the plots legend, either `"interpretation"` (default) or `"antibiotic"` or a grouping variable. For [labels_sir_count()], this must be the same as the `fill` of [geom_sir()], so that the labels are placed on the right bars. If the interpretation is not shown in the plot (i.e., neither in `x`, `fill`, nor `facet`), only the susceptible proportion is plotted, which follows the guideline (see `guideline`): S+SDD+I for EUCAST, S+SDD for CLSI, and S if `guideline = NULL`.
|
||||
#' @param breaks A [numeric] vector of positions.
|
||||
#' @param limits A [numeric] vector of length two providing limits of the scale, use `NA` to refer to the existing minimum or maximum.
|
||||
#' @param facet Variable to split plots by, either `"interpretation"` (default) or `"antibiotic"` or a grouping variable.
|
||||
#' @param facet Variable to split plots by, either `"interpretation"` or `"antibiotic"` or a grouping variable. If there is more than one antimicrobial and the antimicrobial is not shown in the plot (i.e., neither in `x`, `fill`, nor `facet`), [ggplot_sir()] splits the plot by antimicrobial, as their bars would otherwise be stacked: using `facet = "antibiotic"` if `facet` is not set, and otherwise using a grid of `facet` by antimicrobial. Note that [geom_sir()] cannot do this, so add [facet_sir()] in that case.
|
||||
#' @inheritParams proportion
|
||||
#' @param nrow (when using `facet`) number of rows.
|
||||
#' @param colours A named vactor with colour to be used for filling. The default colours are colour-blind friendly.
|
||||
@@ -240,6 +240,21 @@ ggplot_sir <- function(data,
|
||||
position <- "fill"
|
||||
}
|
||||
|
||||
plot_df <- tryCatch(
|
||||
sir_df(data = data, translate_ab = translate_ab, language = language, minimum = minimum, guideline = guideline),
|
||||
error = function(e) NULL
|
||||
)
|
||||
shown <- c(normalise_sir_plot_var(x), normalise_sir_plot_var(fill), normalise_sir_plot_var(facet))
|
||||
facet_grid_ab <- FALSE
|
||||
if (!is.null(plot_df) && length(unique(plot_df$antibiotic)) > 1 && !"antibiotic" %in% shown) {
|
||||
# the antibiotic is not shown, so the bars of all antibiotics would be stacked; split the plot by antibiotic
|
||||
if (is.null(facet)) {
|
||||
facet <- "antibiotic"
|
||||
} else {
|
||||
facet_grid_ab <- TRUE
|
||||
}
|
||||
}
|
||||
|
||||
p <- ggplot2::ggplot(data = data) +
|
||||
create_geom_sir(
|
||||
position = position, x = x, fill = fill, facet = facet, translate_ab = translate_ab,
|
||||
@@ -280,17 +295,21 @@ ggplot_sir <- function(data,
|
||||
p <- p + ggplot2::scale_fill_discrete(labels = labels_taxonomy)
|
||||
}
|
||||
|
||||
if (!is.null(facet)) {
|
||||
if (isTRUE(facet_grid_ab)) {
|
||||
# a grid of the set facet by antibiotic
|
||||
p <- p + ggplot2::facet_grid(
|
||||
stats::as.formula(paste0("`", normalise_sir_plot_var(facet), "` ~ antibiotic")),
|
||||
scales = "free_x",
|
||||
labeller = labeller_taxonomy
|
||||
)
|
||||
} else if (!is.null(facet)) {
|
||||
# pass the value, as facet_sir() takes an unquoted name as column name
|
||||
p <- p + do.call(facet_sir, list(facet = facet, nrow = nrow))
|
||||
}
|
||||
|
||||
if (missing(y.title) && !"interpretation" %in% c(normalise_sir_plot_var(x), normalise_sir_plot_var(fill), normalise_sir_plot_var(facet))) {
|
||||
# only the susceptible proportion is shown, e.g. "Proportion SI" for EUCAST
|
||||
susceptible <- tryCatch(
|
||||
levels(sir_df(data = data, translate_ab = translate_ab, language = language, minimum = minimum, guideline = guideline)$interpretation)[1],
|
||||
error = function(e) NULL
|
||||
)
|
||||
susceptible <- if (is.null(plot_df)) NULL else levels(plot_df$interpretation)[1]
|
||||
if (!is.null(susceptible)) {
|
||||
y.title <- paste(y.title, susceptible)
|
||||
}
|
||||
@@ -389,6 +408,10 @@ sir_plot_data <- function(data, x, fill, facet, translate_ab, minimum, language,
|
||||
# the interpretation is not shown, so the bars of all interpretations would overlap;
|
||||
# keep only the susceptible proportion, which is the first level and follows the guideline:
|
||||
# S+SDD+I ("SI") for EUCAST, S+SDD ("S") for CLSI, and S for guideline = NULL
|
||||
# the number of isolates of the data labels then becomes the number of tested isolates
|
||||
keys <- do.call(paste, c(out[, setdiff(colnames(out), c("interpretation", "value", "ci_min", "ci_max", "isolates")), drop = FALSE], sep = "\r"))
|
||||
totals <- tapply(out$isolates, keys, sum)
|
||||
out$isolates <- as.integer(totals[keys])
|
||||
out <- out[which(as.character(out$interpretation) == levels(out$interpretation)[1]), , drop = FALSE]
|
||||
}
|
||||
out
|
||||
|
||||
+1
-1
@@ -67,7 +67,7 @@ labels_sir_count(
|
||||
|
||||
\item{fill}{Variable to categorise using the plots legend, either \code{"interpretation"} (default) or \code{"antibiotic"} or a grouping variable. For \code{\link[=labels_sir_count]{labels_sir_count()}}, this must be the same as the \code{fill} of \code{\link[=geom_sir]{geom_sir()}}, so that the labels are placed on the right bars. If the interpretation is not shown in the plot (i.e., neither in \code{x}, \code{fill}, nor \code{facet}), only the susceptible proportion is plotted, which follows the guideline (see \code{guideline}): S+SDD+I for EUCAST, S+SDD for CLSI, and S if \code{guideline = NULL}.}
|
||||
|
||||
\item{facet}{Variable to split plots by, either \code{"interpretation"} (default) or \code{"antibiotic"} or a grouping variable.}
|
||||
\item{facet}{Variable to split plots by, either \code{"interpretation"} or \code{"antibiotic"} or a grouping variable. If there is more than one antimicrobial and the antimicrobial is not shown in the plot (i.e., neither in \code{x}, \code{fill}, nor \code{facet}), \code{\link[=ggplot_sir]{ggplot_sir()}} splits the plot by antimicrobial, as their bars would otherwise be stacked: using \code{facet = "antibiotic"} if \code{facet} is not set, and otherwise using a grid of \code{facet} by antimicrobial. Note that \code{\link[=geom_sir]{geom_sir()}} cannot do this, so add \code{\link[=facet_sir]{facet_sir()}} in that case.}
|
||||
|
||||
\item{breaks}{A \link{numeric} vector of positions.}
|
||||
|
||||
|
||||
+1
-1
@@ -185,7 +185,7 @@ labels_taxonomy(x, ...)
|
||||
|
||||
\item{breakpoint_type}{The type of breakpoints to use, either \code{"ECOFF"}, \code{"animal"}, or \code{"human"}. ECOFF stands for Epidemiological Cut-Off values. The default is \code{"human"}, which can also be set with the package option \code{\link[=AMR-options]{AMR_breakpoint_type}}. If \code{host} is set to values of veterinary species, this will automatically be set to \code{"animal"}.}
|
||||
|
||||
\item{facet}{Variable to split plots by, either \code{"interpretation"} (default) or \code{"antibiotic"} or a grouping variable.}
|
||||
\item{facet}{Variable to split plots by, either \code{"interpretation"} or \code{"antibiotic"} or a grouping variable. If there is more than one antimicrobial and the antimicrobial is not shown in the plot (i.e., neither in \code{x}, \code{fill}, nor \code{facet}), \code{\link[=ggplot_sir]{ggplot_sir()}} splits the plot by antimicrobial, as their bars would otherwise be stacked: using \code{facet = "antibiotic"} if \code{facet} is not set, and otherwise using a grid of \code{facet} by antimicrobial. Note that \code{\link[=geom_sir]{geom_sir()}} cannot do this, so add \code{\link[=facet_sir]{facet_sir()}} in that case.}
|
||||
|
||||
\item{nrow}{(when using \code{facet}) number of rows.}
|
||||
|
||||
|
||||
@@ -186,10 +186,27 @@ test_that("test-ggplot_sir.R", {
|
||||
built <- ggplot_build(p)
|
||||
expect_equal(sort(built$data[[1]]$y), sort(expected$value))
|
||||
expect_equal(nrow(built$data[[2]]), nrow(expected))
|
||||
# data labels show the number of tested isolates
|
||||
expected_n <- tapply(sir_df(grouped, guideline = gl)$isolates, sir_df(grouped, guideline = gl)$gender, sum)
|
||||
expect_identical(sort(built$data[[2]]$label), sort(paste0("n=", expected_n)))
|
||||
expect_identical(p$labels$y, paste("Proportion", levels(expected$interpretation)[1]))
|
||||
}
|
||||
# all interpretations when they are shown in the facets
|
||||
built <- ggplot_build(ggplot_sir(grouped, x = "antibiotic", fill = "gender", facet = "interpretation", position = "dodge", guideline = "EUCAST"))
|
||||
expect_equal(nrow(built$data[[1]]), nrow(sir_df(grouped, guideline = "EUCAST")))
|
||||
|
||||
# split by antibiotic if it is not shown in the plot and there are several
|
||||
grouped2 <- example_isolates[, c("gender", "AMX", "CIP")]
|
||||
grouped2 <- structure(grouped2, class = c("grouped_df", "tbl_df", "tbl", "data.frame"), groups = data.frame(gender = c("F", "M"), .rows = I(list(which(grouped2$gender == "F"), which(grouped2$gender == "M")))))
|
||||
p <- ggplot_sir(grouped2, x = "gender", guideline = "EUCAST")
|
||||
expect_true(inherits(p$facet, "FacetWrap"))
|
||||
expect_identical(names(p$facet$params$facets), "antibiotic")
|
||||
p <- ggplot_sir(grouped2, x = "interpretation", fill = "interpretation", facet = "gender", guideline = "EUCAST")
|
||||
expect_true(inherits(p$facet, "FacetGrid"))
|
||||
expect_identical(names(p$facet$params$cols), "antibiotic")
|
||||
expect_identical(names(p$facet$params$rows), "gender")
|
||||
# not if the antibiotic is shown, or if there is only one
|
||||
expect_false(inherits(ggplot_sir(grouped2, x = "antibiotic", guideline = "EUCAST")$facet, "FacetWrap"))
|
||||
expect_false(inherits(ggplot_sir(grouped, x = "gender", guideline = "EUCAST")$facet, "FacetWrap"))
|
||||
}
|
||||
})
|
||||
Reference in new issue
Block a user