mirror of
				https://github.com/msberends/AMR.git
				synced 2025-11-04 09:14:01 +01:00 
			
		
		
		
	(v2.1.1.9155) new mic_p50() and mic_p90() - updated AMR intro
				
					
				
			This commit is contained in:
		@@ -1,6 +1,6 @@
 | 
			
		||||
Package: AMR
 | 
			
		||||
Version: 2.1.1.9154
 | 
			
		||||
Date: 2025-02-22
 | 
			
		||||
Version: 2.1.1.9155
 | 
			
		||||
Date: 2025-02-23
 | 
			
		||||
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
 | 
			
		||||
 
 | 
			
		||||
@@ -251,6 +251,8 @@ export(mdr_cmi2012)
 | 
			
		||||
export(mdr_tb)
 | 
			
		||||
export(mdro)
 | 
			
		||||
export(mean_amr_distance)
 | 
			
		||||
export(mic_p50)
 | 
			
		||||
export(mic_p90)
 | 
			
		||||
export(mo_authors)
 | 
			
		||||
export(mo_class)
 | 
			
		||||
export(mo_cleaning_regex)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								NEWS.md
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								NEWS.md
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
# AMR 2.1.1.9154
 | 
			
		||||
# AMR 2.1.1.9155
 | 
			
		||||
 | 
			
		||||
