diff --git a/DESCRIPTION b/DESCRIPTION index cd03392a..e8644e0a 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,5 +1,5 @@ Package: AMR -Version: 1.2.0.9038 +Version: 1.2.0.9039 Date: 2020-07-29 Title: Antimicrobial Resistance Analysis Authors@R: c( diff --git a/NEWS.md b/NEWS.md index 5d3af8cf..a8da8405 100755 --- a/NEWS.md +++ b/NEWS.md @@ -1,4 +1,4 @@ -# AMR 1.2.0.9038 +# AMR 1.2.0.9039 ## Last updated: 29 July 2020 ### New @@ -17,6 +17,7 @@ * Added official antimicrobial names to all `filter_ab_class()` functions, such as `filter_aminoglycosides()` * Added antibiotics code "FOX1" for cefoxitin screening (abbreviation "cfsc") to the `antibiotics` data set * Added Monuril as trade name for fosfomycin +* Added parameter `conserve_capped_values` to `as.rsi()` for interpreting MIC values - it makes sure that values starting with "<" (but not "<=") will always return "S" and values starting with ">" (but not ">=") will always return "R". The default behaviour of `as.rsi()` has not changed, so you need to specifically do `as.rsi(..., conserve_capped_values = TRUE)`. ### Changed * Big speed improvement for using any function on microorganism codes from earlier package versions (prior to `AMR` v1.2.0), such as `as.mo()`, `mo_name()`, `first_isolate()`, `eucast_rules()`, `mdro()`, etc. diff --git a/R/rsi.R b/R/rsi.R index 8d74f3cc..52f527fa 100755 --- a/R/rsi.R +++ b/R/rsi.R @@ -21,7 +21,7 @@ #' Class 'rsi' #' -#' Interpret MIC values and disk diffusion diameters according to EUCAST or CLSI, or clean up existing R/SI values. This transforms the input to a new class [`rsi`], which is an ordered factor with levels `S < I < R`. Invalid antimicrobial interpretations will be translated as `NA` with a warning. +#' Interpret minimum inhibitory concentration (MIC) values and disk diffusion diameters according to EUCAST or CLSI, or clean up existing R/SI values. This transforms the input to a new class [`rsi`], which is an ordered factor with levels `S < I < R`. Invalid antimicrobial interpretations will be translated as `NA` with a warning. #' @inheritSection lifecycle Stable lifecycle #' @rdname as.rsi #' @param x vector of values (for class [`mic`]: an MIC value in mg/L, for class [`disk`]: a disk diffusion radius in millimetres) @@ -30,6 +30,7 @@ #' @param uti (Urinary Tract Infection) A vector with [logical]s (`TRUE` or `FALSE`) to specify whether a UTI specific interpretation from the guideline should be chosen. For using [as.rsi()] on a [data.frame], this can also be a column containing [logical]s or when left blank, the data set will be search for a 'specimen' and rows containing 'urin' in that column will be regarded isolates from a UTI. See *Examples*. #' @inheritParams first_isolate #' @param guideline defaults to the latest included EUCAST guideline, see Details for all options +#' @param conserve_capped_values a logical to indicate that MIC values starting with `">"` (but not `">="`) must always return "R" , and that MIC values starting with `"<"` (but not `"<="`) must always return "S" #' @param threshold maximum fraction of invalid antimicrobial interpretations of `x`, please see *Examples* #' @param ... parameters passed on to methods #' @details @@ -37,6 +38,8 @@ #' #' Supported guidelines to be used as input for the `guideline` parameter are: `r paste0('"', sort(unique(AMR::rsi_translation$guideline)), '"', collapse = ", ")`. Simply using `"CLSI"` or `"EUCAST"` for input will automatically select the latest version of that guideline. #' +#' When using `conserve_capped_values = TRUE`, an MIC value of e.g. ">2" will always return "R", even if the breakpoint according to the chosen guideline is ">=4". This is to prevent that capped values from raw laboratory data would not be treated conservatively. The default behaviour (`conserve_capped_values = FALSE`) considers ">2" to be lower than ">=4" and will in this case return "S" or "I". +#' #' The repository of this package [contains a machine readable version](https://github.com/msberends/AMR/blob/master/data-raw/rsi_translation.txt) of all guidelines. This is a CSV file consisting of `r format(nrow(AMR::rsi_translation), big.mark = ",")` rows and `r ncol(AMR::rsi_translation)` columns. This file is machine readable, since it contains one row for every unique combination of the test method (MIC or disk diffusion), the antimicrobial agent and the microorganism. **This allows for easy implementation of these rules in laboratory information systems (LIS)**. Note that it only contains interpretation guidelines for humans - interpretation guidelines from CLSI for animals were removed. #' #' After using [as.rsi()], you can use [eucast_rules()] to (1) apply inferred susceptibility and resistance based on results of other antimicrobials and (2) apply intrinsic resistance based on taxonomic properties of a microorganism. @@ -210,7 +213,13 @@ as.rsi.default <- function(x, ...) { #' @rdname as.rsi #' @export -as.rsi.mic <- function(x, mo, ab = deparse(substitute(x)), guideline = "EUCAST", uti = FALSE, ...) { +as.rsi.mic <- function(x, + mo, + ab = deparse(substitute(x)), + guideline = "EUCAST", + uti = FALSE, + conserve_capped_values = FALSE, + ...) { stop_if(missing(mo), 'No information was supplied about the microorganisms (missing parameter "mo"). See ?as.rsi.\n\n', "To transform certain columns with e.g. mutate_at(), use\n", @@ -240,13 +249,20 @@ as.rsi.mic <- function(x, mo, ab = deparse(substitute(x)), guideline = "EUCAST", mo = mo_coerced, ab = ab_coerced, guideline = guideline_coerced, - uti = uti) # exec_as.rsi will return message(font_blue(" OK.")) + uti = uti, + conserve_capped_values = conserve_capped_values) # exec_as.rsi will return message(font_blue(" OK.")) result } #' @rdname as.rsi #' @export -as.rsi.disk <- function(x, mo, ab = deparse(substitute(x)), guideline = "EUCAST", uti = FALSE, ...) { +as.rsi.disk <- function(x, + mo, + ab = deparse(substitute(x)), + guideline = "EUCAST", + uti = FALSE, + conserve_capped_values = FALSE, + ...) { stop_if(missing(mo), 'No information was supplied about the microorganisms (missing parameter "mo"). See ?as.rsi.\n\n', "To transform certain columns with e.g. mutate_at(), use\n", @@ -282,7 +298,12 @@ as.rsi.disk <- function(x, mo, ab = deparse(substitute(x)), guideline = "EUCAST" #' @rdname as.rsi #' @export -as.rsi.data.frame <- function(x, col_mo = NULL, guideline = "EUCAST", uti = NULL, ...) { +as.rsi.data.frame <- function(x, + col_mo = NULL, + guideline = "EUCAST", + uti = NULL, + conserve_capped_values = FALSE, + ...) { # try to find columns based on type # -- mo if (is.null(col_mo)) { @@ -368,7 +389,8 @@ as.rsi.data.frame <- function(x, col_mo = NULL, guideline = "EUCAST", uti = NULL mo = x %>% pull(col_mo), ab = ab_cols[i], guideline = guideline, - uti = uti) + uti = uti, + conserve_capped_values = conserve_capped_values) } else if (types[i] == "disk") { x[, ab_cols[i]] <- as.rsi.disk(x = x %>% pull(ab_cols[i]), mo = x %>% pull(col_mo), @@ -399,7 +421,7 @@ get_guideline <- function(guideline) { } -exec_as.rsi <- function(method, x, mo, ab, guideline, uti) { +exec_as.rsi <- function(method, x, mo, ab, guideline, uti, conserve_capped_values) { if (method == "mic") { x <- as.mic(x) # when as.rsi.mic is called directly } else if (method == "disk") { @@ -471,10 +493,12 @@ exec_as.rsi <- function(method, x, mo, ab, guideline, uti) { mic_input <- x[i] mic_S <- as.mic(get_record$breakpoint_S) mic_R <- as.mic(get_record$breakpoint_R) - new_rsi[i] <- ifelse(isTRUE(which(levels(mic_input) == mic_input) <= which(levels(mic_S) == mic_S)), "S", - ifelse(isTRUE(which(levels(mic_input) == mic_input) >= which(levels(mic_R) == mic_R)), "R", - ifelse(!is.na(get_record$breakpoint_S) & !is.na(get_record$breakpoint_R), "I", - NA_character_))) + new_rsi[i] <- ifelse(isTRUE(conserve_capped_values) & mic_input %like% "^<[0-9]", "S", + ifelse(isTRUE(conserve_capped_values) & mic_input %like% "^>[0-9]", "R", + ifelse(isTRUE(which(levels(mic_input) == mic_input) <= which(levels(mic_S) == mic_S)), "S", + ifelse(isTRUE(which(levels(mic_input) == mic_input) >= which(levels(mic_R) == mic_R)), "R", + ifelse(!is.na(get_record$breakpoint_S) & !is.na(get_record$breakpoint_R), "I", + NA_character_))))) } else if (method == "disk") { new_rsi[i] <- ifelse(isTRUE(as.double(x[i]) >= as.double(get_record$breakpoint_S)), "S", ifelse(isTRUE(as.double(x[i]) <= as.double(get_record$breakpoint_R)), "R", diff --git a/docs/404.html b/docs/404.html index 49b9c82a..08e2e268 100644 --- a/docs/404.html +++ b/docs/404.html @@ -81,7 +81,7 @@ AMR (for R) - 1.2.0.9038 + 1.2.0.9039 diff --git a/docs/LICENSE-text.html b/docs/LICENSE-text.html index 81cdb0f1..ad64af63 100644 --- a/docs/LICENSE-text.html +++ b/docs/LICENSE-text.html @@ -81,7 +81,7 @@ AMR (for R) - 1.2.0.9038 + 1.2.0.9039 diff --git a/docs/articles/index.html b/docs/articles/index.html index 36eba9cc..becb8cde 100644 --- a/docs/articles/index.html +++ b/docs/articles/index.html @@ -81,7 +81,7 @@ AMR (for R) - 1.2.0.9038 + 1.2.0.9039 diff --git a/docs/authors.html b/docs/authors.html index f7da00e1..d721c1ae 100644 --- a/docs/authors.html +++ b/docs/authors.html @@ -81,7 +81,7 @@ AMR (for R) - 1.2.0.9038 + 1.2.0.9039 diff --git a/docs/index.html b/docs/index.html index b8bff786..c9fbbf1a 100644 --- a/docs/index.html +++ b/docs/index.html @@ -43,7 +43,7 @@ AMR (for R) - 1.2.0.9038 + 1.2.0.9039 diff --git a/docs/news/index.html b/docs/news/index.html index b56c24ca..96c24db3 100644 --- a/docs/news/index.html +++ b/docs/news/index.html @@ -81,7 +81,7 @@ AMR (for R) - 1.2.0.9038 + 1.2.0.9039 @@ -229,9 +229,9 @@ Source: NEWS.md -
-

-AMR 1.2.0.9038 Unreleased +
+

+AMR 1.2.0.9039 Unreleased

@@ -256,6 +256,7 @@
  • Added official antimicrobial names to all filter_ab_class() functions, such as filter_aminoglycosides()

  • Added antibiotics code “FOX1” for cefoxitin screening (abbreviation “cfsc”) to the antibiotics data set

  • Added Monuril as trade name for fosfomycin

  • +
  • Added parameter conserve_capped_values to as.rsi() for interpreting MIC values - it makes sure that values starting with “<” (but not “<=”) will always return “S” and values starting with “>” (but not “>=”) will always return “R”. The default behaviour of as.rsi() has not changed, so you need to specifically do as.rsi(..., conserve_capped_values = TRUE).

  • diff --git a/docs/pkgdown.yml b/docs/pkgdown.yml index 1457eaf2..642982ed 100644 --- a/docs/pkgdown.yml +++ b/docs/pkgdown.yml @@ -10,7 +10,7 @@ articles: WHONET: WHONET.html benchmarks: benchmarks.html resistance_predict: resistance_predict.html -last_built: 2020-07-29T08:31Z +last_built: 2020-07-29T09:46Z urls: reference: https://msberends.github.io/AMR/reference article: https://msberends.github.io/AMR/articles diff --git a/docs/reference/as.rsi.html b/docs/reference/as.rsi.html index ece9f88a..4f28a991 100644 --- a/docs/reference/as.rsi.html +++ b/docs/reference/as.rsi.html @@ -49,7 +49,7 @@ - + @@ -82,7 +82,7 @@ AMR (for R) - 1.2.0.9038 + 1.2.0.9039
    @@ -232,7 +232,7 @@
    -

    Interpret MIC values and disk diffusion diameters according to EUCAST or CLSI, or clean up existing R/SI values. This transforms the input to a new class rsi, which is an ordered factor with levels S < I < R. Invalid antimicrobial interpretations will be translated as NA with a warning.

    +

    Interpret minimum inhibitory concentration (MIC) values and disk diffusion diameters according to EUCAST or CLSI, or clean up existing R/SI values. This transforms the input to a new class rsi, which is an ordered factor with levels S < I < R. Invalid antimicrobial interpretations will be translated as NA with a warning.

    as.rsi(x, ...)
    @@ -244,6 +244,7 @@
       ab = deparse(substitute(x)),
       guideline = "EUCAST",
       uti = FALSE,
    +  conserve_capped_values = FALSE,
       ...
     )
     
    @@ -254,11 +255,19 @@
       ab = deparse(substitute(x)),
       guideline = "EUCAST",
       uti = FALSE,
    +  conserve_capped_values = FALSE,
       ...
     )
     
     # S3 method for data.frame
    -as.rsi(x, col_mo = NULL, guideline = "EUCAST", uti = NULL, ...)
    +as.rsi(
    +  x,
    +  col_mo = NULL,
    +  guideline = "EUCAST",
    +  uti = NULL,
    +  conserve_capped_values = FALSE,
    +  ...
    +)
     
     is.rsi(x)
     
    @@ -291,6 +300,10 @@
           uti
           

    (Urinary Tract Infection) A vector with logicals (TRUE or FALSE) to specify whether a UTI specific interpretation from the guideline should be chosen. For using as.rsi() on a data.frame, this can also be a column containing logicals or when left blank, the data set will be search for a 'specimen' and rows containing 'urin' in that column will be regarded isolates from a UTI. See Examples.

    + + conserve_capped_values +

    a logical to indicate that MIC values starting with ">" (but not ">=") must always return "R" , and that MIC values starting with "<" (but not "<=") must always return "S"

    + col_mo

    column name of the IDs of the microorganisms (see as.mo()), defaults to the first column of class mo. Values will be coerced using as.mo().

    @@ -308,6 +321,7 @@

    When using as.rsi() on untransformed data, the data will be cleaned to only contain values S, I and R. When using the function on data with class mic (using as.mic()) or class disk (using as.disk()), the data will be interpreted based on the guideline set with the guideline parameter.

    Supported guidelines to be used as input for the guideline parameter are: "CLSI 2010", "CLSI 2011", "CLSI 2012", "CLSI 2013", "CLSI 2014", "CLSI 2015", "CLSI 2016", "CLSI 2017", "CLSI 2018", "CLSI 2019", "EUCAST 2011", "EUCAST 2012", "EUCAST 2013", "EUCAST 2014", "EUCAST 2015", "EUCAST 2016", "EUCAST 2017", "EUCAST 2018", "EUCAST 2019", "EUCAST 2020". Simply using "CLSI" or "EUCAST" for input will automatically select the latest version of that guideline.

    +

    When using conserve_capped_values = TRUE, an MIC value of e.g. ">2" will always return "R", even if the breakpoint according to the chosen guideline is ">=4". This is to prevent that capped values from raw laboratory data would not be treated conservatively. The default behaviour (conserve_capped_values = FALSE) considers ">2" to be lower than ">=4" and will in this case return "S" or "I".

    The repository of this package contains a machine readable version of all guidelines. This is a CSV file consisting of 18,650 rows and 10 columns. This file is machine readable, since it contains one row for every unique combination of the test method (MIC or disk diffusion), the antimicrobial agent and the microorganism. This allows for easy implementation of these rules in laboratory information systems (LIS). Note that it only contains interpretation guidelines for humans - interpretation guidelines from CLSI for animals were removed.

    After using as.rsi(), you can use eucast_rules() to (1) apply inferred susceptibility and resistance based on results of other antimicrobials and (2) apply intrinsic resistance based on taxonomic properties of a microorganism.

    The function is.rsi.eligible() returns TRUE when a columns contains at most 5% invalid antimicrobial interpretations (not S and/or I and/or R), and FALSE otherwise. The threshold of 5% can be set with the threshold parameter.

    diff --git a/docs/reference/index.html b/docs/reference/index.html index 19b76368..42e3fbef 100644 --- a/docs/reference/index.html +++ b/docs/reference/index.html @@ -81,7 +81,7 @@ AMR (for R) - 1.2.0.9038 + 1.2.0.9039

    diff --git a/docs/survey.html b/docs/survey.html index ed857061..d4288f74 100644 --- a/docs/survey.html +++ b/docs/survey.html @@ -81,7 +81,7 @@ AMR (for R) - 1.2.0.9038 + 1.2.0.9039 diff --git a/man/as.rsi.Rd b/man/as.rsi.Rd index d94e7c8f..569901e6 100755 --- a/man/as.rsi.Rd +++ b/man/as.rsi.Rd @@ -18,6 +18,7 @@ as.rsi(x, ...) ab = deparse(substitute(x)), guideline = "EUCAST", uti = FALSE, + conserve_capped_values = FALSE, ... ) @@ -27,10 +28,18 @@ as.rsi(x, ...) ab = deparse(substitute(x)), guideline = "EUCAST", uti = FALSE, + conserve_capped_values = FALSE, ... ) -\method{as.rsi}{data.frame}(x, col_mo = NULL, guideline = "EUCAST", uti = NULL, ...) +\method{as.rsi}{data.frame}( + x, + col_mo = NULL, + guideline = "EUCAST", + uti = NULL, + conserve_capped_values = FALSE, + ... +) is.rsi(x) @@ -49,6 +58,8 @@ is.rsi.eligible(x, threshold = 0.05) \item{uti}{(Urinary Tract Infection) A vector with \link{logical}s (\code{TRUE} or \code{FALSE}) to specify whether a UTI specific interpretation from the guideline should be chosen. For using \code{\link[=as.rsi]{as.rsi()}} on a \link{data.frame}, this can also be a column containing \link{logical}s or when left blank, the data set will be search for a 'specimen' and rows containing 'urin' in that column will be regarded isolates from a UTI. See \emph{Examples}.} +\item{conserve_capped_values}{a logical to indicate that MIC values starting with \code{">"} (but not \code{">="}) must always return "R" , and that MIC values starting with \code{"<"} (but not \code{"<="}) must always return "S"} + \item{col_mo}{column name of the IDs of the microorganisms (see \code{\link[=as.mo]{as.mo()}}), defaults to the first column of class \code{\link{mo}}. Values will be coerced using \code{\link[=as.mo]{as.mo()}}.} \item{threshold}{maximum fraction of invalid antimicrobial interpretations of \code{x}, please see \emph{Examples}} @@ -57,13 +68,15 @@ is.rsi.eligible(x, threshold = 0.05) Ordered factor with new class \code{\link{rsi}} } \description{ -Interpret MIC values and disk diffusion diameters according to EUCAST or CLSI, or clean up existing R/SI values. This transforms the input to a new class \code{\link{rsi}}, which is an ordered factor with levels \verb{S < I < R}. Invalid antimicrobial interpretations will be translated as \code{NA} with a warning. +Interpret minimum inhibitory concentration (MIC) values and disk diffusion diameters according to EUCAST or CLSI, or clean up existing R/SI values. This transforms the input to a new class \code{\link{rsi}}, which is an ordered factor with levels \verb{S < I < R}. Invalid antimicrobial interpretations will be translated as \code{NA} with a warning. } \details{ When using \code{\link[=as.rsi]{as.rsi()}} on untransformed data, the data will be cleaned to only contain values S, I and R. When using the function on data with class \code{\link{mic}} (using \code{\link[=as.mic]{as.mic()}}) or class \code{\link{disk}} (using \code{\link[=as.disk]{as.disk()}}), the data will be interpreted based on the guideline set with the \code{guideline} parameter. Supported guidelines to be used as input for the \code{guideline} parameter are: "CLSI 2010", "CLSI 2011", "CLSI 2012", "CLSI 2013", "CLSI 2014", "CLSI 2015", "CLSI 2016", "CLSI 2017", "CLSI 2018", "CLSI 2019", "EUCAST 2011", "EUCAST 2012", "EUCAST 2013", "EUCAST 2014", "EUCAST 2015", "EUCAST 2016", "EUCAST 2017", "EUCAST 2018", "EUCAST 2019", "EUCAST 2020". Simply using \code{"CLSI"} or \code{"EUCAST"} for input will automatically select the latest version of that guideline. +When using \code{conserve_capped_values = TRUE}, an MIC value of e.g. ">2" will always return "R", even if the breakpoint according to the chosen guideline is ">=4". This is to prevent that capped values from raw laboratory data would not be treated conservatively. The default behaviour (\code{conserve_capped_values = FALSE}) considers ">2" to be lower than ">=4" and will in this case return "S" or "I". + The repository of this package \href{https://github.com/msberends/AMR/blob/master/data-raw/rsi_translation.txt}{contains a machine readable version} of all guidelines. This is a CSV file consisting of 18,650 rows and 10 columns. This file is machine readable, since it contains one row for every unique combination of the test method (MIC or disk diffusion), the antimicrobial agent and the microorganism. \strong{This allows for easy implementation of these rules in laboratory information systems (LIS)}. Note that it only contains interpretation guidelines for humans - interpretation guidelines from CLSI for animals were removed. After using \code{\link[=as.rsi]{as.rsi()}}, you can use \code{\link[=eucast_rules]{eucast_rules()}} to (1) apply inferred susceptibility and resistance based on results of other antimicrobials and (2) apply intrinsic resistance based on taxonomic properties of a microorganism.