diff --git a/DESCRIPTION b/DESCRIPTION index 1e91ef26..2ed99ea7 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: AMR -Version: 2.1.1.9015 -Date: 2024-03-09 +Version: 2.1.1.9016 +Date: 2024-04-05 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 diff --git a/NEWS.md b/NEWS.md index f2fc26ee..d03dc88c 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,4 +1,4 @@ -# AMR 2.1.1.9015 +# AMR 2.1.1.9016 *(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!)* @@ -10,7 +10,7 @@ This package now supports not only tools for AMR data analysis in clinical setti ## New * One Health implementation - * Function `as.sir()` now supports animal breakpoints from CLSI. Use `breakpoint_type = "animal"` and set the `host` argument to a variable that contains animal species names. + * Function `as.sir()` now has extensive support for animal breakpoints from CLSI. Use `breakpoint_type = "animal"` and set the `host` argument to a variable that contains animal species names. * The `clinical_breakpoints` data set contains all these breakpoints, and can be downloaded on our [download page](https://msberends.github.io/AMR/articles/datasets.html). * The `antibiotics` data set contains all veterinary antibiotics, such as pradofloxacin and enrofloxacin. All WHOCC codes for veterinary use have been added as well. * `ab_atc()` now supports ATC codes of veterinary antibiotics (that all start with "Q") @@ -22,8 +22,9 @@ This package now supports not only tools for AMR data analysis in clinical setti * For MICs: * Added as valid levels: 4096, 6 powers of 0.0625, and 5 powers of 192 (192, 384, 576, 768, 960) * Added new argument `keep_operators` to `as.mic()`. This can be `"all"` (default), `"none"`, or `"edges"`. This argument is also available in the new `limit_mic_range()` and `scale_*_mic()` functions. + * Comparisons of MIC values are now more strict. For example, `>32` is higher than (and never equal to) `32`. Thus, `as.mic(">32") == as.mic(32)` now returns `FALSE`, and `as.mic(">32") > as.mic(32)` now returns `TRUE`. * Updated `italicise_taxonomy()` to support HTML -* Greatly improved `vctrs` integration, a Tidyverse package working in the background for many Tidyverse functions. For users, this means that `dplyr::rowwise()` and `dplyr::c_across()` are now supported for e.g. columns of class `mic`. Despite this, this `AMR` package is still zero-dependent on any other package, including `dplyr` and `vctrs`. +* Greatly improved `vctrs` integration, a Tidyverse package working in the background for many Tidyverse functions. For users, this means that functions such as `dplyr`'s `bind_rows()`, `rowwise()` and `c_across()` are now supported for e.g. columns of class `mic`. Despite this, this `AMR` package is still zero-dependent on any other package, including `dplyr` and `vctrs`. * Updated all ATC codes from WHOCC * Updated all antibiotic DDDs from WHOCC diff --git a/R/aa_helper_functions.R b/R/aa_helper_functions.R index 19d1a63a..b1e8e99e 100644 --- a/R/aa_helper_functions.R +++ b/R/aa_helper_functions.R @@ -875,7 +875,7 @@ meet_criteria <- function(object, # can be literally `list(...)` for `allow_argu if ("logical" %in% allow_class) { is_in <- is_in[!is_in %in% c("TRUE", "FALSE")] } - or_values <- vector_or(is_in, quotes = !isTRUE(any(c("double", "numeric", "integer") %in% allow_class))) + or_values <- vector_or(is_in, quotes = !isTRUE(any(c("numeric", "integer") %in% allow_class))) if ("logical" %in% allow_class) { or_values <- paste0(or_values, ", or TRUE or FALSE") } diff --git a/R/disk.R b/R/disk.R index a939f21c..75e05be0 100755 --- a/R/disk.R +++ b/R/disk.R @@ -165,11 +165,6 @@ pillar_shaft.disk <- function(x, ...) { create_pillar_column(out, align = "right", width = 2) } -# will be exported using s3_register() in R/zzz.R -type_sum.disk <- function(x, ...) { - "disk" -} - #' @method print disk #' @export #' @noRd diff --git a/R/mean_amr_distance.R b/R/mean_amr_distance.R index 0508a4a0..c4fcf51b 100755 --- a/R/mean_amr_distance.R +++ b/R/mean_amr_distance.R @@ -175,8 +175,8 @@ mean_amr_distance.data.frame <- function(x, ..., combine_SI = TRUE) { #' @param row an index, such as a row number #' @export amr_distance_from_row <- function(amr_distance, row) { - meet_criteria(amr_distance, allow_class = c("double", "numeric"), is_finite = TRUE) - meet_criteria(row, allow_class = c("logical", "double", "numeric")) + meet_criteria(amr_distance, allow_class = "numeric", is_finite = TRUE) + meet_criteria(row, allow_class = c("logical", "numeric", "integer")) if (is.logical(row)) { row <- which(row) } diff --git a/R/mic.R b/R/mic.R index c3019a87..81091fed 100644 --- a/R/mic.R +++ b/R/mic.R @@ -154,99 +154,103 @@ as.mic <- function(x, na.rm = FALSE, keep_operators = "all") { } if (is.mic(x) && (keep_operators == "all" || !any(x %like% "[>=<]", na.rm = TRUE))) { - x + if (!identical(levels(x), VALID_MIC_LEVELS)) { + # from an older AMR version - just update MIC factor levels + x <- set_clean_class(factor(as.character(x), levels = VALID_MIC_LEVELS, ordered = TRUE), + new_class = c("mic", "ordered", "factor")) + } + return(x) + } + + x.bak <- NULL + if (is.numeric(x)) { + x.bak <- format(x, scientific = FALSE) + # MICs never have more than 9 decimals, so: + x <- format(round(x, 9), scientific = FALSE) } else { - x.bak <- NULL - if (is.numeric(x)) { - x.bak <- format(x, scientific = FALSE) - # MICs never have more than 9 decimals, so: - x <- format(round(x, 9), scientific = FALSE) - } else { - x <- as.character(unlist(x)) - } - if (isTRUE(na.rm)) { - x <- x[!is.na(x)] - } - x <- trimws2(x) - x[x == ""] <- NA - if (is.null(x.bak)) { - x.bak <- x - } - - # comma to period - x <- gsub(",", ".", x, fixed = TRUE) - # transform scientific notation - x[x %like% "[-]?[0-9]+([.][0-9]+)?e[-]?[0-9]+"] <- as.double(x[x %like% "[-]?[0-9]+([.][0-9]+)?e[-]?[0-9]+"]) - # transform Unicode for >= and <= - x <- gsub("\u2264", "<=", x, fixed = TRUE) - x <- gsub("\u2265", ">=", x, fixed = TRUE) - # remove other invalid characters - x <- gsub("[^a-zA-Z0-9.><= ]+", "", x, perl = TRUE) - # remove space between operator and number ("<= 0.002" -> "<=0.002") - x <- gsub("(<|=|>) +", "\\1", x, perl = TRUE) - # transform => to >= and =< to <= - x <- gsub("=<", "<=", x, fixed = TRUE) - x <- gsub("=>", ">=", x, fixed = TRUE) - # dots without a leading zero must start with 0 - x <- gsub("([^0-9]|^)[.]", "\\10.", x, perl = TRUE) - # values like "<=0.2560.512" should be 0.512 - x <- gsub(".*[.].*[.]", "0.", x, perl = TRUE) - # remove ending .0 - x <- gsub("[.]+0$", "", x, perl = TRUE) - # remove all after last digit - x <- gsub("[^0-9]+$", "", x, perl = TRUE) - # keep only one zero before dot - x <- gsub("0+[.]", "0.", x, perl = TRUE) - # starting 00 is probably 0.0 if there's no dot yet - x[x %unlike% "[.]"] <- gsub("^00", "0.0", x[!x %like% "[.]"]) - # remove last zeroes - x <- gsub("([.].?)0+$", "\\1", x, perl = TRUE) - x <- gsub("(.*[.])0+$", "\\10", x, perl = TRUE) - # remove ending .0 again - x[x %like% "[.]"] <- gsub("0+$", "", x[x %like% "[.]"]) - # never end with dot - x <- gsub("[.]$", "", x, perl = TRUE) - # trim it - x <- trimws2(x) - - ## previously unempty values now empty - should return a warning later on - x[x.bak != "" & x == ""] <- "invalid" - - na_before <- x[is.na(x) | x == ""] %pm>% length() - x[!x %in% VALID_MIC_LEVELS] <- NA - na_after <- x[is.na(x) | x == ""] %pm>% length() - - if (na_before != na_after) { - list_missing <- x.bak[is.na(x) & !is.na(x.bak) & x.bak != ""] %pm>% - unique() %pm>% - sort() %pm>% - vector_and(quotes = TRUE) - cur_col <- get_current_column() - warning_("in `as.mic()`: ", na_after - na_before, " result", - ifelse(na_after - na_before > 1, "s", ""), - ifelse(is.null(cur_col), "", paste0(" in column '", cur_col, "'")), - " truncated (", - round(((na_after - na_before) / length(x)) * 100), - "%) that were invalid MICs: ", - list_missing, - call = FALSE - ) - } - - if (keep_operators == "none" && !all(is.na(x))) { - x <- gsub("[>=<]", "", x) - } else if (keep_operators == "edges" && !all(is.na(x))) { - dbls <- as.double(gsub("[>=<]", "", x)) - x[dbls == min(dbls, na.rm = TRUE)] <- paste0("<=", min(dbls, na.rm = TRUE)) - x[dbls == max(dbls, na.rm = TRUE)] <- paste0(">=", max(dbls, na.rm = TRUE)) - keep <- x[dbls == max(dbls, na.rm = TRUE) | dbls == min(dbls, na.rm = TRUE)] - x[!x %in% keep] <- gsub("[>=<]", "", x[!x %in% keep]) - } - - set_clean_class(factor(x, levels = VALID_MIC_LEVELS, ordered = TRUE), - new_class = c("mic", "ordered", "factor") + x <- as.character(unlist(x)) + } + if (isTRUE(na.rm)) { + x <- x[!is.na(x)] + } + x <- trimws2(x) + x[x == ""] <- NA + if (is.null(x.bak)) { + x.bak <- x + } + + # comma to period + x <- gsub(",", ".", x, fixed = TRUE) + # transform scientific notation + x[x %like% "[-]?[0-9]+([.][0-9]+)?e[-]?[0-9]+"] <- as.double(x[x %like% "[-]?[0-9]+([.][0-9]+)?e[-]?[0-9]+"]) + # transform Unicode for >= and <= + x <- gsub("\u2264", "<=", x, fixed = TRUE) + x <- gsub("\u2265", ">=", x, fixed = TRUE) + # remove other invalid characters + x <- gsub("[^a-zA-Z0-9.><= ]+", "", x, perl = TRUE) + # remove space between operator and number ("<= 0.002" -> "<=0.002") + x <- gsub("(<|=|>) +", "\\1", x, perl = TRUE) + # transform => to >= and =< to <= + x <- gsub("=<", "<=", x, fixed = TRUE) + x <- gsub("=>", ">=", x, fixed = TRUE) + # dots without a leading zero must start with 0 + x <- gsub("([^0-9]|^)[.]", "\\10.", x, perl = TRUE) + # values like "<=0.2560.512" should be 0.512 + x <- gsub(".*[.].*[.]", "0.", x, perl = TRUE) + # remove ending .0 + x <- gsub("[.]+0$", "", x, perl = TRUE) + # remove all after last digit + x <- gsub("[^0-9]+$", "", x, perl = TRUE) + # keep only one zero before dot + x <- gsub("0+[.]", "0.", x, perl = TRUE) + # starting 00 is probably 0.0 if there's no dot yet + x[x %unlike% "[.]"] <- gsub("^00", "0.0", x[!x %like% "[.]"]) + # remove last zeroes + x <- gsub("([.].?)0+$", "\\1", x, perl = TRUE) + x <- gsub("(.*[.])0+$", "\\10", x, perl = TRUE) + # remove ending .0 again + x[x %like% "[.]"] <- gsub("0+$", "", x[x %like% "[.]"]) + # never end with dot + x <- gsub("[.]$", "", x, perl = TRUE) + # trim it + x <- trimws2(x) + + ## previously unempty values now empty - should return a warning later on + x[x.bak != "" & x == ""] <- "invalid" + + na_before <- x[is.na(x) | x == ""] %pm>% length() + x[!x %in% VALID_MIC_LEVELS] <- NA + na_after <- x[is.na(x) | x == ""] %pm>% length() + + if (na_before != na_after) { + list_missing <- x.bak[is.na(x) & !is.na(x.bak) & x.bak != ""] %pm>% + unique() %pm>% + sort() %pm>% + vector_and(quotes = TRUE) + cur_col <- get_current_column() + warning_("in `as.mic()`: ", na_after - na_before, " result", + ifelse(na_after - na_before > 1, "s", ""), + ifelse(is.null(cur_col), "", paste0(" in column '", cur_col, "'")), + " truncated (", + round(((na_after - na_before) / length(x)) * 100), + "%) that were invalid MICs: ", + list_missing, + call = FALSE ) } + + if (keep_operators == "none" && !all(is.na(x))) { + x <- gsub("[>=<]", "", x) + } else if (keep_operators == "edges" && !all(is.na(x))) { + dbls <- as.double(gsub("[>=<]", "", x)) + x[dbls == min(dbls, na.rm = TRUE)] <- paste0("<=", min(dbls, na.rm = TRUE)) + x[dbls == max(dbls, na.rm = TRUE)] <- paste0(">=", max(dbls, na.rm = TRUE)) + keep <- x[dbls == max(dbls, na.rm = TRUE) | dbls == min(dbls, na.rm = TRUE)] + x[!x %in% keep] <- gsub("[>=<]", "", x[!x %in% keep]) + } + + set_clean_class(factor(x, levels = VALID_MIC_LEVELS, ordered = TRUE), + new_class = c("mic", "ordered", "factor")) } #' @rdname as.mic @@ -375,7 +379,7 @@ type_sum.mic <- function(x, ...) { #' @noRd print.mic <- function(x, ...) { cat("Class 'mic'", - ifelse(length(levels(x)) < length(VALID_MIC_LEVELS), font_red(" with dropped levels"), ""), + ifelse(!identical(levels(x), VALID_MIC_LEVELS), font_red(" with outdated structure - convert with `as.mic()` to update"), ""), "\n", sep = "" ) @@ -533,12 +537,23 @@ Math.mic <- function(x, ...) { #' @export Ops.mic <- function(e1, e2) { + e1_chr <- as.character(e1) + e2_chr <- character(0) e1 <- as.double(e1) if (!missing(e2)) { # when e1 is `!`, e2 is missing + e2_chr <- as.character(e2) e2 <- as.double(e2) } - # set class to numeric, because otherwise NextMethod will be factor (since mic is a factor) + if (as.character(.Generic) %in% c("<", "<=", "==", "!=", ">", ">=")) { + # make sure that <0.002 is lower than 0.002 + # and that >32 is higher than 32, but equal to >=32 + e1[e1_chr %like% "<" & e1_chr %unlike% "="] <- e1[e1_chr %like% "<" & e1_chr %unlike% "="] - 0.000001 + e1[e1_chr %like% ">" & e1_chr %unlike% "="] <- e1[e1_chr %like% ">" & e1_chr %unlike% "="] + 0.000001 + e2[e2_chr %like% "<" & e2_chr %unlike% "="] <- e2[e2_chr %like% "<" & e2_chr %unlike% "="] - 0.000001 + e2[e2_chr %like% ">" & e2_chr %unlike% "="] <- e2[e2_chr %like% ">" & e2_chr %unlike% "="] + 0.000001 + } + # set .Class to numeric, because otherwise NextMethod will be factor (since mic is a factor) .Class <- class(e1) NextMethod(.Generic) } diff --git a/R/proportion.R b/R/proportion.R index cb1de3e8..08e953ed 100644 --- a/R/proportion.R +++ b/R/proportion.R @@ -294,7 +294,7 @@ sir_confidence_interval <- function(..., # this applies the Clopper-Pearson method out <- stats::binom.test(x = x, n = n, conf.level = confidence_level)$conf.int - out <- set_clean_class(out, "double") + out <- set_clean_class(out, "numeric") if (side %in% c("left", "l", "lower", "lowest", "less", "min")) { out <- out[1] diff --git a/R/sir.R b/R/sir.R index c42018b5..8e383291 100755 --- a/R/sir.R +++ b/R/sir.R @@ -29,7 +29,7 @@ #' Translate MIC and Disk Diffusion to SIR, or Clean Existing SIR Data #' -#' @description Clean up existing SIR values, or interpret minimum inhibitory concentration (MIC) values and disk diffusion diameters according to EUCAST or CLSI. [as.sir()] transforms the input to a new class [`sir`], which is an ordered [factor] with levels `S < I < R`. +#' @description Clean up existing SIR values, or interpret minimum inhibitory concentration (MIC) values and disk diffusion diameters according to EUCAST or CLSI. [as.sir()] transforms the input to a new class [`sir`], which is an ordered [factor]. #' #' Currently breakpoints are available: #' - For **clinical microbiology** from EUCAST `r min(as.integer(gsub("[^0-9]", "", subset(AMR::clinical_breakpoints, guideline %like% "EUCAST" & type == "human")$guideline)))`-`r max(as.integer(gsub("[^0-9]", "", subset(AMR::clinical_breakpoints, guideline %like% "EUCAST" & type == "human")$guideline)))` and CLSI `r min(as.integer(gsub("[^0-9]", "", subset(AMR::clinical_breakpoints, guideline %like% "CLSI" & type == "human")$guideline)))`-`r max(as.integer(gsub("[^0-9]", "", subset(AMR::clinical_breakpoints, guideline %like% "CLSI" & type == "human")$guideline)))`; @@ -326,7 +326,7 @@ as.sir.default <- function(x, ...) { x.bak <- x x <- as.character(x) # this is needed to prevent the vctrs pkg from throwing an error - if (inherits(x.bak, c("integer", "numeric", "double")) && all(x %in% c(1:3, NA))) { + if (inherits(x.bak, c("numeric", "integer")) && all(x %in% c(1:3, NA))) { # support haven package for importing e.g., from SPSS - it adds the 'labels' attribute lbls <- attributes(x.bak)$labels if (!is.null(lbls) && all(c("S", "I", "R") %in% names(lbls)) && all(c(1:3) %in% lbls)) { diff --git a/R/vctrs.R b/R/vctrs.R index e3737ff8..522d2fd3 100755 --- a/R/vctrs.R +++ b/R/vctrs.R @@ -102,6 +102,12 @@ vec_cast.mo.character <- function(x, to, ...) { } # S3: disk ---- +vec_ptype_full.disk <- function(x, ...) { + "disk" +} +vec_ptype_abbr.disk <- function(x, ...) { + "dsk" +} vec_ptype2.disk.default <- function (x, y, ..., x_arg = "", y_arg = "") { x } @@ -129,10 +135,16 @@ vec_cast.disk.character <- function(x, to, ...) { # S3: mic ---- vec_ptype2.mic.default <- function (x, y, ..., x_arg = "", y_arg = "") { - x + # this will make sure that currently implemented MIC levels are returned + as.mic(x) } vec_ptype2.mic.mic <- function(x, y, ...) { - x + # this will make sure that currently implemented MIC levels are returned + as.mic(x) +} +vec_cast.mic.mic <- function(x, to, ...) { + # this will make sure that currently implemented MIC levels are returned + as.mic(x) } vec_cast.character.mic <- function(x, to, ...) { as.character(x) diff --git a/R/zzz.R b/R/zzz.R index ea9d093e..0054b6d2 100755 --- a/R/zzz.R +++ b/R/zzz.R @@ -106,7 +106,6 @@ if (pkg_is_available("cli")) { s3_register("pillar::type_sum", "mo") s3_register("pillar::type_sum", "sir") s3_register("pillar::type_sum", "mic") - s3_register("pillar::type_sum", "disk") # Support for frequency tables from the cleaner package s3_register("cleaner::freq", "mo") s3_register("cleaner::freq", "sir") @@ -156,6 +155,8 @@ if (pkg_is_available("cli")) { s3_register("vctrs::vec_cast", "character.mo") s3_register("vctrs::vec_cast", "mo.character") # S3: disk + s3_register("vctrs::vec_ptype_full", "disk") # returns "disk" + s3_register("vctrs::vec_ptype_abbr", "disk") # returns "dsk" s3_register("vctrs::vec_ptype2", "disk.default") s3_register("vctrs::vec_ptype2", "disk.disk") s3_register("vctrs::vec_cast", "integer.disk") @@ -173,6 +174,7 @@ if (pkg_is_available("cli")) { s3_register("vctrs::vec_cast", "mic.character") s3_register("vctrs::vec_cast", "mic.double") s3_register("vctrs::vec_cast", "mic.integer") + s3_register("vctrs::vec_cast", "mic.mic") s3_register("vctrs::vec_math", "mic") s3_register("vctrs::vec_arith", "mic") # S3: sir diff --git a/data-raw/eucast_rules.tsv b/data-raw/eucast_rules.tsv index 08f26829..5be538cb 100644 --- a/data-raw/eucast_rules.tsv +++ b/data-raw/eucast_rules.tsv @@ -2,7 +2,7 @@ # For editing this EUCAST reference file, these values can all be used for targeting antibiotics: # aminoglycosides, aminopenicillins, antifungals, antimycobacterials, betalactams, carbapenems, cephalosporins, cephalosporins_1st, cephalosporins_2nd, cephalosporins_3rd, cephalosporins_4th, cephalosporins_5th, cephalosporins_except_CAZ, fluoroquinolones, glycopeptides, glycopeptides_except_lipo, lincosamides, lipoglycopeptides, macrolides, oxazolidinones, penicillins, polymyxins, quinolones, streptogramins, tetracyclines, tetracyclines_except_TGC, trimethoprims, ureidopenicillins # and all separate EARS-Net letter codes such as AMC. They can be separated by comma: 'AMC, fluoroquinolones'. -# The 'if_mo_property' column can be any column name from the AMR::microorganisms data set, or "genus_species" or "gramstain". +# The 'if_mo_property' column can be any column name from the AMR::microorganisms data set, or 'genus_species' or 'gramstain'. # The like.is.one_of column must be 'like' or 'is' or 'one_of' ('like' will read the 'this_value' column as regular expression) # The EUCAST guideline contains references to the 'Burkholderia cepacia complex'. All species in this group are noted on the 'B.cepacia' sheet of the EUCAST Clinical Breakpoint v.10.0 Excel file of 2020 and later # >>>>> IF YOU WANT TO IMPORT THIS FILE INTO YOUR OWN SOFTWARE, HAVE THE FIRST 9 LINES SKIPPED <<<<< diff --git a/inst/tinytest/test-mic.R b/inst/tinytest/test-mic.R index 36d9bdd7..061daef2 100755 --- a/inst/tinytest/test-mic.R +++ b/inst/tinytest/test-mic.R @@ -142,10 +142,35 @@ suppressWarnings(expect_identical(el1^el2, el1_double^el2_double)) suppressWarnings(expect_identical(el1 %% el2, el1_double %% el2_double)) suppressWarnings(expect_identical(el1 %/% el2, el1_double %/% el2_double)) suppressWarnings(expect_identical(el1 & el2, el1_double & el2_double)) -suppressWarnings(expect_identical(el1 | el2, el1_double | el2_double)) -suppressWarnings(expect_identical(el1 == el2, el1_double == el2_double)) -suppressWarnings(expect_identical(el1 != el2, el1_double != el2_double)) -suppressWarnings(expect_identical(el1 < el2, el1_double < el2_double)) -suppressWarnings(expect_identical(el1 <= el2, el1_double <= el2_double)) -suppressWarnings(expect_identical(el1 >= el2, el1_double >= el2_double)) -suppressWarnings(expect_identical(el1 > el2, el1_double > el2_double)) + +# for comparison operators, be more strict: +expect_true(as.mic(">32") > as.mic(32)) +expect_true(as.mic(">32") >= as.mic(32)) +expect_true(as.mic(">32") >= as.mic("<32")) +expect_true(as.mic(">32") >= as.mic("<=32")) +expect_true(as.mic(">32") > as.mic("<=32")) + +expect_false(as.mic("32") > as.mic(32)) +expect_true(as.mic("32") >= as.mic(32)) +expect_true(as.mic("32") >= as.mic("<32")) +expect_true(as.mic("32") >= as.mic("<=32")) +expect_false(as.mic("32") > as.mic("<=32")) + +expect_true(as.mic("32") == as.mic(32)) +expect_true(as.mic("32") == as.mic(32)) +expect_false(as.mic("32") == as.mic("<32")) +expect_true(as.mic("32") == as.mic("<=32")) +expect_true(as.mic("32") == as.mic("<=32")) + +expect_false(as.mic(">32") < as.mic(32)) +expect_false(as.mic(">32") <= as.mic(32)) +expect_false(as.mic(">32") <= as.mic("<32")) +expect_false(as.mic(">32") <= as.mic("<=32")) +expect_false(as.mic(">32") < as.mic("<=32")) + +expect_false(as.mic("32") < as.mic(32)) +expect_true(as.mic("32") <= as.mic(32)) +expect_false(as.mic("32") <= as.mic("<32")) +expect_true(as.mic("32") <= as.mic("<=32")) +expect_false(as.mic("32") < as.mic("<=32")) + diff --git a/man/as.sir.Rd b/man/as.sir.Rd index dac300f8..6252edd3 100644 --- a/man/as.sir.Rd +++ b/man/as.sir.Rd @@ -115,7 +115,7 @@ sir_interpretation_history(clean = FALSE) Ordered \link{factor} with new class \code{sir} } \description{ -Clean up existing SIR values, or interpret minimum inhibitory concentration (MIC) values and disk diffusion diameters according to EUCAST or CLSI. \code{\link[=as.sir]{as.sir()}} transforms the input to a new class \code{\link{sir}}, which is an ordered \link{factor} with levels \verb{S < I < R}. +Clean up existing SIR values, or interpret minimum inhibitory concentration (MIC) values and disk diffusion diameters according to EUCAST or CLSI. \code{\link[=as.sir]{as.sir()}} transforms the input to a new class \code{\link{sir}}, which is an ordered \link{factor}. Currently breakpoints are available: \itemize{