*(this beta version will eventually become v3.0. We're happy to reach a new major milestone soon, which will be all about the new One Health support! Install this beta using [the instructions here](https://msberends.github.io/AMR/#latest-development-version).)*
 | 
			
		||||
 | 
			
		||||
@@ -38,7 +38,7 @@ This package now supports not only tools for AMR data analysis in clinical setti
 | 
			
		||||
* **Other**
 | 
			
		||||
  * New function `top_n_microorganisms()` to filter a data set to the top *n* of any taxonomic property, e.g., filter to the top 3 species, filter to any species in the top 5 genera, or filter to the top 3 species in each of the top 5 genera
 | 
			
		||||
  * New function `mo_group_members()` to retrieve the member microorganisms of a microorganism group. For example, `mo_group_members("Strep group C")` returns a vector of all microorganisms that belong to that group.
 | 
			
		||||
  
 | 
			
		||||
  * New functions `mic_p50()` and `mic_p90()` to retrieve the 50th and 90th percentile of MIC values.
 | 
			
		||||
 | 
			
		||||
## Changed
 | 
			
		||||
* SIR interpretation
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
Metadata-Version: 2.2
 | 
			
		||||
Name: AMR
 | 
			
		||||
Version: 2.1.1.9154
 | 
			
		||||
Version: 2.1.1.9155
 | 
			
		||||
Summary: A Python wrapper for the AMR R package
 | 
			
		||||
Home-page: https://github.com/msberends/AMR
 | 
			
		||||
Author: Matthijs Berends
 | 
			
		||||
 
 | 
			
		||||
@@ -73,6 +73,8 @@ from .functions import is_disk
 | 
			
		||||
from .functions import as_mic
 | 
			
		||||
from .functions import is_mic
 | 
			
		||||
from .functions import rescale_mic
 | 
			
		||||
from .functions import mic_p50
 | 
			
		||||
from .functions import mic_p90
 | 
			
		||||
from .functions import as_mo
 | 
			
		||||
from .functions import is_mo
 | 
			
		||||
from .functions import mo_uncertainties
 | 
			
		||||
 
 | 
			
		||||
@@ -249,6 +249,12 @@ def is_mic(x):
 | 
			
		||||
def rescale_mic(x, *args, **kwargs):
 | 
			
		||||
    """See our website of the R package for the manual: https://msberends.github.io/AMR/index.html"""
 | 
			
		||||
    return convert_to_python(amr_r.rescale_mic(x, *args, **kwargs))
 | 
			
		||||
def mic_p50(x, *args, **kwargs):
 | 
			
		||||
    """See our website of the R package for the manual: https://msberends.github.io/AMR/index.html"""
 | 
			
		||||
    return convert_to_python(amr_r.mic_p50(x, *args, **kwargs))
 | 
			
		||||
def mic_p90(x, *args, **kwargs):
 | 
			
		||||
    """See our website of the R package for the manual: https://msberends.github.io/AMR/index.html"""
 | 
			
		||||
    return convert_to_python(amr_r.mic_p90(x, *args, **kwargs))
 | 
			
		||||
def as_mo(x, *args, **kwargs):
 | 
			
		||||
    """See our website of the R package for the manual: https://msberends.github.io/AMR/index.html"""
 | 
			
		||||
    return convert_to_python(amr_r.as_mo(x, *args, **kwargs))
 | 
			
		||||
 
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								PythonPackage/AMR/dist/AMR-2.1.1.9155-py3-none-any.whl
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								PythonPackage/AMR/dist/AMR-2.1.1.9155-py3-none-any.whl
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								PythonPackage/AMR/dist/amr-2.1.1.9154.tar.gz
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								PythonPackage/AMR/dist/amr-2.1.1.9154.tar.gz
									
									
									
									
										vendored
									
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								PythonPackage/AMR/dist/amr-2.1.1.9155.tar.gz
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								PythonPackage/AMR/dist/amr-2.1.1.9155.tar.gz
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
 | 
			
		||||
 | 
			
		||||
setup(
 | 
			
		||||
    name='AMR',
 | 
			
		||||
    version='2.1.1.9154',
 | 
			
		||||
    version='2.1.1.9155',
 | 
			
		||||
    packages=find_packages(),
 | 
			
		||||
    install_requires=[
 | 
			
		||||
        'rpy2',
 | 
			
		||||
 
 | 
			
		||||
@@ -1390,6 +1390,9 @@ as_original_data_class <- function(df, old_class = NULL, extra_class = NULL) {
 | 
			
		||||
    fn <- function(x) base::as.data.frame(df, stringsAsFactors = FALSE)
 | 
			
		||||
  }
 | 
			
		||||
  out <- fn(df)
 | 
			
		||||
  # don't keep row names
 | 
			
		||||
  rownames(out) <- NULL
 | 
			
		||||
  # add additional class if needed
 | 
			
		||||
  if (!is.null(extra_class)) {
 | 
			
		||||
    class(out) <- c(extra_class, class(out))
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
@@ -923,19 +923,16 @@ antibiogram.default <- function(x,
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  out <- as_original_data_class(new_df, class(x), extra_class = "antibiogram")
 | 
			
		||||
  out <- structure(as_original_data_class(new_df, class(x), extra_class = "antibiogram"),
 | 
			
		||||
                   has_syndromic_group = has_syndromic_group,
 | 
			
		||||
                   combine_SI = combine_SI,
 | 
			
		||||
                   wisca = wisca,
 | 
			
		||||
                   conf_interval = conf_interval,
 | 
			
		||||
                   formatting_type = formatting_type,
 | 
			
		||||
                   wisca_parameters = as_original_data_class(wisca_parameters, class(x)),
 | 
			
		||||
                   long_numeric = as_original_data_class(long_numeric, class(x)))
 | 
			
		||||
  rownames(out) <- NULL
 | 
			
		||||
  rownames(wisca_parameters) <- NULL
 | 
			
		||||
  rownames(long_numeric) <- NULL
 | 
			
		||||
  structure(out,
 | 
			
		||||
            has_syndromic_group = has_syndromic_group,
 | 
			
		||||
            combine_SI = combine_SI,
 | 
			
		||||
            wisca = wisca,
 | 
			
		||||
            conf_interval = conf_interval,
 | 
			
		||||
            formatting_type = formatting_type,
 | 
			
		||||
            wisca_parameters = as_original_data_class(wisca_parameters, class(x)),
 | 
			
		||||
            long_numeric = as_original_data_class(long_numeric, class(x))
 | 
			
		||||
  )
 | 
			
		||||
  out
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#' @method antibiogram grouped_df
 | 
			
		||||
@@ -1041,14 +1038,16 @@ antibiogram.grouped_df <- function(x,
 | 
			
		||||
  
 | 
			
		||||
  close(progress)
 | 
			
		||||
  
 | 
			
		||||
  structure(as_original_data_class(out, class(x), extra_class = "antibiogram"),
 | 
			
		||||
            has_syndromic_group = FALSE,
 | 
			
		||||
            combine_SI = isTRUE(combine_SI),
 | 
			
		||||
            wisca = isTRUE(wisca),
 | 
			
		||||
            conf_interval = conf_interval,
 | 
			
		||||
            formatting_type = formatting_type,
 | 
			
		||||
            wisca_parameters = as_original_data_class(wisca_parameters, class(x)),
 | 
			
		||||
            long_numeric = as_original_data_class(long_numeric, class(x)))
 | 
			
		||||
  out <- structure(as_original_data_class(out, class(x), extra_class = "antibiogram"),
 | 
			
		||||
                   has_syndromic_group = FALSE,
 | 
			
		||||
                   combine_SI = isTRUE(combine_SI),
 | 
			
		||||
                   wisca = isTRUE(wisca),
 | 
			
		||||
                   conf_interval = conf_interval,
 | 
			
		||||
                   formatting_type = formatting_type,
 | 
			
		||||
                   wisca_parameters = as_original_data_class(wisca_parameters, class(x)),
 | 
			
		||||
                   long_numeric = as_original_data_class(long_numeric, class(x)))
 | 
			
		||||
  rownames(out) <- NULL
 | 
			
		||||
  out
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#' @export
 | 
			
		||||
 
 | 
			
		||||
@@ -185,8 +185,9 @@ bug_drug_combinations <- function(x,
 | 
			
		||||
  
 | 
			
		||||
  out <- as_original_data_class(out, class(x.bak)) # will remove tibble groups
 | 
			
		||||
  out <- out %pm>% pm_arrange(mo, ab)
 | 
			
		||||
  class(out) <- c("bug_drug_combinations", if(data_has_groups) "grouped" else NULL, class(out))
 | 
			
		||||
  rownames(out) <- NULL
 | 
			
		||||
  structure(out, class = c("bug_drug_combinations", if(data_has_groups) "grouped" else NULL, class(out)))
 | 
			
		||||
  out
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#' @method format bug_drug_combinations
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										15
									
								
								R/mic.R
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								R/mic.R
									
									
									
									
									
								
							@@ -346,6 +346,21 @@ rescale_mic <- function(x, mic_range, keep_operators = "edges", as.mic = TRUE) {
 | 
			
		||||
  out
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#' @rdname as.mic
 | 
			
		||||
#' @details Use [mic_p50()] and [mic_p90()] to get the 50th and 90th percentile of MIC values. They return 'normal' [numeric] values.
 | 
			
		||||
#' @export
 | 
			
		||||
mic_p50 <- function(x, na.rm = FALSE, ...) {
 | 
			
		||||
  x <- as.mic(x)
 | 
			
		||||
  as.double(stats::quantile(x, probs = 0.5, na.rm = na.rm))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#' @rdname as.mic
 | 
			
		||||
#' @export
 | 
			
		||||
mic_p90 <- function(x, na.rm = FALSE, ...) {
 | 
			
		||||
  x <- as.mic(x)
 | 
			
		||||
  as.double(stats::quantile(x, probs = 0.9, na.rm = na.rm))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#' @method as.double mic
 | 
			
		||||
#' @export
 | 
			
		||||
#' @noRd
 | 
			
		||||
 
 | 
			
		||||
@@ -186,7 +186,7 @@
 | 
			
		||||
#'     scale_colour_sir(language = "pt",
 | 
			
		||||
#'                      name = "Support in 20 languages")
 | 
			
		||||
#' }
 | 
			
		||||
#' 
 | 
			
		||||
#' }
 | 
			
		||||
#' 
 | 
			
		||||
#' # Plotting using base R's plot() ---------------------------------------
 | 
			
		||||
#'
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								R/sir.R
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								R/sir.R
									
									
									
									
									
								
							@@ -1544,7 +1544,7 @@ sir_interpretation_history <- function(clean = FALSE) {
 | 
			
		||||
  if (pkg_is_available("tibble")) {
 | 
			
		||||
    out <- import_fn("as_tibble", "tibble")(out)
 | 
			
		||||
  }
 | 
			
		||||
  structure(out, class = c("sir_log", class(out)))
 | 
			
		||||
  as_original_data_class(out, class(out), extra_class = "sir_log")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#' @method print sir_log
 | 
			
		||||
 
 | 
			
		||||
@@ -383,8 +383,6 @@ sir_calc_df <- function(type, # "proportion", "count" or "both"
 | 
			
		||||
    # remove redundant columns
 | 
			
		||||
    out <- subset(out, select = -c(ci_min, ci_max, isolates))
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  rownames(out) <- NULL
 | 
			
		||||
  out <- as_original_data_class(out, class(data.bak)) # will remove tibble groups
 | 
			
		||||
  structure(out, class = c("sir_df", class(out)))
 | 
			
		||||
  
 | 
			
		||||
  as_original_data_class(out, class(data.bak), extra_class = "sir_df") # will remove tibble groups
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
This knowledge base contains all context you must know about the AMR package for R. You are a GPT trained to be an assistant for the AMR package in R. You are an incredible R specialist, especially trained in this package and in the tidyverse.
 | 
			
		||||
 | 
			
		||||
First and foremost, you are trained on version 2.1.1.9154. Remember this whenever someone asks which AMR package version you’re at.
 | 
			
		||||
First and foremost, you are trained on version 2.1.1.9155. Remember this whenever someone asks which AMR package version you’re at.
 | 
			
		||||
 | 
			
		||||
Below are the contents of the  file, the  file, and all the  files (documentation) in the package. Every file content is split using 100 hypens.
 | 
			
		||||
----------------------------------------------------------------------------------------------------
 | 
			
		||||
@@ -262,6 +262,8 @@ export(mdr_cmi2012)
 | 
			
		||||
export(mdr_tb)
 | 
			
		||||
export(mdro)
 | 
			
		||||
export(mean_amr_distance)
 | 
			
		||||
export(mic_p50)
 | 
			
		||||
export(mic_p90)
 | 
			
		||||
export(mo_authors)
 | 
			
		||||
export(mo_class)
 | 
			
		||||
export(mo_cleaning_regex)
 | 
			
		||||
@@ -656,30 +658,18 @@ It will be downloaded and installed automatically. For RStudio, click on the men
 | 
			
		||||
 | 
			
		||||
#### Latest development version
 | 
			
		||||
 | 
			
		||||
[](https://github.com/msberends/AMR/actions/workflows/check-old.yaml?query=branch%3Amain)
 | 
			
		||||
[](https://github.com/msberends/AMR/actions/workflows/check-recent.yaml?query=branch%3Amain)
 | 
			
		||||
[](https://github.com/msberends/AMR/actions/workflows/check-old-tinytest.yaml)
 | 
			
		||||
[](https://github.com/msberends/AMR/actions/workflows/check-current-testthat.yaml)
 | 
			
		||||
[](https://www.codefactor.io/repository/github/msberends/amr)
 | 
			
		||||
[](https://codecov.io/gh/msberends/AMR?branch=main)
 | 
			
		||||
 | 
			
		||||
Please read our [Developer Guideline here](https://github.com/msberends/AMR/wiki/Developer-Guideline).
 | 
			
		||||
 | 
			
		||||
The latest and unpublished development version can be installed from GitHub in two ways:
 | 
			
		||||
The latest and unpublished development version can be installed from the [rOpenSci R-universe platform](https://msberends.r-universe.dev/AMR):
 | 
			
		||||
 | 
			
		||||
1. Manually, using:
 | 
			
		||||
 | 
			
		||||
   ```r
 | 
			
		||||
   install.packages("remotes") # if you haven't already
 | 
			
		||||
   remotes::install_github("msberends/AMR")
 | 
			
		||||
   ```
 | 
			
		||||
   
 | 
			
		||||
2. Automatically, using the [rOpenSci R-universe platform](https://ropensci.org/r-universe/), by adding [our R-universe address](https://msberends.r-universe.dev) to your list of repositories ('repos'):
 | 
			
		||||
 | 
			
		||||
   ```r
 | 
			
		||||
   options(repos = c(getOption("repos"),
 | 
			
		||||
                     msberends = "https://msberends.r-universe.dev"))
 | 
			
		||||
   ```
 | 
			
		||||
   
 | 
			
		||||
   After this, you can install and update this `AMR` package like any official release (e.g., using `install.packages("AMR")` or in RStudio via *Tools* > *Check for Package Updates...*).
 | 
			
		||||
```r
 | 
			
		||||
install.packages("AMR", repos = "https://msberends.r-universe.dev")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Get started
 | 
			
		||||
 | 
			
		||||
@@ -2873,6 +2863,8 @@ THE PART HEREAFTER CONTAINS CONTENTS FROM FILE 'man/as.mic.Rd':
 | 
			
		||||
\alias{is.mic}
 | 
			
		||||
\alias{NA_mic_}
 | 
			
		||||
\alias{rescale_mic}
 | 
			
		||||
\alias{mic_p50}
 | 
			
		||||
\alias{mic_p90}
 | 
			
		||||
\alias{droplevels.mic}
 | 
			
		||||
\title{Transform Input to Minimum Inhibitory Concentrations (MIC)}
 | 
			
		||||
\usage{
 | 
			
		||||
@@ -2884,6 +2876,10 @@ NA_mic_
 | 
			
		||||
 | 
			
		||||
rescale_mic(x, mic_range, keep_operators = "edges", as.mic = TRUE)
 | 
			
		||||
 | 
			
		||||
mic_p50(x, na.rm = FALSE, ...)
 | 
			
		||||
 | 
			
		||||
mic_p90(x, na.rm = FALSE, ...)
 | 
			
		||||
 | 
			
		||||
\method{droplevels}{mic}(x, as.mic = FALSE, ...)
 | 
			
		||||
}
 | 
			
		||||
\arguments{
 | 
			
		||||
@@ -2953,6 +2949,8 @@ With \code{\link[=rescale_mic]{rescale_mic()}}, existing MIC ranges can be limit
 | 
			
		||||
For \code{ggplot2}, use one of the \code{\link[=scale_x_mic]{scale_*_mic()}} functions to plot MIC values. They allows custom MIC ranges and to plot intermediate log2 levels for missing MIC values.
 | 
			
		||||
 | 
			
		||||
\code{NA_mic_} is a missing value of the new \code{mic} class, analogous to e.g. base \R's \code{\link[base:NA]{NA_character_}}.
 | 
			
		||||
 | 
			
		||||
Use \code{\link[=mic_p50]{mic_p50()}} and \code{\link[=mic_p90]{mic_p90()}} to get the 50th and 90th percentile of MIC values. They return 'normal' \link{numeric} values.
 | 
			
		||||
}
 | 
			
		||||
\examples{
 | 
			
		||||
mic_data <- as.mic(c(">=32", "1.0", "1", "1.00", 8, "<=0.128", "8", "16", "16"))
 | 
			
		||||
@@ -7540,6 +7538,131 @@ The interpretation of "I" will be named "Increased exposure" for all EUCAST guid
 | 
			
		||||
For interpreting MIC values as well as disk diffusion diameters, the default guideline is EUCAST 2024, unless the package option \code{\link[=AMR-options]{AMR_guideline}} is set. See \code{\link[=as.sir]{as.sir()}} for more information.
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
\examples{
 | 
			
		||||
some_mic_values <- random_mic(size = 100)
 | 
			
		||||
some_disk_values <- random_disk(size = 100, mo = "Escherichia coli", ab = "cipro")
 | 
			
		||||
some_sir_values <- random_sir(50, prob_SIR = c(0.55, 0.05, 0.30))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
\donttest{
 | 
			
		||||
# Plotting using ggplot2's autoplot() for MIC, disk, and SIR -----------
 | 
			
		||||
if (require("ggplot2")) {
 | 
			
		||||
  autoplot(some_mic_values)
 | 
			
		||||
}
 | 
			
		||||
if (require("ggplot2")) {
 | 
			
		||||
  # when providing the microorganism and antibiotic, colours will show interpretations:
 | 
			
		||||
  autoplot(some_mic_values, mo = "Escherichia coli", ab = "cipro")
 | 
			
		||||
}
 | 
			
		||||
if (require("ggplot2")) {
 | 
			
		||||
  # support for 20 languages, various guidelines, and many options
 | 
			
		||||
  autoplot(some_disk_values, mo = "Escherichia coli", ab = "cipro",
 | 
			
		||||
           guideline = "CLSI 2024", language = "no",
 | 
			
		||||
           title = "Disk diffusion from the North")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Plotting using scale_x_mic() -----------------------------------------
 | 
			
		||||
if (require("ggplot2")) {
 | 
			
		||||
  mic_plot <- ggplot(data.frame(mics = as.mic(c(0.25, "<=4", 4, 8, 32, ">=32")),
 | 
			
		||||
                                counts = c(1, 1, 2, 2, 3, 3)),
 | 
			
		||||
                     aes(mics, counts)) +
 | 
			
		||||
    geom_col()
 | 
			
		||||
  mic_plot +
 | 
			
		||||
    labs(title = "without scale_x_mic()")
 | 
			
		||||
}
 | 
			
		||||
if (require("ggplot2")) {
 | 
			
		||||
  mic_plot +
 | 
			
		||||
    scale_x_mic() +
 | 
			
		||||
    labs(title = "with scale_x_mic()")
 | 
			
		||||
}
 | 
			
		||||
if (require("ggplot2")) {
 | 
			
		||||
  mic_plot +
 | 
			
		||||
    scale_x_mic(keep_operators = "all") +
 | 
			
		||||
    labs(title = "with scale_x_mic() keeping all operators")
 | 
			
		||||
}
 | 
			
		||||
if (require("ggplot2")) {
 | 
			
		||||
  mic_plot +
 | 
			
		||||
    scale_x_mic(mic_range = c(1, 16)) +
 | 
			
		||||
    labs(title = "with scale_x_mic() using a manual 'within' range")
 | 
			
		||||
}
 | 
			
		||||
if (require("ggplot2")) {
 | 
			
		||||
  mic_plot +
 | 
			
		||||
    scale_x_mic(mic_range = c(0.032, 256)) +
 | 
			
		||||
    labs(title = "with scale_x_mic() using a manual 'outside' range")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Plotting using scale_y_mic() -----------------------------------------
 | 
			
		||||
some_groups <- sample(LETTERS[1:5], 20, replace = TRUE)
 | 
			
		||||
 | 
			
		||||
if (require("ggplot2")) {
 | 
			
		||||
  ggplot(data.frame(mic = some_mic_values,
 | 
			
		||||
                    group = some_groups),
 | 
			
		||||
         aes(group, mic)) +
 | 
			
		||||
    geom_boxplot() +
 | 
			
		||||
    geom_violin(linetype = 2, colour = "grey", fill = NA) +
 | 
			
		||||
    scale_y_mic()
 | 
			
		||||
}
 | 
			
		||||
if (require("ggplot2")) {
 | 
			
		||||
  ggplot(data.frame(mic = some_mic_values,
 | 
			
		||||
                    group = some_groups),
 | 
			
		||||
         aes(group, mic)) +
 | 
			
		||||
    geom_boxplot() +
 | 
			
		||||
    geom_violin(linetype = 2, colour = "grey", fill = NA) +
 | 
			
		||||
    scale_y_mic(mic_range = c(NA, 0.25))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Plotting using scale_x_sir() -----------------------------------------
 | 
			
		||||
if (require("ggplot2")) {
 | 
			
		||||
  ggplot(data.frame(x = c("I", "R", "S"),
 | 
			
		||||
                    y = c(45,323, 573)),
 | 
			
		||||
         aes(x, y)) +
 | 
			
		||||
    geom_col() +
 | 
			
		||||
    scale_x_sir()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Plotting using scale_y_mic() and scale_colour_sir() ------------------
 | 
			
		||||
if (require("ggplot2")) {
 | 
			
		||||
  plain <- ggplot(data.frame(mic = some_mic_values,
 | 
			
		||||
                             group = some_groups,
 | 
			
		||||
                             sir = as.sir(some_mic_values,
 | 
			
		||||
                                          mo = "E. coli",
 | 
			
		||||
                                          ab = "cipro")),
 | 
			
		||||
                  aes(x = group, y = mic, colour = sir)) +
 | 
			
		||||
    theme_minimal() +
 | 
			
		||||
    geom_boxplot(fill = NA, colour = "grey") +
 | 
			
		||||
    geom_jitter(width = 0.25)
 | 
			
		||||
  
 | 
			
		||||
  plain
 | 
			
		||||
}
 | 
			
		||||
if (require("ggplot2")) {
 | 
			
		||||
  # and now with our MIC and SIR scale functions:
 | 
			
		||||
  plain +
 | 
			
		||||
    scale_y_mic() +
 | 
			
		||||
    scale_colour_sir()
 | 
			
		||||
}
 | 
			
		||||
if (require("ggplot2")) {
 | 
			
		||||
  plain +
 | 
			
		||||
    scale_y_mic(mic_range = c(0.005, 32), name = "Our MICs!") +
 | 
			
		||||
    scale_colour_sir(language = "pt",
 | 
			
		||||
                     name = "Support in 20 languages")
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Plotting using base R's plot() ---------------------------------------
 | 
			
		||||
 | 
			
		||||
plot(some_mic_values)
 | 
			
		||||
# when providing the microorganism and antibiotic, colours will show interpretations:
 | 
			
		||||
plot(some_mic_values, mo = "S. aureus", ab = "ampicillin")
 | 
			
		||||
 | 
			
		||||
plot(some_disk_values)
 | 
			
		||||
plot(some_disk_values, mo = "Escherichia coli", ab = "cipro")
 | 
			
		||||
plot(some_disk_values, mo = "Escherichia coli", ab = "cipro", language = "nl")
 | 
			
		||||
 | 
			
		||||
plot(some_sir_values)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -8516,8 +8639,10 @@ antibiogram(example_isolates,
 | 
			
		||||
To create a combined antibiogram, use antibiotic codes or names with a plus `+` character like this:
 | 
			
		||||
 | 
			
		||||
```{r comb}
 | 
			
		||||
antibiogram(example_isolates,
 | 
			
		||||
            antibiotics = c("TZP", "TZP+TOB", "TZP+GEN"))
 | 
			
		||||
combined_ab <- antibiogram(example_isolates,
 | 
			
		||||
                           antibiotics = c("TZP", "TZP+TOB", "TZP+GEN"),
 | 
			
		||||
                           ab_transform = NULL)
 | 
			
		||||
combined_ab
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Syndromic Antibiogram
 | 
			
		||||
@@ -8532,17 +8657,26 @@ antibiogram(example_isolates,
 | 
			
		||||
 | 
			
		||||
### Weighted-Incidence Syndromic Combination Antibiogram (WISCA)
 | 
			
		||||
 | 
			
		||||
To create a WISCA, you must state combination therapy in the `antibiotics` argument (similar to the Combination Antibiogram), define a syndromic group with the `syndromic_group` argument (similar to the Syndromic Antibiogram) in which cases are predefined based on clinical or demographic characteristics (e.g., endocarditis in 75+ females).  This next example is a simplification without clinical characteristics, but just gives an idea of how a WISCA can be created:
 | 
			
		||||
To create a **Weighted-Incidence Syndromic Combination Antibiogram (WISCA)**, simply set `wisca = TRUE` in the `antibiogram()` function, or use the dedicated `wisca()` function. Unlike traditional antibiograms, WISCA provides syndrome-based susceptibility estimates, weighted by pathogen incidence and antimicrobial susceptibility patterns.
 | 
			
		||||
 | 
			
		||||
```{r wisca}
 | 
			
		||||
wisca <- antibiogram(example_isolates,
 | 
			
		||||
                     antibiotics = c("AMC", "AMC+CIP", "TZP", "TZP+TOB"),
 | 
			
		||||
                     mo_transform = "gramstain",
 | 
			
		||||
                     minimum = 10, # this should be >= 30, but now just as example
 | 
			
		||||
                     syndromic_group = ifelse(example_isolates$age >= 65 &
 | 
			
		||||
                                                example_isolates$gender == "M",
 | 
			
		||||
                                              "WISCA Group 1", "WISCA Group 2"))
 | 
			
		||||
wisca
 | 
			
		||||
example_isolates %>%
 | 
			
		||||
  wisca(antibiotics = c("TZP", "TZP+TOB", "TZP+GEN"),
 | 
			
		||||
        minimum = 10) # Recommended threshold: ≥30
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
WISCA uses a **Bayesian decision model** to integrate data from multiple pathogens, improving empirical therapy guidance, especially for low-incidence infections. It is **pathogen-agnostic**, meaning results are syndrome-based rather than stratified by microorganism.
 | 
			
		||||
 | 
			
		||||
For reliable results, ensure your data includes **only first isolates** (use `first_isolate()`) and consider filtering for **the top *n* species** (use `top_n_microorganisms()`), as WISCA outcomes are most meaningful when based on robust incidence estimates.
 | 
			
		||||
 | 
			
		||||
For **patient- or syndrome-specific WISCA**, run the function on a grouped `tibble`, i.e., using `group_by()` first:
 | 
			
		||||
 | 
			
		||||
```{r wisca_grouped}
 | 
			
		||||
example_isolates %>%
 | 
			
		||||
  top_n_microorganisms(n = 10) %>%
 | 
			
		||||
  group_by(age_group = age_groups(age, c(25, 50, 75)),
 | 
			
		||||
           gender) %>%
 | 
			
		||||
  wisca(antibiotics = c("TZP", "TZP+TOB", "TZP+GEN"))
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Plotting antibiograms
 | 
			
		||||
@@ -8550,7 +8684,7 @@ wisca
 | 
			
		||||
Antibiograms can be plotted using `autoplot()` from the `ggplot2` packages, since this `AMR` package provides an extension to that function:
 | 
			
		||||
 | 
			
		||||
```{r}
 | 
			
		||||
autoplot(wisca)
 | 
			
		||||
autoplot(combined_ab)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
To calculate antimicrobial resistance in a more sensible way, also by correcting for too few results, we use the `resistance()` and `susceptibility()` functions.
 | 
			
		||||
@@ -8575,9 +8709,54 @@ our_data_1st %>%
 | 
			
		||||
  summarise(amoxicillin = resistance(AMX))
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Interpreting MIC and Disk Diffusion Values  
 | 
			
		||||
 | 
			
		||||
Minimal inhibitory concentration (MIC) values and disk diffusion diameters can be interpreted into clinical breakpoints (SIR) using `as.sir()`. Here’s an example with randomly generated MIC values for *Klebsiella pneumoniae* and ciprofloxacin:
 | 
			
		||||
 | 
			
		||||
```{r mic_interpretation}
 | 
			
		||||
set.seed(123)
 | 
			
		||||
mic_values <- random_mic(100)
 | 
			
		||||
sir_values <- as.sir(mic_values, mo = "K. pneumoniae", ab = "cipro", guideline = "EUCAST 2024")
 | 
			
		||||
 | 
			
		||||
my_data <- tibble(MIC = mic_values, SIR = sir_values)
 | 
			
		||||
my_data
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This allows direct interpretation according to EUCAST or CLSI breakpoints, facilitating automated AMR data processing.
 | 
			
		||||
 | 
			
		||||
## Plotting MIC and SIR Interpretations  
 | 
			
		||||
 | 
			
		||||
We can visualise MIC distributions and their SIR interpretations using `ggplot2`, using the new `scale_y_mic()` for the y-axis and `scale_colour_sir()` to colour-code SIR categories.
 | 
			
		||||
 | 
			
		||||
```{r mic_plot}
 | 
			
		||||
# add a group
 | 
			
		||||
my_data$group <- rep(c("A", "B", "C", "D"), each = 25) 
 | 
			
		||||
 | 
			
		||||
ggplot(my_data,
 | 
			
		||||
       aes(x = group, y = MIC, colour = SIR)) +
 | 
			
		||||
  geom_jitter(width = 0.2, size = 2) +
 | 
			
		||||
  geom_boxplot(fill = NA, colour = "grey40") +
 | 
			
		||||
  scale_y_mic() +
 | 
			
		||||
  scale_colour_sir() +
 | 
			
		||||
  labs(title = "MIC Distribution and SIR Interpretation",
 | 
			
		||||
       x = "Sample Groups",
 | 
			
		||||
       y = "MIC (mg/L)")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This plot provides an intuitive way to assess susceptibility patterns across different groups while incorporating clinical breakpoints.  
 | 
			
		||||
 | 
			
		||||
For a more straightforward and less manual approach, `ggplot2`'s function `autoplot()` has been extended by this package to directly plot MIC and disk diffusion values:
 | 
			
		||||
 | 
			
		||||
```{r autoplot}
 | 
			
		||||
autoplot(mic_values)
 | 
			
		||||
 | 
			
		||||
# by providing `mo` and `ab`, colours will indicate the SIR interpretation:
 | 
			
		||||
autoplot(mic_values, mo = "K. pneumoniae", ab = "cipro", guideline = "EUCAST 2024")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
----
 | 
			
		||||
 | 
			
		||||
*Author: Dr. Matthijs Berends, 26th Feb 2023*
 | 
			
		||||
*Author: Dr. Matthijs Berends, 23rd Feb 2025*
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										24
									
								
								index.md
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								index.md
									
									
									
									
									
								
							@@ -266,30 +266,18 @@ It will be downloaded and installed automatically. For RStudio, click on the men
 | 
			
		||||
 | 
			
		||||
#### Latest development version
 | 
			
		||||
 | 
			
		||||
[](https://github.com/msberends/AMR/actions/workflows/check-old.yaml?query=branch%3Amain)
 | 
			
		||||
[](https://github.com/msberends/AMR/actions/workflows/check-recent.yaml?query=branch%3Amain)
 | 
			
		||||
[](https://github.com/msberends/AMR/actions/workflows/check-old-tinytest.yaml)
 | 
			
		||||
[](https://github.com/msberends/AMR/actions/workflows/check-current-testthat.yaml)
 | 
			
		||||
[](https://www.codefactor.io/repository/github/msberends/amr)
 | 
			
		||||
[](https://codecov.io/gh/msberends/AMR?branch=main)
 | 
			
		||||
 | 
			
		||||
Please read our [Developer Guideline here](https://github.com/msberends/AMR/wiki/Developer-Guideline).
 | 
			
		||||
 | 
			
		||||
The latest and unpublished development version can be installed from GitHub in two ways:
 | 
			
		||||
The latest and unpublished development version can be installed from the [rOpenSci R-universe platform](https://msberends.r-universe.dev/AMR):
 | 
			
		||||
 | 
			
		||||
1. Manually, using:
 | 
			
		||||
 | 
			
		||||
   ```r
 | 
			
		||||
   install.packages("remotes") # if you haven't already
 | 
			
		||||
   remotes::install_github("msberends/AMR")
 | 
			
		||||
   ```
 | 
			
		||||
   
 | 
			
		||||
2. Automatically, using the [rOpenSci R-universe platform](https://ropensci.org/r-universe/), by adding [our R-universe address](https://msberends.r-universe.dev) to your list of repositories ('repos'):
 | 
			
		||||
 | 
			
		||||
   ```r
 | 
			
		||||
   options(repos = c(getOption("repos"),
 | 
			
		||||
                     msberends = "https://msberends.r-universe.dev"))
 | 
			
		||||
   ```
 | 
			
		||||
   
 | 
			
		||||
   After this, you can install and update this `AMR` package like any official release (e.g., using `install.packages("AMR")` or in RStudio via *Tools* > *Check for Package Updates...*).
 | 
			
		||||
```r
 | 
			
		||||
install.packages("AMR", repos = "https://msberends.r-universe.dev")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Get started
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,8 @@
 | 
			
		||||
\alias{is.mic}
 | 
			
		||||
\alias{NA_mic_}
 | 
			
		||||
\alias{rescale_mic}
 | 
			
		||||
\alias{mic_p50}
 | 
			
		||||
\alias{mic_p90}
 | 
			
		||||
\alias{droplevels.mic}
 | 
			
		||||
\title{Transform Input to Minimum Inhibitory Concentrations (MIC)}
 | 
			
		||||
\usage{
 | 
			
		||||
@@ -18,6 +20,10 @@ NA_mic_
 | 
			
		||||
 | 
			
		||||
rescale_mic(x, mic_range, keep_operators = "edges", as.mic = TRUE)
 | 
			
		||||
 | 
			
		||||
mic_p50(x, na.rm = FALSE, ...)
 | 
			
		||||
 | 
			
		||||
mic_p90(x, na.rm = FALSE, ...)
 | 
			
		||||
 | 
			
		||||
\method{droplevels}{mic}(x, as.mic = FALSE, ...)
 | 
			
		||||
}
 | 
			
		||||
\arguments{
 | 
			
		||||
@@ -87,6 +93,8 @@ With \code{\link[=rescale_mic]{rescale_mic()}}, existing MIC ranges can be limit
 | 
			
		||||
For \code{ggplot2}, use one of the \code{\link[=scale_x_mic]{scale_*_mic()}} functions to plot MIC values. They allows custom MIC ranges and to plot intermediate log2 levels for missing MIC values.
 | 
			
		||||
 | 
			
		||||
\code{NA_mic_} is a missing value of the new \code{mic} class, analogous to e.g. base \R's \code{\link[base:NA]{NA_character_}}.
 | 
			
		||||
 | 
			
		||||
Use \code{\link[=mic_p50]{mic_p50()}} and \code{\link[=mic_p90]{mic_p90()}} to get the 50th and 90th percentile of MIC values. They return 'normal' \link{numeric} values.
 | 
			
		||||
}
 | 
			
		||||
\examples{
 | 
			
		||||
mic_data <- as.mic(c(">=32", "1.0", "1", "1.00", 8, "<=0.128", "8", "16", "16"))
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										125
									
								
								man/plot.Rd
									
									
									
									
									
								
							
							
						
						
									
										125
									
								
								man/plot.Rd
									
									
									
									
									
								
							@@ -196,3 +196,128 @@ The interpretation of "I" will be named "Increased exposure" for all EUCAST guid
 | 
			
		||||
For interpreting MIC values as well as disk diffusion diameters, the default guideline is EUCAST 2024, unless the package option \code{\link[=AMR-options]{AMR_guideline}} is set. See \code{\link[=as.sir]{as.sir()}} for more information.
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
\examples{
 | 
			
		||||
some_mic_values <- random_mic(size = 100)
 | 
			
		||||
some_disk_values <- random_disk(size = 100, mo = "Escherichia coli", ab = "cipro")
 | 
			
		||||
some_sir_values <- random_sir(50, prob_SIR = c(0.55, 0.05, 0.30))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
\donttest{
 | 
			
		||||
# Plotting using ggplot2's autoplot() for MIC, disk, and SIR -----------
 | 
			
		||||
if (require("ggplot2")) {
 | 
			
		||||
  autoplot(some_mic_values)
 | 
			
		||||
}
 | 
			
		||||
if (require("ggplot2")) {
 | 
			
		||||
  # when providing the microorganism and antibiotic, colours will show interpretations:
 | 
			
		||||
  autoplot(some_mic_values, mo = "Escherichia coli", ab = "cipro")
 | 
			
		||||
}
 | 
			
		||||
if (require("ggplot2")) {
 | 
			
		||||
  # support for 20 languages, various guidelines, and many options
 | 
			
		||||
  autoplot(some_disk_values, mo = "Escherichia coli", ab = "cipro",
 | 
			
		||||
           guideline = "CLSI 2024", language = "no",
 | 
			
		||||
           title = "Disk diffusion from the North")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Plotting using scale_x_mic() -----------------------------------------
 | 
			
		||||
if (require("ggplot2")) {
 | 
			
		||||
  mic_plot <- ggplot(data.frame(mics = as.mic(c(0.25, "<=4", 4, 8, 32, ">=32")),
 | 
			
		||||
                                counts = c(1, 1, 2, 2, 3, 3)),
 | 
			
		||||
                     aes(mics, counts)) +
 | 
			
		||||
    geom_col()
 | 
			
		||||
  mic_plot +
 | 
			
		||||
    labs(title = "without scale_x_mic()")
 | 
			
		||||
}
 | 
			
		||||
if (require("ggplot2")) {
 | 
			
		||||
  mic_plot +
 | 
			
		||||
    scale_x_mic() +
 | 
			
		||||
    labs(title = "with scale_x_mic()")
 | 
			
		||||
}
 | 
			
		||||
if (require("ggplot2")) {
 | 
			
		||||
  mic_plot +
 | 
			
		||||
    scale_x_mic(keep_operators = "all") +
 | 
			
		||||
    labs(title = "with scale_x_mic() keeping all operators")
 | 
			
		||||
}
 | 
			
		||||
if (require("ggplot2")) {
 | 
			
		||||
  mic_plot +
 | 
			
		||||
    scale_x_mic(mic_range = c(1, 16)) +
 | 
			
		||||
    labs(title = "with scale_x_mic() using a manual 'within' range")
 | 
			
		||||
}
 | 
			
		||||
if (require("ggplot2")) {
 | 
			
		||||
  mic_plot +
 | 
			
		||||
    scale_x_mic(mic_range = c(0.032, 256)) +
 | 
			
		||||
    labs(title = "with scale_x_mic() using a manual 'outside' range")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Plotting using scale_y_mic() -----------------------------------------
 | 
			
		||||
some_groups <- sample(LETTERS[1:5], 20, replace = TRUE)
 | 
			
		||||
 | 
			
		||||
if (require("ggplot2")) {
 | 
			
		||||
  ggplot(data.frame(mic = some_mic_values,
 | 
			
		||||
                    group = some_groups),
 | 
			
		||||
         aes(group, mic)) +
 | 
			
		||||
    geom_boxplot() +
 | 
			
		||||
    geom_violin(linetype = 2, colour = "grey", fill = NA) +
 | 
			
		||||
    scale_y_mic()
 | 
			
		||||
}
 | 
			
		||||
if (require("ggplot2")) {
 | 
			
		||||
  ggplot(data.frame(mic = some_mic_values,
 | 
			
		||||
                    group = some_groups),
 | 
			
		||||
         aes(group, mic)) +
 | 
			
		||||
    geom_boxplot() +
 | 
			
		||||
    geom_violin(linetype = 2, colour = "grey", fill = NA) +
 | 
			
		||||
    scale_y_mic(mic_range = c(NA, 0.25))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Plotting using scale_x_sir() -----------------------------------------
 | 
			
		||||
if (require("ggplot2")) {
 | 
			
		||||
  ggplot(data.frame(x = c("I", "R", "S"),
 | 
			
		||||
                    y = c(45,323, 573)),
 | 
			
		||||
         aes(x, y)) +
 | 
			
		||||
    geom_col() +
 | 
			
		||||
    scale_x_sir()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Plotting using scale_y_mic() and scale_colour_sir() ------------------
 | 
			
		||||
if (require("ggplot2")) {
 | 
			
		||||
  plain <- ggplot(data.frame(mic = some_mic_values,
 | 
			
		||||
                             group = some_groups,
 | 
			
		||||
                             sir = as.sir(some_mic_values,
 | 
			
		||||
                                          mo = "E. coli",
 | 
			
		||||
                                          ab = "cipro")),
 | 
			
		||||
                  aes(x = group, y = mic, colour = sir)) +
 | 
			
		||||
    theme_minimal() +
 | 
			
		||||
    geom_boxplot(fill = NA, colour = "grey") +
 | 
			
		||||
    geom_jitter(width = 0.25)
 | 
			
		||||
  
 | 
			
		||||
  plain
 | 
			
		||||
}
 | 
			
		||||
if (require("ggplot2")) {
 | 
			
		||||
  # and now with our MIC and SIR scale functions:
 | 
			
		||||
  plain +
 | 
			
		||||
    scale_y_mic() +
 | 
			
		||||
    scale_colour_sir()
 | 
			
		||||
}
 | 
			
		||||
if (require("ggplot2")) {
 | 
			
		||||
  plain +
 | 
			
		||||
    scale_y_mic(mic_range = c(0.005, 32), name = "Our MICs!") +
 | 
			
		||||
    scale_colour_sir(language = "pt",
 | 
			
		||||
                     name = "Support in 20 languages")
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Plotting using base R's plot() ---------------------------------------
 | 
			
		||||
 | 
			
		||||
plot(some_mic_values)
 | 
			
		||||
# when providing the microorganism and antibiotic, colours will show interpretations:
 | 
			
		||||
plot(some_mic_values, mo = "S. aureus", ab = "ampicillin")
 | 
			
		||||
 | 
			
		||||
plot(some_disk_values)
 | 
			
		||||
plot(some_disk_values, mo = "Escherichia coli", ab = "cipro")
 | 
			
		||||
plot(some_disk_values, mo = "Escherichia coli", ab = "cipro", language = "nl")
 | 
			
		||||
 | 
			
		||||
plot(some_sir_values)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -28,9 +28,9 @@
 | 
			
		||||
# ==================================================================== #
 | 
			
		||||
 | 
			
		||||
# used in multiple functions, also in plotting
 | 
			
		||||
expect_true(all(as.mic(COMMON_MIC_VALUES) %in% VALID_MIC_LEVELS))
 | 
			
		||||
expect_true(all(paste0("<=", as.mic(COMMON_MIC_VALUES)) %in% VALID_MIC_LEVELS))
 | 
			
		||||
expect_true(all(paste0(">=", as.mic(COMMON_MIC_VALUES)) %in% VALID_MIC_LEVELS))
 | 
			
		||||
expect_true(all(as.mic(AMR:::COMMON_MIC_VALUES) %in% AMR:::VALID_MIC_LEVELS))
 | 
			
		||||
expect_true(all(paste0("<=", as.mic(AMR:::COMMON_MIC_VALUES)) %in% AMR:::VALID_MIC_LEVELS))
 | 
			
		||||
expect_true(all(paste0(">=", as.mic(AMR:::COMMON_MIC_VALUES)) %in% AMR:::VALID_MIC_LEVELS))
 | 
			
		||||
 | 
			
		||||
expect_true(as.mic(8) == as.mic("8"))
 | 
			
		||||
expect_true(as.mic("1") > as.mic("<=0.0625"))
 | 
			
		||||
 
 | 
			
		||||
@@ -288,8 +288,10 @@ antibiogram(example_isolates,
 | 
			
		||||
To create a combined antibiogram, use antibiotic codes or names with a plus `+` character like this:
 | 
			
		||||
 | 
			
		||||
```{r comb}
 | 
			
		||||
antibiogram(example_isolates,
 | 
			
		||||
            antibiotics = c("TZP", "TZP+TOB", "TZP+GEN"))
 | 
			
		||||
combined_ab <- antibiogram(example_isolates,
 | 
			
		||||
                           antibiotics = c("TZP", "TZP+TOB", "TZP+GEN"),
 | 
			
		||||
                           ab_transform = NULL)
 | 
			
		||||
combined_ab
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Syndromic Antibiogram
 | 
			
		||||
@@ -304,17 +306,26 @@ antibiogram(example_isolates,
 | 
			
		||||
 | 
			
		||||
### Weighted-Incidence Syndromic Combination Antibiogram (WISCA)
 | 
			
		||||
 | 
			
		||||
To create a WISCA, you must state combination therapy in the `antibiotics` argument (similar to the Combination Antibiogram), define a syndromic group with the `syndromic_group` argument (similar to the Syndromic Antibiogram) in which cases are predefined based on clinical or demographic characteristics (e.g., endocarditis in 75+ females).  This next example is a simplification without clinical characteristics, but just gives an idea of how a WISCA can be created:
 | 
			
		||||
To create a **Weighted-Incidence Syndromic Combination Antibiogram (WISCA)**, simply set `wisca = TRUE` in the `antibiogram()` function, or use the dedicated `wisca()` function. Unlike traditional antibiograms, WISCA provides syndrome-based susceptibility estimates, weighted by pathogen incidence and antimicrobial susceptibility patterns.
 | 
			
		||||
 | 
			
		||||
```{r wisca}
 | 
			
		||||
wisca <- antibiogram(example_isolates,
 | 
			
		||||
                     antibiotics = c("AMC", "AMC+CIP", "TZP", "TZP+TOB"),
 | 
			
		||||
                     mo_transform = "gramstain",
 | 
			
		||||
                     minimum = 10, # this should be >= 30, but now just as example
 | 
			
		||||
                     syndromic_group = ifelse(example_isolates$age >= 65 &
 | 
			
		||||
                                                example_isolates$gender == "M",
 | 
			
		||||
                                              "WISCA Group 1", "WISCA Group 2"))
 | 
			
		||||
wisca
 | 
			
		||||
example_isolates %>%
 | 
			
		||||
  wisca(antibiotics = c("TZP", "TZP+TOB", "TZP+GEN"),
 | 
			
		||||
        minimum = 10) # Recommended threshold: ≥30
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
WISCA uses a **Bayesian decision model** to integrate data from multiple pathogens, improving empirical therapy guidance, especially for low-incidence infections. It is **pathogen-agnostic**, meaning results are syndrome-based rather than stratified by microorganism.
 | 
			
		||||
 | 
			
		||||
For reliable results, ensure your data includes **only first isolates** (use `first_isolate()`) and consider filtering for **the top *n* species** (use `top_n_microorganisms()`), as WISCA outcomes are most meaningful when based on robust incidence estimates.
 | 
			
		||||
 | 
			
		||||
For **patient- or syndrome-specific WISCA**, run the function on a grouped `tibble`, i.e., using `group_by()` first:
 | 
			
		||||
 | 
			
		||||
```{r wisca_grouped}
 | 
			
		||||
example_isolates %>%
 | 
			
		||||
  top_n_microorganisms(n = 10) %>%
 | 
			
		||||
  group_by(age_group = age_groups(age, c(25, 50, 75)),
 | 
			
		||||
           gender) %>%
 | 
			
		||||
  wisca(antibiotics = c("TZP", "TZP+TOB", "TZP+GEN"))
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Plotting antibiograms
 | 
			
		||||
@@ -322,7 +333,7 @@ wisca
 | 
			
		||||
Antibiograms can be plotted using `autoplot()` from the `ggplot2` packages, since this `AMR` package provides an extension to that function:
 | 
			
		||||
 | 
			
		||||
```{r}
 | 
			
		||||
autoplot(wisca)
 | 
			
		||||
autoplot(combined_ab)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
To calculate antimicrobial resistance in a more sensible way, also by correcting for too few results, we use the `resistance()` and `susceptibility()` functions.
 | 
			
		||||
@@ -347,6 +358,51 @@ our_data_1st %>%
 | 
			
		||||
  summarise(amoxicillin = resistance(AMX))
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Interpreting MIC and Disk Diffusion Values  
 | 
			
		||||
 | 
			
		||||
Minimal inhibitory concentration (MIC) values and disk diffusion diameters can be interpreted into clinical breakpoints (SIR) using `as.sir()`. Here’s an example with randomly generated MIC values for *Klebsiella pneumoniae* and ciprofloxacin:
 | 
			
		||||
 | 
			
		||||
```{r mic_interpretation}
 | 
			
		||||
set.seed(123)
 | 
			
		||||
mic_values <- random_mic(100)
 | 
			
		||||
sir_values <- as.sir(mic_values, mo = "K. pneumoniae", ab = "cipro", guideline = "EUCAST 2024")
 | 
			
		||||
 | 
			
		||||
my_data <- tibble(MIC = mic_values, SIR = sir_values)
 | 
			
		||||
my_data
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This allows direct interpretation according to EUCAST or CLSI breakpoints, facilitating automated AMR data processing.
 | 
			
		||||
 | 
			
		||||
## Plotting MIC and SIR Interpretations  
 | 
			
		||||
 | 
			
		||||
We can visualise MIC distributions and their SIR interpretations using `ggplot2`, using the new `scale_y_mic()` for the y-axis and `scale_colour_sir()` to colour-code SIR categories.
 | 
			
		||||
 | 
			
		||||
```{r mic_plot}
 | 
			
		||||
# add a group
 | 
			
		||||
my_data$group <- rep(c("A", "B", "C", "D"), each = 25) 
 | 
			
		||||
 | 
			
		||||
ggplot(my_data,
 | 
			
		||||
       aes(x = group, y = MIC, colour = SIR)) +
 | 
			
		||||
  geom_jitter(width = 0.2, size = 2) +
 | 
			
		||||
  geom_boxplot(fill = NA, colour = "grey40") +
 | 
			
		||||
  scale_y_mic() +
 | 
			
		||||
  scale_colour_sir() +
 | 
			
		||||
  labs(title = "MIC Distribution and SIR Interpretation",
 | 
			
		||||
       x = "Sample Groups",
 | 
			
		||||
       y = "MIC (mg/L)")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This plot provides an intuitive way to assess susceptibility patterns across different groups while incorporating clinical breakpoints.  
 | 
			
		||||
 | 
			
		||||
For a more straightforward and less manual approach, `ggplot2`'s function `autoplot()` has been extended by this package to directly plot MIC and disk diffusion values:
 | 
			
		||||
 | 
			
		||||
```{r autoplot}
 | 
			
		||||
autoplot(mic_values)
 | 
			
		||||
 | 
			
		||||
# by providing `mo` and `ab`, colours will indicate the SIR interpretation:
 | 
			
		||||
autoplot(mic_values, mo = "K. pneumoniae", ab = "cipro", guideline = "EUCAST 2024")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
----
 | 
			
		||||
 | 
			
		||||
*Author: Dr. Matthijs Berends, 26th Feb 2023*
 | 
			
		||||
*Author: Dr. Matthijs Berends, 23rd Feb 2025*
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user