diff --git a/DESCRIPTION b/DESCRIPTION index 140c7b25..787073fb 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: AMR -Version: 1.5.0.9007 -Date: 2021-01-18 +Version: 1.5.0.9008 +Date: 2021-01-22 Title: Antimicrobial Resistance Analysis Authors@R: c( person(role = c("aut", "cre"), diff --git a/NAMESPACE b/NAMESPACE index b5b96919..5caeab7e 100755 --- a/NAMESPACE +++ b/NAMESPACE @@ -22,6 +22,7 @@ S3method("[[<-",isolate_identifier) S3method("[[<-",mic) S3method("[[<-",mo) S3method("[[<-",rsi) +S3method(all.equal,isolate_identifier) S3method(as.data.frame,ab) S3method(as.data.frame,mo) S3method(as.double,mic) diff --git a/NEWS.md b/NEWS.md index 73246277..5cbbc5b5 100755 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,5 @@ -# AMR 1.5.0.9007 -## Last updated: 18 January 2021 +# AMR 1.5.0.9008 +## Last updated: 22 January 2021 ### New * Support for EUCAST Clinical Breakpoints v11.0 (2021), effective in the `eucast_rules()` function and in `as.rsi()` to interpret MIC and disk diffusion values. This is now the default guideline in this package. @@ -32,10 +32,12 @@ * Updated the data set `microorganisms.codes` (which contains popular LIS and WHONET codes for microorganisms) for some species of *Mycobacterium* that previously incorrectly returned *M. africanum* * Added Pretomanid (PMD, J04AK08) to the `antibiotics` data set * WHONET code `"PNV"` will now correctly be interpreted as `PHN`, the antibiotic code for phenoxymethylpenicillin ('peni V') -* Fix for verbose output of `mdro(..., verbose = TRUE)` for German guideline (3MGRN and 4MGRN) and *P. aeruginosa* in Dutch guideline (BRMO) +* Fix for verbose output of `mdro(..., verbose = TRUE)` for German guideline (3MGRN and 4MGRN) and Dutch guideline (BRMO, only *P. aeruginosa*) +* `is.rsi.eligible()` now returns `FALSE` immediately if the input does not contain any of the values "R", "S" or "I". This drastically improves speed, also for a lot of other functions that rely on automatic determination of antibiotic columns. ### Other * Big documentation updates +* Loading the package (i.e., `library(AMR)`) now is ~50 times faster than before # AMR 1.5.0 diff --git a/R/aa_helper_functions.R b/R/aa_helper_functions.R index c8fc76ae..15b470ef 100755 --- a/R/aa_helper_functions.R +++ b/R/aa_helper_functions.R @@ -585,7 +585,7 @@ get_current_data <- function(arg_name, call) { stop_("argument `", arg_name, "` is missing with no default", call = call) } } - + # try a (base R) method, by going over the complete system call stack with sys.frames() not_set <- TRUE frms <- lapply(sys.frames(), function(el) { @@ -615,6 +615,7 @@ get_current_data <- function(arg_name, call) { NULL } }) + vars_df <- tryCatch(frms[[which(!vapply(FUN.VALUE = logical(1), frms, is.null))]], error = function(e) NULL) if (is.data.frame(vars_df)) { return(vars_df) diff --git a/R/ab_class_selectors.R b/R/ab_class_selectors.R index db3a62ba..ddbcfc21 100644 --- a/R/ab_class_selectors.R +++ b/R/ab_class_selectors.R @@ -173,7 +173,15 @@ ab_selector <- function(ab_class, function_name) { } vars_df <- get_current_data(arg_name = NA, call = -3) - ab_in_data <- get_column_abx(vars_df, info = FALSE) + + # improve speed here so it will only run once when e.g. in one select call + if (!identical(pkg_env$ab_selector, unique_call_id())) { + ab_in_data <- get_column_abx(vars_df, info = FALSE) + pkg_env$ab_selector <- unique_call_id() + pkg_env$ab_selector_cols <- ab_in_data + } else { + ab_in_data <- pkg_env$ab_selector_cols + } if (length(ab_in_data) == 0) { message_("No antimicrobial agents found.") @@ -199,13 +207,14 @@ ab_selector <- function(ab_class, function_name) { } else { agents_formatted <- paste0("column '", font_bold(agents, collapse = NULL), "'") agents_names <- ab_name(names(agents), tolower = TRUE, language = NULL) - agents_formatted[agents != agents_names] <- paste0(agents_formatted[agents != agents_names], - " (", agents_names[agents != agents_names], ")") + need_name <- tolower(agents) != tolower(agents_names) + agents_formatted[need_name] <- paste0(agents_formatted[need_name], + " (", agents_names[need_name], ")") message_("Selecting ", ab_group, ": ", paste(agents_formatted, collapse = ", "), as_note = FALSE, extra_indent = nchar(paste0("Selecting ", ab_group, ": "))) } - remember_thrown_message(function_name) - } + remember_thrown_message(function_name) + } unname(agents) } diff --git a/R/eucast_rules.R b/R/eucast_rules.R index a148f68f..37c1e1a9 100755 --- a/R/eucast_rules.R +++ b/R/eucast_rules.R @@ -1049,6 +1049,7 @@ eucast_rules <- function(x, warn_lacking_rsi_class <- unique(warn_lacking_rsi_class) warning_("Not all columns with antimicrobial results are of class . Transform them on beforehand, with e.g.:\n", " ", x_deparsed, " %>% mutate_if(is.rsi.eligible, as.rsi)\n", + " ", x_deparsed, " %>% mutate(across((is.rsi.eligible), as.rsi))\n", " ", x_deparsed, " %>% as.rsi(", ifelse(length(warn_lacking_rsi_class) == 1, warn_lacking_rsi_class, paste0(warn_lacking_rsi_class[1], ":", warn_lacking_rsi_class[length(warn_lacking_rsi_class)])), diff --git a/R/guess_ab_col.R b/R/guess_ab_col.R index b273b6a2..a48b72ab 100755 --- a/R/guess_ab_col.R +++ b/R/guess_ab_col.R @@ -137,25 +137,25 @@ get_column_abx <- function(x, } else if (info == TRUE) { message_("...", appendLF = FALSE, as_note = FALSE) } - x_bak <- x + # only check columns that are a valid AB code, ATC code, name, abbreviation or synonym, # or already have the class (as.rsi) # and that they have no more than 50% invalid values vectr_antibiotics <- unique(toupper(unlist(antibiotics[, c("ab", "atc", "name", "abbreviations", "synonyms")]))) vectr_antibiotics <- vectr_antibiotics[!is.na(vectr_antibiotics) & nchar(vectr_antibiotics) >= 3] - x_columns <- vapply(FUN.VALUE = character(1), colnames(x), function(col, df = x_bak) { + x_columns <- vapply(FUN.VALUE = character(1), colnames(x), function(col, df = x) { if (toupper(col) %in% vectr_antibiotics || - is.rsi(as.data.frame(df, stringsAsFactors = FALSE)[, col, drop = TRUE]) || - is.rsi.eligible(as.data.frame(df, stringsAsFactors = FALSE)[, col, drop = TRUE], - threshold = 0.5)) { + is.rsi(x[, col, drop = TRUE]) || + is.rsi.eligible(x[, col, drop = TRUE], threshold = 0.5) + ) { return(col) } else { return(NA_character_) } }) + x_columns <- x_columns[!is.na(x_columns)] x <- x[, x_columns, drop = FALSE] # without drop = TRUE, x will become a vector when x_columns is length 1 - df_trans <- data.frame(colnames = colnames(x), abcode = suppressWarnings(as.ab(colnames(x), info = FALSE)), stringsAsFactors = FALSE) @@ -217,7 +217,6 @@ get_column_abx <- function(x, } } - if (!is.null(hard_dependencies)) { hard_dependencies <- unique(hard_dependencies) if (!all(hard_dependencies %in% names(x))) { diff --git a/R/isolate_identifier.R b/R/isolate_identifier.R index 8a2ceed8..94a2c49c 100644 --- a/R/isolate_identifier.R +++ b/R/isolate_identifier.R @@ -26,9 +26,10 @@ #' Create Identifier of an Isolate #' #' This function will paste the microorganism code with all antimicrobial results into one string for each row in a data set. This is useful to compare isolates, e.g. between institutions or regions, when there is no genotyping available. -#' @inheritSection lifecycle Maturing Lifecycle +#' @inheritSection lifecycle Experimental Lifecycle #' @inheritParams eucast_rules #' @param cols_ab a character vector of column names of `x`, or (a combination with) an [antibiotic selector function]([ab_class()]), such as [carbapenems()] and [aminoglycosides()] +#' @rdname isolate_identifier #' @export #' @inheritSection AMR Read more on Our Website! #' @examples @@ -43,7 +44,12 @@ isolate_identifier <- function(x, col_mo = NULL, cols_ab = NULL) { if (is.null(col_mo)) { col_mo <- search_type_in_df(x, "mo") + if (is.null(col_mo)) { + # no column found, then ignore the argument + col_mo <- FALSE + } } + if (isFALSE(col_mo)) { # is FALSE then ignore mo column x$col_mo <- "" @@ -60,14 +66,77 @@ isolate_identifier <- function(x, col_mo = NULL, cols_ab = NULL) { # tryCatch adds 4 calls, so total is -5 error = function(e) stop_(e$message, call = -5)) } - if (length(cols_ab) == 0) { - warning_("no columns with antimicrobial agents found", call = TRUE) + + # cope with empty values + if (length(cols_ab) == 0 && all(x[, col_mo, drop = TRUE] == "", na.rm = TRUE)) { + warning_("in isolate_identifier(): no column with microorganisms and no columns with antimicrobial agents found", call = FALSE) + } else if (length(cols_ab) == 0) { + warning_("in isolate_identifier(): no columns with antimicrobial agents found", call = FALSE) } out <- x[, c(col_mo, cols_ab), drop = FALSE] out <- do.call(paste, c(out, sep = "")) out <- gsub("NA", ".", out, fixed = TRUE) - set_clean_class(out, new_class = c("isolate_identifier", "character")) + out <- set_clean_class(out, new_class = c("isolate_identifier", "character")) + attr(out, "ab") <- cols_ab + out +} + +#' @method all.equal isolate_identifier +#' @rdname isolate_identifier +#' @export +all.equal.isolate_identifier <- function(target, current, ignore_empty_results = TRUE, ...) { + if (isTRUE(all.equal.character(target, current))) { + return(TRUE) + } + # vectorise over both target and current + if (length(target) > 1 && length(current) == 1) { + current <- rep(current, length(target)) + } else if (length(current) > 1 && length(target) == 1) { + target <- rep(target, length(current)) + } + stop_if(length(target) != length(current), + "length of `target` and `current` must be the same, or one must be 1") + + get_vector <- function(x) { + if (grepl("|", x, fixed = TRUE)) { + mo <- gsub("(.*)\\|.*", "\\1", x) + } else { + mo <- NULL + } + if (grepl("|", x, fixed = TRUE)) { + ab <- gsub(".*\\|(.*)", "\\1", x) + } else { + ab <- x + } + ab <- strsplit(ab, "")[[1L]] + if (is.null(mo)) { + out <- as.character(ab) + names(out) <- attributes(x)$ab + } else { + out <- as.character(c(mo, ab)) + names(out) <- c("mo", attributes(x)$ab) + } + out + } + + # run it + for (i in seq_len(length(target))) { + if (i == 1) { + df <- data.frame(object = paste0(c("target[", "current["), i, "]")) + } + trgt <- get_vector(target[i]) + crnt <- get_vector(current[i]) + if (ignore_empty_results == TRUE) { + diff <- names(trgt[trgt != crnt & trgt != "." & crnt != "."]) + } else { + diff <- names(trgt[trgt != crnt]) + } + + } + + stop("THIS FUNCTION IS WORK IN PROGRESS AND NOT AVAILABLE IN THIS BETA VERSION") + } #' @method print isolate_identifier diff --git a/R/rsi.R b/R/rsi.R index 47d1a149..f30b038f 100755 --- a/R/rsi.R +++ b/R/rsi.R @@ -49,16 +49,16 @@ #' 2. For **interpreting minimum inhibitory concentration (MIC) values** according to EUCAST or CLSI. You must clean your MIC values first using [as.mic()], that also gives your columns the new data class [`mic`]. Also, be sure to have a column with microorganism names or codes. It will be found automatically, but can be set manually using the `mo` argument. #' * Using `dplyr`, R/SI interpretation can be done very easily with either: #' ``` -#' your_data %>% mutate_if(is.mic, as.rsi) # until dplyr 1.0.0 -#' your_data %>% mutate(across(where(is.mic), as.rsi)) # since dplyr 1.0.0 +#' your_data %>% mutate_if(is.mic, as.rsi) # until dplyr 1.0.0 +#' your_data %>% mutate(across((is.mic), as.rsi)) # since dplyr 1.0.0 #' ``` #' * Operators like "<=" will be stripped before interpretation. 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 might in this case return "S" or "I". #' #' 3. For **interpreting disk diffusion diameters** according to EUCAST or CLSI. You must clean your disk zones first using [as.disk()], that also gives your columns the new data class [`disk`]. Also, be sure to have a column with microorganism names or codes. It will be found automatically, but can be set manually using the `mo` argument. #' * Using `dplyr`, R/SI interpretation can be done very easily with either: #' ``` -#' your_data %>% mutate_if(is.disk, as.rsi) # until dplyr 1.0.0 -#' your_data %>% mutate(across(where(is.disk), as.rsi)) # since dplyr 1.0.0 +#' your_data %>% mutate_if(is.disk, as.rsi) # until dplyr 1.0.0 +#' your_data %>% mutate(across((is.disk), as.rsi)) # since dplyr 1.0.0 #' ``` #' #' 4. For **interpreting a complete data set**, with automatic determination of MIC values, disk diffusion diameters, microorganism names or codes, and antimicrobial test results. This is done very simply by running `as.rsi(data)`. @@ -133,7 +133,7 @@ #' if (require("dplyr")) { #' df %>% mutate_if(is.mic, as.rsi) #' df %>% mutate_if(function(x) is.mic(x) | is.disk(x), as.rsi) -#' df %>% mutate(across(where(is.mic), as.rsi)) +#' df %>% mutate(across((is.mic), as.rsi)) #' df %>% mutate_at(vars(AMP:TOB), as.rsi) #' df %>% mutate(across(AMP:TOB, as.rsi)) #' @@ -179,7 +179,7 @@ #' #' # note: from dplyr 1.0.0 on, this will be: #' # example_isolates %>% -#' # mutate(across(where(is.rsi.eligible), as.rsi)) +#' # mutate(across((is.rsi.eligible), as.rsi)) #' } #' } as.rsi <- function(x, ...) { @@ -202,14 +202,19 @@ is.rsi.eligible <- function(x, threshold = 0.05) { "numeric", "integer", "mo", + "ab", "Date", - "POSIXct", + "POSIXt", "rsi", "raw", - "hms") + "hms", + "mic", + "disk") %in% class(x))) { # no transformation needed - FALSE + return(FALSE) + } else if (!any(c("R", "S", "I") %in% x, na.rm = TRUE)) { + return(FALSE) } else { x <- x[!is.na(x) & !is.null(x) & !identical(x, "")] if (length(x) == 0) { diff --git a/R/rsi_calc.R b/R/rsi_calc.R index d9ec0dd8..e55c1949 100755 --- a/R/rsi_calc.R +++ b/R/rsi_calc.R @@ -148,7 +148,9 @@ rsi_calc <- function(..., if (print_warning == TRUE) { if (message_not_thrown_before("rsi_calc")) { - warning_("Increase speed by transforming to class on beforehand: your_data %>% mutate_if(is.rsi.eligible, as.rsi)", + warning_("Increase speed by transforming to class on beforehand:\n", + " your_data %>% mutate_if(is.rsi.eligible, as.rsi)\n", + " your_data %>% mutate(across((is.rsi.eligible), as.rsi))", call = FALSE) remember_thrown_message("rsi_calc") } diff --git a/R/sysdata.rda b/R/sysdata.rda index 9c6d291d..d3d3c27a 100644 Binary files a/R/sysdata.rda and b/R/sysdata.rda differ diff --git a/R/zzz.R b/R/zzz.R index 7ed13808..577d377f 100755 --- a/R/zzz.R +++ b/R/zzz.R @@ -28,35 +28,6 @@ pkg_env <- new.env(hash = FALSE) pkg_env$mo_failed <- character(0) .onLoad <- function(libname, pkgname) { - - assign(x = "AB_lookup", - value = create_AB_lookup(), - envir = asNamespace("AMR")) - - assign(x = "MO_lookup", - value = create_MO_lookup(), - envir = asNamespace("AMR")) - - assign(x = "MO.old_lookup", - value = create_MO.old_lookup(), - envir = asNamespace("AMR")) - - assign(x = "INTRINSIC_R", - value = create_intr_resistance(), - envir = asNamespace("AMR")) - - assign(x = "LANGUAGES_SUPPORTED", - value = sort(c("en", unique(translations_file$lang))), - envir = asNamespace("AMR")) - - assign(x = "MO_CONS", - value = create_species_cons_cops("CoNS"), - envir = asNamespace("AMR")) - - assign(x = "MO_COPS", - value = create_species_cons_cops("CoPS"), - envir = asNamespace("AMR")) - # Support for tibble headers (type_sum) and tibble columns content (pillar_shaft) # without the need to depend on other packages. This was suggested by the # developers of the vctrs package: @@ -102,89 +73,5 @@ pkg_env$mo_failed <- character(0) font_bold("options(AMR_silentstart = TRUE)"), "]")) } -create_intr_resistance <- function() { - # for mo_is_intrinsic_resistant() - saves a lot of time when executed on this vector - paste(AMR::microorganisms[match(AMR::intrinsic_resistant$microorganism, AMR::microorganisms$fullname), "mo", drop = TRUE], - AMR::antibiotics[match(AMR::intrinsic_resistant$antibiotic, AMR::antibiotics$name), "ab", drop = TRUE]) -} -create_species_cons_cops <- function(type = c("CoNS", "CoPS")) { - # Determination of which staphylococcal species are CoNS/CoPS according to: - # - Becker et al. 2014, PMID 25278577 - # - Becker et al. 2019, PMID 30872103 - # - Becker et al. 2020, PMID 32056452 - # this function returns class - MO_staph <- AMR::microorganisms - MO_staph <- MO_staph[which(MO_staph$genus == "Staphylococcus"), , drop = FALSE] - if (type == "CoNS") { - MO_staph[which(MO_staph$species %in% c("coagulase-negative", "argensis", "arlettae", - "auricularis", "caeli", "capitis", "caprae", - "carnosus", "chromogenes", "cohnii", "condimenti", - "debuckii", "devriesei", "edaphicus", "epidermidis", - "equorum", "felis", "fleurettii", "gallinarum", - "haemolyticus", "hominis", "jettensis", "kloosii", - "lentus", "lugdunensis", "massiliensis", "microti", - "muscae", "nepalensis", "pasteuri", "petrasii", - "pettenkoferi", "piscifermentans", "pseudoxylosus", - "rostri", "saccharolyticus", "saprophyticus", - "sciuri", "simulans", "stepanovicii", "succinus", - "vitulinus", "warneri", "xylosus") - | (MO_staph$species == "schleiferi" & MO_staph$subspecies %in% c("schleiferi", ""))), - "mo", drop = TRUE] - } else if (type == "CoPS") { - MO_staph[which(MO_staph$species %in% c("coagulase-positive", - "simiae", "agnetis", - "delphini", "lutrae", - "hyicus", "intermedius", - "pseudintermedius", "pseudointermedius", - "schweitzeri", "argenteus") - | (MO_staph$species == "schleiferi" & MO_staph$subspecies == "coagulans")), - "mo", drop = TRUE] - } -} -create_AB_lookup <- function() { - AB_lookup <- AMR::antibiotics - AB_lookup$generalised_name <- generalise_antibiotic_name(AB_lookup$name) - AB_lookup$generalised_synonyms <- lapply(AB_lookup$synonyms, generalise_antibiotic_name) - AB_lookup$generalised_abbreviations <- lapply(AB_lookup$abbreviations, generalise_antibiotic_name) - AB_lookup$generalised_loinc <- lapply(AB_lookup$loinc, generalise_antibiotic_name) - AB_lookup -} - -create_MO_lookup <- function() { - MO_lookup <- AMR::microorganisms - - MO_lookup$kingdom_index <- NA_real_ - MO_lookup[which(MO_lookup$kingdom == "Bacteria" | MO_lookup$mo == "UNKNOWN"), "kingdom_index"] <- 1 - MO_lookup[which(MO_lookup$kingdom == "Fungi"), "kingdom_index"] <- 2 - MO_lookup[which(MO_lookup$kingdom == "Protozoa"), "kingdom_index"] <- 3 - MO_lookup[which(MO_lookup$kingdom == "Archaea"), "kingdom_index"] <- 4 - # all the rest - MO_lookup[which(is.na(MO_lookup$kingdom_index)), "kingdom_index"] <- 5 - - # use this paste instead of `fullname` to work with Viridans Group Streptococci, etc. - MO_lookup$fullname_lower <- tolower(trimws(paste(MO_lookup$genus, - MO_lookup$species, - MO_lookup$subspecies))) - ind <- MO_lookup$genus == "" | grepl("^[(]unknown ", MO_lookup$fullname) - MO_lookup[ind, "fullname_lower"] <- tolower(MO_lookup[ind, "fullname"]) - MO_lookup$fullname_lower <- trimws(gsub("[^.a-z0-9/ \\-]+", "", MO_lookup$fullname_lower, perl = TRUE)) - - # add a column with only "e coli" like combinations - MO_lookup$g_species <- gsub("^([a-z])[a-z]+ ([a-z]+) ?.*", "\\1 \\2", MO_lookup$fullname_lower, perl = TRUE) - - # so arrange data on prevalence first, then kingdom, then full name - MO_lookup[order(MO_lookup$prevalence, MO_lookup$kingdom_index, MO_lookup$fullname_lower), ] -} - -create_MO.old_lookup <- function() { - MO.old_lookup <- AMR::microorganisms.old - MO.old_lookup$fullname_lower <- trimws(gsub("[^.a-z0-9/ \\-]+", "", tolower(trimws(MO.old_lookup$fullname)))) - - # add a column with only "e coli"-like combinations - MO.old_lookup$g_species <- trimws(gsub("^([a-z])[a-z]+ ([a-z]+) ?.*", "\\1 \\2", MO.old_lookup$fullname_lower)) - - # so arrange data on prevalence first, then full name - MO.old_lookup[order(MO.old_lookup$prevalence, MO.old_lookup$fullname_lower), ] -} diff --git a/cran-comments.md b/cran-comments.md index 823a18bb..d4177285 100644 --- a/cran-comments.md +++ b/cran-comments.md @@ -1 +1 @@ -* Since version 0.3.0 (2018-08-14), CHECK returns a NOTE for having a data directory over 3 MB. This is needed to offer users reference data for the complete taxonomy of microorganisms - one of the most important features of this package. +* Ever since one of the first CRAN releases, CHECK returns a NOTE for having a data and R directory over 3 MB. This is needed to offer users reference data for the complete taxonomy of microorganisms - one of the most important features of this package. diff --git a/data-raw/AMR_1.5.0.9007.tar.gz b/data-raw/AMR_1.5.0.9007.tar.gz deleted file mode 100644 index af5e782e..00000000 Binary files a/data-raw/AMR_1.5.0.9007.tar.gz and /dev/null differ diff --git a/data-raw/AMR_1.5.0.9008.tar.gz b/data-raw/AMR_1.5.0.9008.tar.gz new file mode 100644 index 00000000..231e2b61 Binary files /dev/null and b/data-raw/AMR_1.5.0.9008.tar.gz differ diff --git a/data-raw/internals.R b/data-raw/internals.R index 7f45b666..10203ebc 100644 --- a/data-raw/internals.R +++ b/data-raw/internals.R @@ -23,12 +23,108 @@ # how to conduct AMR analysis: https://msberends.github.io/AMR/ # # ==================================================================== # -# Run this file to update the package using: ------------------------------- +# Run this file to update the package using: # source("data-raw/internals.R") -# -------------------------------------------------------------------------- + +library(dplyr, warn.conflicts = FALSE) +devtools::load_all(quiet = TRUE) + +old_globalenv <- ls(envir = globalenv()) + +# Helper functions -------------------------------------------------------- + +create_species_cons_cops <- function(type = c("CoNS", "CoPS")) { + # Determination of which staphylococcal species are CoNS/CoPS according to: + # - Becker et al. 2014, PMID 25278577 + # - Becker et al. 2019, PMID 30872103 + # - Becker et al. 2020, PMID 32056452 + # this function returns class + MO_staph <- AMR::microorganisms + MO_staph <- MO_staph[which(MO_staph$genus == "Staphylococcus"), , drop = FALSE] + if (type == "CoNS") { + MO_staph[which(MO_staph$species %in% c("coagulase-negative", "argensis", "arlettae", + "auricularis", "caeli", "capitis", "caprae", + "carnosus", "chromogenes", "cohnii", "condimenti", + "debuckii", "devriesei", "edaphicus", "epidermidis", + "equorum", "felis", "fleurettii", "gallinarum", + "haemolyticus", "hominis", "jettensis", "kloosii", + "lentus", "lugdunensis", "massiliensis", "microti", + "muscae", "nepalensis", "pasteuri", "petrasii", + "pettenkoferi", "piscifermentans", "pseudoxylosus", + "rostri", "saccharolyticus", "saprophyticus", + "sciuri", "simulans", "stepanovicii", "succinus", + "vitulinus", "warneri", "xylosus") + | (MO_staph$species == "schleiferi" & MO_staph$subspecies %in% c("schleiferi", ""))), + "mo", drop = TRUE] + } else if (type == "CoPS") { + MO_staph[which(MO_staph$species %in% c("coagulase-positive", + "simiae", "agnetis", + "delphini", "lutrae", + "hyicus", "intermedius", + "pseudintermedius", "pseudointermedius", + "schweitzeri", "argenteus") + | (MO_staph$species == "schleiferi" & MO_staph$subspecies == "coagulans")), + "mo", drop = TRUE] + } +} + +create_AB_lookup <- function() { + AB_lookup <- AMR::antibiotics + AB_lookup$generalised_name <- generalise_antibiotic_name(AB_lookup$name) + AB_lookup$generalised_synonyms <- lapply(AB_lookup$synonyms, generalise_antibiotic_name) + AB_lookup$generalised_abbreviations <- lapply(AB_lookup$abbreviations, generalise_antibiotic_name) + AB_lookup$generalised_loinc <- lapply(AB_lookup$loinc, generalise_antibiotic_name) + AB_lookup +} + +create_MO_lookup <- function() { + MO_lookup <- AMR::microorganisms + + MO_lookup$kingdom_index <- NA_real_ + MO_lookup[which(MO_lookup$kingdom == "Bacteria" | MO_lookup$mo == "UNKNOWN"), "kingdom_index"] <- 1 + MO_lookup[which(MO_lookup$kingdom == "Fungi"), "kingdom_index"] <- 2 + MO_lookup[which(MO_lookup$kingdom == "Protozoa"), "kingdom_index"] <- 3 + MO_lookup[which(MO_lookup$kingdom == "Archaea"), "kingdom_index"] <- 4 + # all the rest + MO_lookup[which(is.na(MO_lookup$kingdom_index)), "kingdom_index"] <- 5 + + # use this paste instead of `fullname` to work with Viridans Group Streptococci, etc. + MO_lookup$fullname_lower <- tolower(trimws(paste(MO_lookup$genus, + MO_lookup$species, + MO_lookup$subspecies))) + ind <- MO_lookup$genus == "" | grepl("^[(]unknown ", MO_lookup$fullname) + MO_lookup[ind, "fullname_lower"] <- tolower(MO_lookup[ind, "fullname"]) + MO_lookup$fullname_lower <- trimws(gsub("[^.a-z0-9/ \\-]+", "", MO_lookup$fullname_lower, perl = TRUE)) + + # add a column with only "e coli" like combinations + MO_lookup$g_species <- gsub("^([a-z])[a-z]+ ([a-z]+) ?.*", "\\1 \\2", MO_lookup$fullname_lower, perl = TRUE) + + # so arrange data on prevalence first, then kingdom, then full name + MO_lookup[order(MO_lookup$prevalence, MO_lookup$kingdom_index, MO_lookup$fullname_lower), ] +} + +create_MO.old_lookup <- function() { + MO.old_lookup <- AMR::microorganisms.old + MO.old_lookup$fullname_lower <- trimws(gsub("[^.a-z0-9/ \\-]+", "", tolower(trimws(MO.old_lookup$fullname)))) + + # add a column with only "e coli"-like combinations + MO.old_lookup$g_species <- trimws(gsub("^([a-z])[a-z]+ ([a-z]+) ?.*", "\\1 \\2", MO.old_lookup$fullname_lower)) + + # so arrange data on prevalence first, then full name + MO.old_lookup[order(MO.old_lookup$prevalence, MO.old_lookup$fullname_lower), ] +} + +create_intr_resistance <- function() { + # for mo_is_intrinsic_resistant() - saves a lot of time when executed on this vector + paste(AMR::microorganisms[match(AMR::intrinsic_resistant$microorganism, AMR::microorganisms$fullname), "mo", drop = TRUE], + AMR::antibiotics[match(AMR::intrinsic_resistant$antibiotic, AMR::antibiotics$name), "ab", drop = TRUE]) +} + + + +# Save internal data sets to R/sysdata.rda -------------------------------- # See 'data-raw/eucast_rules.tsv' for the EUCAST reference file -library(dplyr, warn.conflicts = FALSE) eucast_rules_file <- utils::read.delim(file = "data-raw/eucast_rules.tsv", skip = 10, sep = "\t", @@ -48,7 +144,7 @@ eucast_rules_file <- utils::read.delim(file = "data-raw/eucast_rules.tsv", mutate(reference.rule_group = as.character(reference.rule_group)) %>% select(-sorting_rule) -# Translations ---- +# Translations translations_file <- utils::read.delim(file = "data-raw/translations.tsv", sep = "\t", stringsAsFactors = FALSE, @@ -62,23 +158,42 @@ translations_file <- utils::read.delim(file = "data-raw/translations.tsv", allowEscapes = TRUE, # else "\\1" will be imported as "\\\\1" quote = "") -# Old microorganism codes ------------------------------------------------- - +# Old microorganism codes microorganisms.translation <- readRDS("data-raw/microorganisms.translation.rds") +# for mo_is_intrinsic_resistant() - saves a lot of time when executed on this vector +INTRINSIC_R <- create_intr_resistance() + +# for checking input in `language` argument in e.g. mo_*() and ab_*() functions +LANGUAGES_SUPPORTED <- sort(c("en", unique(translations_file$lang))) + +# vectors of CoNS and CoPS, improves speed in as.mo() +MO_CONS <- create_species_cons_cops("CoNS") +MO_COPS <- create_species_cons_cops("CoPS") + +# reference data - they have additional columns compared to `antibiotics` and `microorganisms` to improve speed +AB_lookup <- create_AB_lookup() +MO_lookup <- create_MO_lookup() +MO.old_lookup <- create_MO.old_lookup() + # Export to package as internal data ---- -usethis::use_data(eucast_rules_file, translations_file, microorganisms.translation, +usethis::use_data(eucast_rules_file, + translations_file, + microorganisms.translation, + INTRINSIC_R, + LANGUAGES_SUPPORTED, + MO_CONS, + MO_COPS, + AB_lookup, + MO_lookup, + MO.old_lookup, internal = TRUE, overwrite = TRUE, version = 2, compress = "xz") -# Remove from global environment ---- -rm(eucast_rules_file) -rm(translations_file) -rm(microorganisms.translation) +# Export data sets to the repository in different formats ----------------- -# Save to raw data to repository ---- write_md5 <- function(object) { conn <- file(paste0("data-raw/", deparse(substitute(object)), ".md5")) writeLines(digest::digest(object, "md5"), conn) @@ -93,7 +208,7 @@ changed_md5 <- function(object) { }, error = function(e) TRUE) } usethis::ui_done(paste0("Saving raw data to {usethis::ui_value('/data-raw/')}")) -devtools::load_all(quiet = TRUE) + # give official names to ABs and MOs rsi <- dplyr::mutate(rsi_translation, ab = ab_name(ab), mo = mo_name(mo)) if (changed_md5(rsi)) { @@ -169,5 +284,7 @@ if (changed_md5(dosage)) { try(openxlsx::write.xlsx(dosage, "data-raw/dosage.xlsx"), silent = TRUE) } -rm(write_md5) -rm(changed_md5) +# remove leftovers from global env +current_globalenv <- ls(envir = globalenv()) +rm(list = current_globalenv[!current_globalenv %in% old_globalenv]) +rm(current_globalenv) diff --git a/docs/404.html b/docs/404.html index e4192c1a..b2626d44 100644 --- a/docs/404.html +++ b/docs/404.html @@ -81,7 +81,7 @@ AMR (for R) - 1.5.0.9007 + 1.5.0.9008 diff --git a/docs/LICENSE-text.html b/docs/LICENSE-text.html index 53200bbb..aaf1ad72 100644 --- a/docs/LICENSE-text.html +++ b/docs/LICENSE-text.html @@ -81,7 +81,7 @@ AMR (for R) - 1.5.0.9007 + 1.5.0.9008 diff --git a/docs/articles/SPSS.html b/docs/articles/SPSS.html index a802f763..183b98d8 100644 --- a/docs/articles/SPSS.html +++ b/docs/articles/SPSS.html @@ -39,7 +39,7 @@ AMR (for R) - 1.5.0 + 1.5.0.9008 @@ -193,7 +193,7 @@

How to import data from SPSS / SAS / Stata

Matthijs S. Berends

-

29 December 2020

+

22 January 2021

Source: vignettes/SPSS.Rmd @@ -228,7 +228,7 @@
  • R has a huge community.

    -

    Many R users just ask questions on websites like StackOverflow.com, the largest online community for programmers. At the time of writing, more than 360,000 R-related questions have already been asked on this platform (which covers questions and answers for any programming language). In my own experience, most questions are answered within a couple of minutes.

    +

    Many R users just ask questions on websites like StackOverflow.com, the largest online community for programmers. At the time of writing, 383,346 R-related questions have already been asked on this platform (that covers questions and answers for any programming language). In my own experience, most questions are answered within a couple of minutes.

  • R understands any data type, including SPSS/SAS/Stata.

    @@ -243,7 +243,7 @@
  • R is (nowadays) the preferred analysis software in academic papers.

    At present, R is among the world most powerful statistical languages, and it is generally very popular in science (Bollmann et al., 2017). For all the above reasons, the number of references to R as an analysis method in academic papers is rising continuously and has even surpassed SPSS for academic use (Muenchen, 2014).

    -

    I believe that the thing with SPSS is, that it has always had a great user interface which is very easy to learn and use. Back when they developed it, they had very little competition, let alone from R. R didn’t even had a professional user interface until the last decade (called RStudio, see below). How people used R between the nineties and 2010 is almost completely incomparable to how R is being used now. The language itself has been restyled completely by volunteers who are dedicated professionals in the field of data science. SPSS was great when there was nothing else that could compete. But now in 2020, I don’t see any reason why SPSS would be of any better use than R.

    +

    I believe that the thing with SPSS is, that it has always had a great user interface which is very easy to learn and use. Back when they developed it, they had very little competition, let alone from R. R didn’t even had a professional user interface until the last decade (called RStudio, see below). How people used R between the nineties and 2010 is almost completely incomparable to how R is being used now. The language itself has been restyled completely by volunteers who are dedicated professionals in the field of data science. SPSS was great when there was nothing else that could compete. But now in 2021, I don’t see any reason why SPSS would be of any better use than R.

  • To demonstrate the first point:

    diff --git a/docs/articles/datasets.html b/docs/articles/datasets.html index b1ea78e5..ed3a0aec 100644 --- a/docs/articles/datasets.html +++ b/docs/articles/datasets.html @@ -39,7 +39,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/articles/index.html b/docs/articles/index.html index cfd9a553..32015764 100644 --- a/docs/articles/index.html +++ b/docs/articles/index.html @@ -81,7 +81,7 @@ AMR (for R) - 1.5.0.9007 + 1.5.0.9008 diff --git a/docs/authors.html b/docs/authors.html index 63d122fe..dcc70bfe 100644 --- a/docs/authors.html +++ b/docs/authors.html @@ -81,7 +81,7 @@ AMR (for R) - 1.5.0.9007 + 1.5.0.9008 diff --git a/docs/extra.css b/docs/extra.css index 8bf2825f..11c2f0ad 100644 --- a/docs/extra.css +++ b/docs/extra.css @@ -24,14 +24,6 @@ # how to conduct AMR analysis: https://msberends.github.io/AMR/ # # ==================================================================== # */ -@media (prefers-color-scheme: dark) { - .navbar-default { - background-color: #213730; - } - .navbar-default .navbar-nav > .active > a, .navbar-default .navbar-nav > .active > a:hover, .navbar-default .navbar-nav > .active > a:focus { - background-color: #355951; - } -} /* R for Data Science (r4ds) */ #r4ds a { @@ -209,16 +201,6 @@ thead ~ tbody { /* only when it has a header */ border-bottom: 2px solid black; } -@media (prefers-color-scheme: dark) { - thead { - border-top: 2px solid white; - border-bottom: 2px solid white; - } - thead ~ tbody { - /* only when it has a header */ - border-bottom: 2px solid white; - } -} thead th { text-align: inherit; } diff --git a/docs/index.html b/docs/index.html index bb3dd48a..ccdaeec5 100644 --- a/docs/index.html +++ b/docs/index.html @@ -43,7 +43,7 @@ AMR (for R) - 1.5.0.9007 + 1.5.0.9008 diff --git a/docs/news/index.html b/docs/news/index.html index e2bbca0f..3faabf1c 100644 --- a/docs/news/index.html +++ b/docs/news/index.html @@ -81,7 +81,7 @@ AMR (for R) - 1.5.0.9007 + 1.5.0.9008 @@ -236,13 +236,13 @@ Source: NEWS.md -
    -

    -AMR 1.5.0.9007 Unreleased +
    +

    +AMR 1.5.0.9008 Unreleased

    -
    +

    -Last updated: 18 January 2021 +Last updated: 22 January 2021

    @@ -285,7 +285,9 @@
  • Added Pretomanid (PMD, J04AK08) to the antibiotics data set
  • WHONET code "PNV" will now correctly be interpreted as PHN, the antibiotic code for phenoxymethylpenicillin (‘peni V’)
  • -
  • Fix for verbose output of mdro(..., verbose = TRUE) for German guideline (3MGRN and 4MGRN) and P. aeruginosa in Dutch guideline (BRMO)
  • +
  • Fix for verbose output of mdro(..., verbose = TRUE) for German guideline (3MGRN and 4MGRN) and Dutch guideline (BRMO, only P. aeruginosa)
  • +
  • +is.rsi.eligible() now returns FALSE immediately if the input does not contain any of the values “R”, “S” or “I”. This drastically improves speed, also for a lot of other functions that rely on automatic determination of antibiotic columns.
  • @@ -293,6 +295,7 @@ Other

    • Big documentation updates
    • +
    • Loading the package (i.e., library(AMR)) now is ~50 times faster than before
    diff --git a/docs/pkgdown.yml b/docs/pkgdown.yml index d2d6b68f..64b9961d 100644 --- a/docs/pkgdown.yml +++ b/docs/pkgdown.yml @@ -12,7 +12,7 @@ articles: datasets: datasets.html resistance_predict: resistance_predict.html welcome_to_AMR: welcome_to_AMR.html -last_built: 2021-01-18T17:45Z +last_built: 2021-01-22T08:54Z urls: reference: https://msberends.github.io/AMR//reference article: https://msberends.github.io/AMR//articles diff --git a/docs/reference/AMR-deprecated.html b/docs/reference/AMR-deprecated.html index 569c7830..fa263efb 100644 --- a/docs/reference/AMR-deprecated.html +++ b/docs/reference/AMR-deprecated.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/AMR.html b/docs/reference/AMR.html index 6d91eb58..9a029ce0 100644 --- a/docs/reference/AMR.html +++ b/docs/reference/AMR.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/WHOCC.html b/docs/reference/WHOCC.html index e156223c..0e40d2ce 100644 --- a/docs/reference/WHOCC.html +++ b/docs/reference/WHOCC.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/WHONET.html b/docs/reference/WHONET.html index f5d417c1..433a7d7d 100644 --- a/docs/reference/WHONET.html +++ b/docs/reference/WHONET.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/ab_from_text.html b/docs/reference/ab_from_text.html index a32d2fe4..6af7b67e 100644 --- a/docs/reference/ab_from_text.html +++ b/docs/reference/ab_from_text.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/ab_property.html b/docs/reference/ab_property.html index 4f23523d..c5d5fae5 100644 --- a/docs/reference/ab_property.html +++ b/docs/reference/ab_property.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/age.html b/docs/reference/age.html index 663d38f1..509e6b63 100644 --- a/docs/reference/age.html +++ b/docs/reference/age.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/age_groups.html b/docs/reference/age_groups.html index ae38e5f9..f00727b7 100644 --- a/docs/reference/age_groups.html +++ b/docs/reference/age_groups.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/antibiotic_class_selectors.html b/docs/reference/antibiotic_class_selectors.html index 6d97cfa0..954b9a29 100644 --- a/docs/reference/antibiotic_class_selectors.html +++ b/docs/reference/antibiotic_class_selectors.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/antibiotics.html b/docs/reference/antibiotics.html index fd015a9d..787ea69d 100644 --- a/docs/reference/antibiotics.html +++ b/docs/reference/antibiotics.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/as.ab.html b/docs/reference/as.ab.html index e719ca42..7612861c 100644 --- a/docs/reference/as.ab.html +++ b/docs/reference/as.ab.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/as.disk.html b/docs/reference/as.disk.html index 83424f55..bd23f96d 100644 --- a/docs/reference/as.disk.html +++ b/docs/reference/as.disk.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/as.mic.html b/docs/reference/as.mic.html index 6a5a6bc5..e2165146 100644 --- a/docs/reference/as.mic.html +++ b/docs/reference/as.mic.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/as.mo.html b/docs/reference/as.mo.html index bea9a702..f5fe5180 100644 --- a/docs/reference/as.mo.html +++ b/docs/reference/as.mo.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/as.rsi.html b/docs/reference/as.rsi.html index addeab99..9a87940a 100644 --- a/docs/reference/as.rsi.html +++ b/docs/reference/as.rsi.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 @@ -346,14 +346,14 @@

    The as.rsi() function works in four ways:

    1. For cleaning raw / untransformed data. The data will be cleaned to only contain values S, I and R and will try its best to determine this with some intelligence. For example, mixed values with R/SI interpretations and MIC values such as "<0.25; S" will be coerced to "S". Combined interpretations for multiple test methods (as seen in laboratory records) such as "S; S" will be coerced to "S", but a value like "S; I" will return NA with a warning that the input is unclear.

    2. For interpreting minimum inhibitory concentration (MIC) values according to EUCAST or CLSI. You must clean your MIC values first using as.mic(), that also gives your columns the new data class mic. Also, be sure to have a column with microorganism names or codes. It will be found automatically, but can be set manually using the mo argument.

        -
      • Using dplyr, R/SI interpretation can be done very easily with either:

        your_data %>% mutate_if(is.mic, as.rsi)             # until dplyr 1.0.0
        -your_data %>% mutate(across(where(is.mic), as.rsi)) # since dplyr 1.0.0
        +
      • Using dplyr, R/SI interpretation can be done very easily with either:

        your_data %>% mutate_if(is.mic, as.rsi)         # until dplyr 1.0.0
        +your_data %>% mutate(across((is.mic), as.rsi))  # since dplyr 1.0.0
         
      • Operators like "<=" will be stripped before interpretation. 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 might in this case return "S" or "I".

    3. For interpreting disk diffusion diameters according to EUCAST or CLSI. You must clean your disk zones first using as.disk(), that also gives your columns the new data class disk. Also, be sure to have a column with microorganism names or codes. It will be found automatically, but can be set manually using the mo argument.

        -
      • Using dplyr, R/SI interpretation can be done very easily with either:

        your_data %>% mutate_if(is.disk, as.rsi)             # until dplyr 1.0.0
        -your_data %>% mutate(across(where(is.disk), as.rsi)) # since dplyr 1.0.0
        +
      • Using dplyr, R/SI interpretation can be done very easily with either:

        your_data %>% mutate_if(is.disk, as.rsi)         # until dplyr 1.0.0
        +your_data %>% mutate(across((is.disk), as.rsi))  # since dplyr 1.0.0
         
    4. For interpreting a complete data set, with automatic determination of MIC values, disk diffusion diameters, microorganism names or codes, and antimicrobial test results. This is done very simply by running as.rsi(data).

    5. @@ -452,7 +452,7 @@ The lifecycle of this function is stableif (require("dplyr")) { df %>% mutate_if(is.mic, as.rsi) df %>% mutate_if(function(x) is.mic(x) | is.disk(x), as.rsi) - df %>% mutate(across(where(is.mic), as.rsi)) + df %>% mutate(across((is.mic), as.rsi)) df %>% mutate_at(vars(AMP:TOB), as.rsi) df %>% mutate(across(AMP:TOB, as.rsi)) @@ -497,7 +497,7 @@ The lifecycle of this function is stable# note: from dplyr 1.0.0 on, this will be: # example_isolates %>% - # mutate(across(where(is.rsi.eligible), as.rsi)) + # mutate(across((is.rsi.eligible), as.rsi)) } # } diff --git a/docs/reference/atc_online.html b/docs/reference/atc_online.html index bd5f237b..fae9e5fe 100644 --- a/docs/reference/atc_online.html +++ b/docs/reference/atc_online.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/availability.html b/docs/reference/availability.html index 4633ad46..6e2f58ce 100644 --- a/docs/reference/availability.html +++ b/docs/reference/availability.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/bug_drug_combinations.html b/docs/reference/bug_drug_combinations.html index 7ee74544..8c2ed01a 100644 --- a/docs/reference/bug_drug_combinations.html +++ b/docs/reference/bug_drug_combinations.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/catalogue_of_life.html b/docs/reference/catalogue_of_life.html index e18babf3..80a338a4 100644 --- a/docs/reference/catalogue_of_life.html +++ b/docs/reference/catalogue_of_life.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/catalogue_of_life_version.html b/docs/reference/catalogue_of_life_version.html index eac244e4..7f271b2e 100644 --- a/docs/reference/catalogue_of_life_version.html +++ b/docs/reference/catalogue_of_life_version.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/count.html b/docs/reference/count.html index feb89c2f..da71389b 100644 --- a/docs/reference/count.html +++ b/docs/reference/count.html @@ -83,7 +83,7 @@ count_resistant() should be used to count resistant isolates, count_susceptible( AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/dosage.html b/docs/reference/dosage.html index abb625f7..78e3e094 100644 --- a/docs/reference/dosage.html +++ b/docs/reference/dosage.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/eucast_rules.html b/docs/reference/eucast_rules.html index 34753480..12933c27 100644 --- a/docs/reference/eucast_rules.html +++ b/docs/reference/eucast_rules.html @@ -83,7 +83,7 @@ To improve the interpretation of the antibiogram before EUCAST rules are applied AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/example_isolates.html b/docs/reference/example_isolates.html index 65bd5cfa..53a51bb2 100644 --- a/docs/reference/example_isolates.html +++ b/docs/reference/example_isolates.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/example_isolates_unclean.html b/docs/reference/example_isolates_unclean.html index 368b6070..e32d1d96 100644 --- a/docs/reference/example_isolates_unclean.html +++ b/docs/reference/example_isolates_unclean.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/filter_ab_class.html b/docs/reference/filter_ab_class.html index 6e6af35f..3b2da8ec 100644 --- a/docs/reference/filter_ab_class.html +++ b/docs/reference/filter_ab_class.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/first_isolate.html b/docs/reference/first_isolate.html index 5e874f1d..146f35b8 100644 --- a/docs/reference/first_isolate.html +++ b/docs/reference/first_isolate.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/g.test.html b/docs/reference/g.test.html index 14d48ca5..3470910b 100644 --- a/docs/reference/g.test.html +++ b/docs/reference/g.test.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/get_episode.html b/docs/reference/get_episode.html index 6b425466..9093c38c 100644 --- a/docs/reference/get_episode.html +++ b/docs/reference/get_episode.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/ggplot_pca.html b/docs/reference/ggplot_pca.html index 0379d156..03ad375d 100644 --- a/docs/reference/ggplot_pca.html +++ b/docs/reference/ggplot_pca.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/ggplot_rsi.html b/docs/reference/ggplot_rsi.html index fbef82f1..8649d827 100644 --- a/docs/reference/ggplot_rsi.html +++ b/docs/reference/ggplot_rsi.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/guess_ab_col.html b/docs/reference/guess_ab_col.html index ea55ffd1..2db3a2cd 100644 --- a/docs/reference/guess_ab_col.html +++ b/docs/reference/guess_ab_col.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/index.html b/docs/reference/index.html index ceb53d07..c6d2adc7 100644 --- a/docs/reference/index.html +++ b/docs/reference/index.html @@ -81,7 +81,7 @@ AMR (for R) - 1.5.0.9007 + 1.5.0.9008 @@ -459,7 +459,7 @@ -

      isolate_identifier()

      +

      isolate_identifier() all.equal(<isolate_identifier>)

      Create Identifier of an Isolate

      diff --git a/docs/reference/intrinsic_resistant.html b/docs/reference/intrinsic_resistant.html index bfcf9055..3dbaf40d 100644 --- a/docs/reference/intrinsic_resistant.html +++ b/docs/reference/intrinsic_resistant.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/isolate_identifier.html b/docs/reference/isolate_identifier.html index 0aaa012a..21e7fb58 100644 --- a/docs/reference/isolate_identifier.html +++ b/docs/reference/isolate_identifier.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 @@ -242,7 +242,10 @@

      This function will paste the microorganism code with all antimicrobial results into one string for each row in a data set. This is useful to compare isolates, e.g. between institutions or regions, when there is no genotyping available.

      -
      isolate_identifier(x, col_mo = NULL, cols_ab = NULL)
      +
      isolate_identifier(x, col_mo = NULL, cols_ab = NULL)
      +
      +# S3 method for isolate_identifier
      +all.equal(target, current, ignore_empty_results = TRUE, ...)

      Arguments

      @@ -259,14 +262,18 @@ + + + +
      cols_ab

      a character vector of column names of x, or (a combination with) an antibiotic selector function, such as carbapenems() and aminoglycosides()

      ...

      column name of an antibiotic, see section Antibiotics below

      -

      Maturing Lifecycle

      +

      Experimental Lifecycle

      -


      -The lifecycle of this function is maturing. The unlying code of a maturing function has been roughed out, but finer details might still change. Since this function needs wider usage and more extensive testing, you are very welcome to suggest changes at our repository or write us an email (see section 'Contact Us').

      +


      +The lifecycle of this function is experimental. An experimental function is in early stages of development. The unlying code might be changing frequently. Experimental functions might be removed without deprecation, so you are generally best off waiting until a function is more mature before you use it in production code. Experimental functions are only available in development versions of this AMR package and will thus not be included in releases that are submitted to CRAN, since such functions have not yet matured enough.

      Read more on Our Website!

      diff --git a/docs/reference/join.html b/docs/reference/join.html index 4bd46665..b6da0cad 100644 --- a/docs/reference/join.html +++ b/docs/reference/join.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/key_antibiotics.html b/docs/reference/key_antibiotics.html index 39945a9c..21e512d5 100644 --- a/docs/reference/key_antibiotics.html +++ b/docs/reference/key_antibiotics.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/kurtosis.html b/docs/reference/kurtosis.html index 7f841b6d..957c3739 100644 --- a/docs/reference/kurtosis.html +++ b/docs/reference/kurtosis.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/lifecycle.html b/docs/reference/lifecycle.html index 1682ba1a..2a6e01e4 100644 --- a/docs/reference/lifecycle.html +++ b/docs/reference/lifecycle.html @@ -84,7 +84,7 @@ This page contains a section for every lifecycle (with text borrowed from the af AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/like.html b/docs/reference/like.html index 08df3484..c8c0afc3 100644 --- a/docs/reference/like.html +++ b/docs/reference/like.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/mdro.html b/docs/reference/mdro.html index c793a3bf..daccc21f 100644 --- a/docs/reference/mdro.html +++ b/docs/reference/mdro.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/microorganisms.codes.html b/docs/reference/microorganisms.codes.html index 1932c7ec..dbf9cc23 100644 --- a/docs/reference/microorganisms.codes.html +++ b/docs/reference/microorganisms.codes.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/microorganisms.html b/docs/reference/microorganisms.html index 04a6aabe..05c2850a 100644 --- a/docs/reference/microorganisms.html +++ b/docs/reference/microorganisms.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/microorganisms.old.html b/docs/reference/microorganisms.old.html index 7bccad5c..7946f46d 100644 --- a/docs/reference/microorganisms.old.html +++ b/docs/reference/microorganisms.old.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/mo_matching_score.html b/docs/reference/mo_matching_score.html index d129ab3c..187ea1cd 100644 --- a/docs/reference/mo_matching_score.html +++ b/docs/reference/mo_matching_score.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/mo_property.html b/docs/reference/mo_property.html index 2260754b..77c4ab8b 100644 --- a/docs/reference/mo_property.html +++ b/docs/reference/mo_property.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/mo_source.html b/docs/reference/mo_source.html index f9e35b02..9315bec1 100644 --- a/docs/reference/mo_source.html +++ b/docs/reference/mo_source.html @@ -83,7 +83,7 @@ This is the fastest way to have your organisation (or analysis) specific codes p AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/pca.html b/docs/reference/pca.html index 354cbeb9..2379e238 100644 --- a/docs/reference/pca.html +++ b/docs/reference/pca.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/plot.html b/docs/reference/plot.html index 3a5b8e25..0fd87849 100644 --- a/docs/reference/plot.html +++ b/docs/reference/plot.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/proportion.html b/docs/reference/proportion.html index 2c9d9268..560cc6a2 100644 --- a/docs/reference/proportion.html +++ b/docs/reference/proportion.html @@ -83,7 +83,7 @@ resistance() should be used to calculate resistance, susceptibility() should be AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/random.html b/docs/reference/random.html index 5058efc8..18d02873 100644 --- a/docs/reference/random.html +++ b/docs/reference/random.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/resistance_predict.html b/docs/reference/resistance_predict.html index ae871da0..0d5c3d5f 100644 --- a/docs/reference/resistance_predict.html +++ b/docs/reference/resistance_predict.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/rsi_translation.html b/docs/reference/rsi_translation.html index 8fd79c76..2041954a 100644 --- a/docs/reference/rsi_translation.html +++ b/docs/reference/rsi_translation.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/skewness.html b/docs/reference/skewness.html index 35a7ee41..175b74fc 100644 --- a/docs/reference/skewness.html +++ b/docs/reference/skewness.html @@ -83,7 +83,7 @@ When negative ('left-skewed'): the left tail is longer; the mass of the distribu AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/reference/translate.html b/docs/reference/translate.html index 19ddf4e0..72c453f7 100644 --- a/docs/reference/translate.html +++ b/docs/reference/translate.html @@ -82,7 +82,7 @@ AMR (for R) - 1.5.0.9006 + 1.5.0.9008 diff --git a/docs/survey.html b/docs/survey.html index b1b9d7cc..9f037053 100644 --- a/docs/survey.html +++ b/docs/survey.html @@ -81,7 +81,7 @@ AMR (for R) - 1.5.0.9007 + 1.5.0.9008 diff --git a/man/as.rsi.Rd b/man/as.rsi.Rd index 2bf0eabe..61c247c4 100755 --- a/man/as.rsi.Rd +++ b/man/as.rsi.Rd @@ -87,15 +87,15 @@ The \code{\link[=as.rsi]{as.rsi()}} function works in four ways: \item For \strong{cleaning raw / untransformed data}. The data will be cleaned to only contain values S, I and R and will try its best to determine this with some intelligence. For example, mixed values with R/SI interpretations and MIC values such as \code{"<0.25; S"} will be coerced to \code{"S"}. Combined interpretations for multiple test methods (as seen in laboratory records) such as \code{"S; S"} will be coerced to \code{"S"}, but a value like \code{"S; I"} will return \code{NA} with a warning that the input is unclear. \item For \strong{interpreting minimum inhibitory concentration (MIC) values} according to EUCAST or CLSI. You must clean your MIC values first using \code{\link[=as.mic]{as.mic()}}, that also gives your columns the new data class \code{\link{mic}}. Also, be sure to have a column with microorganism names or codes. It will be found automatically, but can be set manually using the \code{mo} argument. \itemize{ -\item Using \code{dplyr}, R/SI interpretation can be done very easily with either:\preformatted{your_data \%>\% mutate_if(is.mic, as.rsi) # until dplyr 1.0.0 -your_data \%>\% mutate(across(where(is.mic), as.rsi)) # since dplyr 1.0.0 +\item Using \code{dplyr}, R/SI interpretation can be done very easily with either:\preformatted{your_data \%>\% mutate_if(is.mic, as.rsi) # until dplyr 1.0.0 +your_data \%>\% mutate(across((is.mic), as.rsi)) # since dplyr 1.0.0 } \item Operators like "<=" will be stripped before interpretation. 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 might in this case return "S" or "I". } \item For \strong{interpreting disk diffusion diameters} according to EUCAST or CLSI. You must clean your disk zones first using \code{\link[=as.disk]{as.disk()}}, that also gives your columns the new data class \code{\link{disk}}. Also, be sure to have a column with microorganism names or codes. It will be found automatically, but can be set manually using the \code{mo} argument. \itemize{ -\item Using \code{dplyr}, R/SI interpretation can be done very easily with either:\preformatted{your_data \%>\% mutate_if(is.disk, as.rsi) # until dplyr 1.0.0 -your_data \%>\% mutate(across(where(is.disk), as.rsi)) # since dplyr 1.0.0 +\item Using \code{dplyr}, R/SI interpretation can be done very easily with either:\preformatted{your_data \%>\% mutate_if(is.disk, as.rsi) # until dplyr 1.0.0 +your_data \%>\% mutate(across((is.disk), as.rsi)) # since dplyr 1.0.0 } } \item For \strong{interpreting a complete data set}, with automatic determination of MIC values, disk diffusion diameters, microorganism names or codes, and antimicrobial test results. This is done very simply by running \code{as.rsi(data)}. @@ -193,7 +193,7 @@ as.rsi(x = as.disk(18), if (require("dplyr")) { df \%>\% mutate_if(is.mic, as.rsi) df \%>\% mutate_if(function(x) is.mic(x) | is.disk(x), as.rsi) - df \%>\% mutate(across(where(is.mic), as.rsi)) + df \%>\% mutate(across((is.mic), as.rsi)) df \%>\% mutate_at(vars(AMP:TOB), as.rsi) df \%>\% mutate(across(AMP:TOB, as.rsi)) @@ -238,7 +238,7 @@ if (require("dplyr")) { # note: from dplyr 1.0.0 on, this will be: # example_isolates \%>\% - # mutate(across(where(is.rsi.eligible), as.rsi)) + # mutate(across((is.rsi.eligible), as.rsi)) } } } diff --git a/man/isolate_identifier.Rd b/man/isolate_identifier.Rd index c6d2c3e7..4c95e487 100644 --- a/man/isolate_identifier.Rd +++ b/man/isolate_identifier.Rd @@ -2,9 +2,12 @@ % Please edit documentation in R/isolate_identifier.R \name{isolate_identifier} \alias{isolate_identifier} +\alias{all.equal.isolate_identifier} \title{Create Identifier of an Isolate} \usage{ isolate_identifier(x, col_mo = NULL, cols_ab = NULL) + +\method{all.equal}{isolate_identifier}(target, current, ignore_empty_results = TRUE, ...) } \arguments{ \item{x}{data with antibiotic columns, such as \code{amox}, \code{AMX} and \code{AMC}} @@ -12,14 +15,16 @@ isolate_identifier(x, col_mo = NULL, cols_ab = NULL) \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{cols_ab}{a character vector of column names of \code{x}, or (a combination with) an \href{[ab_class()]}{antibiotic selector function}, such as \code{\link[=carbapenems]{carbapenems()}} and \code{\link[=aminoglycosides]{aminoglycosides()}}} + +\item{...}{column name of an antibiotic, see section \emph{Antibiotics} below} } \description{ This function will paste the microorganism code with all antimicrobial results into one string for each row in a data set. This is useful to compare isolates, e.g. between institutions or regions, when there is no genotyping available. } -\section{Maturing Lifecycle}{ +\section{Experimental Lifecycle}{ -\if{html}{\figure{lifecycle_maturing.svg}{options: style=margin-bottom:5px} \cr} -The \link[=lifecycle]{lifecycle} of this function is \strong{maturing}. The unlying code of a maturing function has been roughed out, but finer details might still change. Since this function needs wider usage and more extensive testing, you are very welcome \href{https://github.com/msberends/AMR/issues}{to suggest changes at our repository} or \link[=AMR]{write us an email (see section 'Contact Us')}. +\if{html}{\figure{lifecycle_experimental.svg}{options: style=margin-bottom:5px} \cr} +The \link[=lifecycle]{lifecycle} of this function is \strong{experimental}. An experimental function is in early stages of development. The unlying code might be changing frequently. Experimental functions might be removed without deprecation, so you are generally best off waiting until a function is more mature before you use it in production code. Experimental functions are only available in development versions of this \code{AMR} package and will thus not be included in releases that are submitted to CRAN, since such functions have not yet matured enough. } \section{Read more on Our Website!}{ diff --git a/pkgdown/extra.css b/pkgdown/extra.css index 8bf2825f..11c2f0ad 100644 --- a/pkgdown/extra.css +++ b/pkgdown/extra.css @@ -24,14 +24,6 @@ # how to conduct AMR analysis: https://msberends.github.io/AMR/ # # ==================================================================== # */ -@media (prefers-color-scheme: dark) { - .navbar-default { - background-color: #213730; - } - .navbar-default .navbar-nav > .active > a, .navbar-default .navbar-nav > .active > a:hover, .navbar-default .navbar-nav > .active > a:focus { - background-color: #355951; - } -} /* R for Data Science (r4ds) */ #r4ds a { @@ -209,16 +201,6 @@ thead ~ tbody { /* only when it has a header */ border-bottom: 2px solid black; } -@media (prefers-color-scheme: dark) { - thead { - border-top: 2px solid white; - border-bottom: 2px solid white; - } - thead ~ tbody { - /* only when it has a header */ - border-bottom: 2px solid white; - } -} thead th { text-align: inherit; } diff --git a/tests/testthat/test-isolate_identifier.R b/tests/testthat/test-isolate_identifier.R new file mode 100644 index 00000000..fd63bcc3 --- /dev/null +++ b/tests/testthat/test-isolate_identifier.R @@ -0,0 +1,44 @@ +# ==================================================================== # +# TITLE # +# Antimicrobial Resistance (AMR) Analysis for R # +# # +# SOURCE # +# https://github.com/msberends/AMR # +# # +# LICENCE # +# (c) 2018-2021 Berends MS, Luz CF et al. # +# Developed at the University of Groningen, the Netherlands, in # +# collaboration with non-profit organisations Certe Medical # +# Diagnostics & Advice, and University Medical Center Groningen. # +# # +# This R package is free software; you can freely use and distribute # +# it for both personal and commercial purposes under the terms of the # +# GNU General Public License version 2.0 (GNU GPL-2), as published by # +# the Free Software Foundation. # +# We created this package for both routine data analysis and academic # +# research and it was publicly released in the hope that it will be # +# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. # +# # +# Visit our website for the full manual and a complete tutorial about # +# how to conduct AMR analysis: https://msberends.github.io/AMR/ # +# ==================================================================== # + +context("isolate_identifier.R") + +test_that("isolate_identifier works", { + x <- suppressMessages(isolate_identifier(example_isolates)) + expect_s3_class(x, "isolate_identifier") + expect_s3_class(x, "character") + + expect_equal(suppressMessages( + unique(nchar(isolate_identifier(example_isolates, cols_ab = carbapenems(), col_mo = FALSE)))), + 2) + + expect_warning(isolate_identifier(example_isolates[, 1:3, drop = FALSE])) # without mo and without rsi + expect_warning(isolate_identifier(example_isolates[, 1:9, drop = FALSE])) # only without rsi + + + expect_output(print(x)) + expect_s3_class(unique(c(x, x)), "isolate_identifier") + +}) diff --git a/vignettes/SPSS.Rmd b/vignettes/SPSS.Rmd index 75c8d653..53eb0cdd 100755 --- a/vignettes/SPSS.Rmd +++ b/vignettes/SPSS.Rmd @@ -49,7 +49,7 @@ As said, SPSS is easier to learn than R. But SPSS, SAS and Stata come with major * **R has a huge community.** - Many R users just ask questions on websites like [StackOverflow.com](https://stackoverflow.com), the largest online community for programmers. At the time of writing, more than [360,000 R-related questions](https://stackoverflow.com/questions/tagged/r?sort=votes) have already been asked on this platform (which covers questions and answers for any programming language). In my own experience, most questions are answered within a couple of minutes. + Many R users just ask questions on websites like [StackOverflow.com](https://stackoverflow.com), the largest online community for programmers. At the time of writing, [`r format(suppressWarnings(readr::read_csv("https://data.stackexchange.com/stackoverflow/csv/1674647", col_types = "d")[[1]]), big.mark = ",")` R-related questions](https://stackoverflow.com/questions/tagged/r?sort=votes) have already been asked on this platform (that covers questions and answers for any programming language). In my own experience, most questions are answered within a couple of minutes. * **R understands any data type, including SPSS/SAS/Stata.**