diff --git a/DESCRIPTION b/DESCRIPTION index a51216b4..7c7edde2 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: AMR -Version: 0.8.0.9003 -Date: 2019-10-23 +Version: 0.8.0.9004 +Date: 2019-10-26 Title: Antimicrobial Resistance Analysis Authors@R: c( person(role = c("aut", "cre"), diff --git a/NAMESPACE b/NAMESPACE index eed558a9..ed00fbae 100755 --- a/NAMESPACE +++ b/NAMESPACE @@ -135,6 +135,7 @@ export(kurtosis) export(labels_rsi_count) export(left_join_microorganisms) export(like) +export(mdr_cmi2012) export(mdr_tb) export(mdro) export(mo_authors) diff --git a/NEWS.md b/NEWS.md index 3507d49a..66d7e65e 100755 --- a/NEWS.md +++ b/NEWS.md @@ -1,11 +1,17 @@ -# AMR 0.8.0.9003 -Last updated: 23-Oct-2019 +# AMR 0.8.0.9004 +Last updated: 26-Oct-2019 + +### New +* Support for a new MDRO guideline: Magiorakos AP, Srinivasan A *et al.* "Multidrug-resistant, extensively drug-resistant and pandrug-resistant bacteria: an international expert proposal for interim standard definitions for acquired resistance." Clinical Microbiology and Infection (2012). **This is now the new default guideline for the `mdro()` function.** ### Changes * When running `as.rsi()` over a data set, it will now print the guideline that will be used if it is not specified by the user * Fix for `eucast_rules()`: *Stenotrophomonas maltophilia* not interpreted "R" to ceftazidime anymore (following EUCAST v3.1) * Fix in taxonomic info for genera that are in multiple kingdoms, like *Proteus* * Fix for interpreting MIC values with `as.rsi()` where the input is `NA` +* Added "imi" as allowed abbreviation for Imipenem +* Fix for automatically determining columns with antibiotic results in `mdro()` and `eucast_rules()` +* Added ATC codes for ceftaroline, ceftobiprole and faropenem # AMR 0.8.0 diff --git a/R/eucast_rules.R b/R/eucast_rules.R index 0564d4a9..d94ddf49 100755 --- a/R/eucast_rules.R +++ b/R/eucast_rules.R @@ -47,6 +47,7 @@ EUCAST_VERSION_EXPERT_RULES <- "3.1, 2016" #' \strong{AMX}: amoxicillin (\href{https://www.whocc.no/atc_ddd_index/?code=J01CA04}{J01CA04}), #' \strong{AMC}: amoxicillin/clavulanic acid (\href{https://www.whocc.no/atc_ddd_index/?code=J01CR02}{J01CR02}), #' \strong{AMP}: ampicillin (\href{https://www.whocc.no/atc_ddd_index/?code=J01CA01}{J01CA01}), +#' \strong{SAM}: ampicillin/sulbactam (\href{https://www.whocc.no/atc_ddd_index/?code=J01CR01}{J01CR01}), #' \strong{AZM}: azithromycin (\href{https://www.whocc.no/atc_ddd_index/?code=J01FA10}{J01FA10}), #' \strong{AZL}: azlocillin (\href{https://www.whocc.no/atc_ddd_index/?code=J01CA09}{J01CA09}), #' \strong{ATM}: aztreonam (\href{https://www.whocc.no/atc_ddd_index/?code=J01DF01}{J01DF01}), @@ -55,17 +56,20 @@ EUCAST_VERSION_EXPERT_RULES <- "3.1, 2016" #' \strong{CZO}: cefazolin (\href{https://www.whocc.no/atc_ddd_index/?code=J01DB04}{J01DB04}), #' \strong{FEP}: cefepime (\href{https://www.whocc.no/atc_ddd_index/?code=J01DE01}{J01DE01}), #' \strong{CTX}: cefotaxime (\href{https://www.whocc.no/atc_ddd_index/?code=J01DD01}{J01DD01}), +#' \strong{CTT}: cefotetan (\href{https://www.whocc.no/atc_ddd_index/?code=J01DC05}{J01DC05}), #' \strong{FOX}: cefoxitin (\href{https://www.whocc.no/atc_ddd_index/?code=J01DC01}{J01DC01}), -#' \strong{CED}: cefradine (\href{https://www.whocc.no/atc_ddd_index/?code=J01DB09}{J01DB09}), +#' \strong{CPT}: ceftaroline (\href{https://www.whocc.no/atc_ddd_index/?code=J01DI02}{J01DI02}), #' \strong{CAZ}: ceftazidime (\href{https://www.whocc.no/atc_ddd_index/?code=J01DD02}{J01DD02}), #' \strong{CRO}: ceftriaxone (\href{https://www.whocc.no/atc_ddd_index/?code=J01DD04}{J01DD04}), #' \strong{CXM}: cefuroxime (\href{https://www.whocc.no/atc_ddd_index/?code=J01DC02}{J01DC02}), +#' \strong{CED}: cephradine (\href{https://www.whocc.no/atc_ddd_index/?code=J01DB09}{J01DB09}), #' \strong{CHL}: chloramphenicol (\href{https://www.whocc.no/atc_ddd_index/?code=J01BA01}{J01BA01}), #' \strong{CIP}: ciprofloxacin (\href{https://www.whocc.no/atc_ddd_index/?code=J01MA02}{J01MA02}), #' \strong{CLR}: clarithromycin (\href{https://www.whocc.no/atc_ddd_index/?code=J01FA09}{J01FA09}), #' \strong{CLI}: clindamycin (\href{https://www.whocc.no/atc_ddd_index/?code=J01FF01}{J01FF01}), #' \strong{COL}: colistin (\href{https://www.whocc.no/atc_ddd_index/?code=J01XB01}{J01XB01}), #' \strong{DAP}: daptomycin (\href{https://www.whocc.no/atc_ddd_index/?code=J01XX09}{J01XX09}), +#' \strong{DOR}: doripenem (\href{https://www.whocc.no/atc_ddd_index/?code=J01DH04}{J01DH04}), #' \strong{DOX}: doxycycline (\href{https://www.whocc.no/atc_ddd_index/?code=J01AA02}{J01AA02}), #' \strong{ETP}: ertapenem (\href{https://www.whocc.no/atc_ddd_index/?code=J01DH03}{J01DH03}), #' \strong{ERY}: erythromycin (\href{https://www.whocc.no/atc_ddd_index/?code=J01FA01}{J01FA01}), @@ -75,6 +79,7 @@ EUCAST_VERSION_EXPERT_RULES <- "3.1, 2016" #' \strong{FUS}: fusidic acid (\href{https://www.whocc.no/atc_ddd_index/?code=J01XC01}{J01XC01}), #' \strong{GAT}: gatifloxacin (\href{https://www.whocc.no/atc_ddd_index/?code=J01MA16}{J01MA16}), #' \strong{GEN}: gentamicin (\href{https://www.whocc.no/atc_ddd_index/?code=J01GB03}{J01GB03}), +#' \strong{GEH}: gentamicin-high (no ATC code), #' \strong{IPM}: imipenem (\href{https://www.whocc.no/atc_ddd_index/?code=J01DH51}{J01DH51}), #' \strong{INH}: isoniazid (\href{https://www.whocc.no/atc_ddd_index/?code=J04AC01}{J04AC01}), #' \strong{KAN}: kanamycin (\href{https://www.whocc.no/atc_ddd_index/?code=J01GB04}{J01GB04}), @@ -91,10 +96,10 @@ EUCAST_VERSION_EXPERT_RULES <- "3.1, 2016" #' \strong{NET}: netilmicin (\href{https://www.whocc.no/atc_ddd_index/?code=J01GB07}{J01GB07}), #' \strong{NIT}: nitrofurantoin (\href{https://www.whocc.no/atc_ddd_index/?code=J01XE01}{J01XE01}), #' \strong{NOR}: norfloxacin (\href{https://www.whocc.no/atc_ddd_index/?code=J01MA06}{J01MA06}), -#' \strong{NOV}: novobiocin (an ATCvet code: \href{https://www.whocc.no/atc_ddd_index/?code=QJ01XX95}{QJ01XX95}), +#' \strong{NOV}: novobiocin (\href{https://www.whocc.no/atc_ddd_index/?code=QJ01XX95}{QJ01XX95}), #' \strong{OFX}: ofloxacin (\href{https://www.whocc.no/atc_ddd_index/?code=J01MA01}{J01MA01}), #' \strong{OXA}: oxacillin (\href{https://www.whocc.no/atc_ddd_index/?code=J01CF04}{J01CF04}), -#' \strong{PEN}: penicillin G (\href{https://www.whocc.no/atc_ddd_index/?code=J01CE01}{J01CE01}), +#' \strong{PEN}: penicillin G (\href{https://www.whocc.no/atc_ddd_index/?code=J01RA01}{J01RA01}), #' \strong{PIP}: piperacillin (\href{https://www.whocc.no/atc_ddd_index/?code=J01CA12}{J01CA12}), #' \strong{TZP}: piperacillin/tazobactam (\href{https://www.whocc.no/atc_ddd_index/?code=J01CR05}{J01CR05}), #' \strong{PLB}: polymyxin B (\href{https://www.whocc.no/atc_ddd_index/?code=J01XB02}{J01XB02}), @@ -103,13 +108,15 @@ EUCAST_VERSION_EXPERT_RULES <- "3.1, 2016" #' \strong{QDA}: quinupristin/dalfopristin (\href{https://www.whocc.no/atc_ddd_index/?code=J01FG02}{J01FG02}), #' \strong{RIB}: rifabutin (\href{https://www.whocc.no/atc_ddd_index/?code=J04AB04}{J04AB04}), #' \strong{RIF}: rifampicin (\href{https://www.whocc.no/atc_ddd_index/?code=J04AB02}{J04AB02}), -#' \strong{RIF}: rifampin (\href{https://www.whocc.no/atc_ddd_index/?code=J04AB02}{J04AB02}), #' \strong{RFP}: rifapentine (\href{https://www.whocc.no/atc_ddd_index/?code=J04AB05}{J04AB05}), -#' \strong{RXT}: roxithromycin (\href{https://www.whocc.no/atc_ddd_index/?code=J01FA06}{J01FA06}), +#' \strong{RXT}: roxithromicin (\href{https://www.whocc.no/atc_ddd_index/?code=J01FA06}{J01FA06}), #' \strong{SIS}: sisomicin (\href{https://www.whocc.no/atc_ddd_index/?code=J01GB08}{J01GB08}), +#' \strong{STH}: streptomycin-high (no ATC code), #' \strong{TEC}: teicoplanin (\href{https://www.whocc.no/atc_ddd_index/?code=J01XA02}{J01XA02}), +#' \strong{TLV}: telavancin (\href{https://www.whocc.no/atc_ddd_index/?code=J01XA03}{J01XA03}), #' \strong{TCY}: tetracycline (\href{https://www.whocc.no/atc_ddd_index/?code=J01AA07}{J01AA07}), #' \strong{TIC}: ticarcillin (\href{https://www.whocc.no/atc_ddd_index/?code=J01CA13}{J01CA13}), +#' \strong{TCC}: ticarcillin/clavulanic acid (\href{https://www.whocc.no/atc_ddd_index/?code=J01CR03}{J01CR03}), #' \strong{TGC}: tigecycline (\href{https://www.whocc.no/atc_ddd_index/?code=J01AA12}{J01AA12}), #' \strong{TOB}: tobramycin (\href{https://www.whocc.no/atc_ddd_index/?code=J01GB01}{J01GB01}), #' \strong{TMP}: trimethoprim (\href{https://www.whocc.no/atc_ddd_index/?code=J01EA01}{J01EA01}), diff --git a/R/guess_ab_col.R b/R/guess_ab_col.R index 971c707f..faedfbc6 100755 --- a/R/guess_ab_col.R +++ b/R/guess_ab_col.R @@ -166,26 +166,31 @@ get_column_abx <- function(x, # sort on name x <- x[order(names(x), x)] - duplicates <- x[base::duplicated(x)] - x <- x[!names(x) %in% names(duplicates)] + duplicates <- c(x[base::duplicated(x)], x[base::duplicated(names(x))]) + duplicates <- duplicates[unique(names(duplicates))] + x <- c(x[!names(x) %in% names(duplicates)], duplicates) + x <- x[order(names(x), x)] # succeeded with aut-guessing message(blue("OK.")) - - if (verbose == TRUE) { - for (i in seq_len(length(x))) { + + for (i in seq_len(length(x))) { + if (verbose == TRUE & !names(x[i]) %in% names(duplicates)) { message(blue(paste0("NOTE: Using column `", bold(x[i]), "` as input for `", names(x)[i], "` (", ab_name(names(x)[i], tolower = TRUE), ")."))) } - } else if (length(duplicates) > 0) { - for (i in seq_len(length(duplicates))) { - warning(red(paste0("Using column `", bold(duplicates[i]), "` as input for `", names(x[which(x == duplicates[i])]), - "` (", ab_name(names(x[names(which(x == duplicates))[i]]), tolower = TRUE), - "), although it was matched for multiple antibiotics or columns.")), call. = FALSE) + if (names(x[i]) %in% names(duplicates)) { + warning(red(paste0("Using column `", bold(x[i]), "` as input for `", names(x)[i], + "` (", ab_name(names(x)[i], tolower = TRUE), + "), although it was matched for multiple antibiotics or columns.")), + call. = FALSE, + immediate. = verbose) } } - + + if (!is.null(hard_dependencies)) { + hard_dependencies <- unique(hard_dependencies) if (!all(hard_dependencies %in% names(x))) { # missing a hard dependency will return NA and consequently the data will not be analysed missing <- hard_dependencies[!hard_dependencies %in% names(x)] @@ -194,6 +199,7 @@ get_column_abx <- function(x, } } if (!is.null(soft_dependencies)) { + soft_dependencies <- unique(soft_dependencies) if (!all(soft_dependencies %in% names(x))) { # missing a soft dependency may lower the reliability missing <- soft_dependencies[!soft_dependencies %in% names(x)] @@ -203,7 +209,7 @@ get_column_abx <- function(x, mutate(txt = paste0(bold(missing), " (", missing_names, ")")) %>% arrange(missing_names) %>% pull(txt) - message(blue("NOTE: Reliability might be improved if these antimicrobial results would be available too:", + message(blue("NOTE: Reliability will be improved if these antimicrobial results would be available too:", paste(missing_txt, collapse = ", "))) } } diff --git a/R/mdro.R b/R/mdro.R index 06aa2642..5ef60add 100755 --- a/R/mdro.R +++ b/R/mdro.R @@ -23,13 +23,14 @@ #' #' Determine which isolates are multidrug-resistant organisms (MDRO) according to (country-specific) guidelines. #' @param x table with antibiotic columns, like e.g. \code{AMX} and \code{AMC} -#' @param guideline a specific guideline to mention, see Details. EUCAST guidelines will be used when left empty, see Details. +#' @param guideline a specific guideline to follow. When left empty, the publication by Magiorakos \emph{et al.} (2012, Clinical Microbiology and Infection) will be followed, see Details. #' @param info print progress #' @inheritParams eucast_rules #' @param verbose print additional info: missing antibiotic columns per parameter #' @inheritSection eucast_rules Antibiotics #' @details Currently supported guidelines are (case-insensitive): #' \itemize{ +#' \item{\code{guideline = "CMI2012"}: Magiorakos AP, Srinivasan A \emph{et al.} "Multidrug-resistant, extensively drug-resistant and pandrug-resistant bacteria: an international expert proposal for interim standard definitions for acquired resistance." Clinical Microbiology and Infection (2012) (\href{https://www.clinicalmicrobiologyandinfection.com/article/S1198-743X(14)61632-3/fulltext}{link})} #' \item{\code{guideline = "EUCAST"}: The European international guideline - EUCAST Expert Rules Version 3.1 "Intrinsic Resistance and Exceptional Phenotypes Tables" (\href{http://www.eucast.org/fileadmin/src/media/PDFs/EUCAST_files/Expert_Rules/Expert_rules_intrinsic_exceptional_V3.1.pdf}{link})} #' \item{\code{guideline = "TB"}: The international guideline for multi-drug resistant tuberculosis - World Health Organization "Companion handbook to the WHO guidelines for the programmatic management of drug-resistant tuberculosis" (\href{https://www.who.int/tb/publications/pmdt_companionhandbook/en/}{link})} #' \item{\code{guideline = "MRGN"}: The German national guideline - Mueller et al. (2015) Antimicrobial Resistance and Infection Control 4:7. DOI: 10.1186/s13756-015-0047-6} @@ -38,24 +39,26 @@ #' #' Please suggest your own (country-specific) guidelines by letting us know: \url{https://gitlab.com/msberends/AMR/issues/new}. #' @return \itemize{ -#' \item{TB guideline - function \code{mdr_tb()} or \code{mdro(..., guideline = "TB")}:\cr Ordered factor with levels \code{Negative < Mono-resistant < Poly-resistant < Multi-drug-resistant < Extensive drug-resistant}} +#' \item{CMI 2012 paper - function \code{mdr_cmi2012()} or \code{mdro()}:\cr Ordered factor with levels \code{Negative < Multi-drug-resistant (MDR) < Extensively drug-resistant (XDR) < Pandrug-resistant (PDR)}} +#' \item{TB guideline - function \code{mdr_tb()} or \code{mdro(..., guideline = "TB")}:\cr Ordered factor with levels \code{Negative < Mono-resistant < Poly-resistant < Multi-drug-resistant < Extensively drug-resistant}} #' \item{German guideline - function \code{mrgn()} or \code{mdro(..., guideline = "MRGN")}:\cr Ordered factor with levels \code{Negative < 3MRGN < 4MRGN}} #' \item{Everything else:\cr Ordered factor with levels \code{Negative < Positive, unconfirmed < Positive}. The value \code{"Positive, unconfirmed"} means that, according to the guideline, it is not entirely sure if the isolate is multi-drug resistant and this should be confirmed with additional (e.g. molecular) tests} #' } #' @rdname mdro -#' @importFrom dplyr %>% -#' @importFrom crayon red blue bold +#' @importFrom dplyr %>% filter_all +#' @importFrom crayon blue bold italic #' @export #' @inheritSection AMR Read more on our website! #' @source -#' EUCAST Expert Rules Version 3.1 "Intrinsic Resistance and Exceptional Phenotypes Tables" (\href{http://www.eucast.org/fileadmin/src/media/PDFs/EUCAST_files/Expert_Rules/Expert_rules_intrinsic_exceptional_V3.1.pdf}{link}) -#' -#' World Health Organization "Companion handbook to the WHO guidelines for the programmatic management of drug-resistant tuberculosis" (\href{https://www.who.int/tb/publications/pmdt_companionhandbook/en/}{link}) -#' -#' Rijksinstituut voor Volksgezondheid en Milieu "WIP-richtlijn BRMO (Bijzonder Resistente Micro-Organismen) [ZKH]" (\href{https://www.rivm.nl/Documenten_en_publicaties/Professioneel_Praktisch/Richtlijnen/Infectieziekten/WIP_Richtlijnen/WIP_Richtlijnen/Ziekenhuizen/WIP_richtlijn_BRMO_Bijzonder_Resistente_Micro_Organismen_ZKH}{link}) +#' Please see Details for the list of publications used for this function. #' @examples #' library(dplyr) -#' +#' +#' example_isolates %>% +#' mdro() %>% +#' freq() +#' +#' \donttest{ #' example_isolates %>% #' mutate(EUCAST = mdro(.), #' BRMO = brmo(.), @@ -65,6 +68,7 @@ #' rename(PIP = TZP) %>% # no piperacillin, so take piperacillin/tazobactam #' mrgn() %>% # check German guideline #' freq() # check frequencies +#' } mdro <- function(x, guideline = NULL, col_mo = NULL, @@ -86,7 +90,8 @@ mdro <- function(x, } if (is.null(guideline)) { - guideline <- "eucast" + # default to the paper by Magiorakos et al. (2012) + guideline <- "cmi2012" } if (tolower(guideline) == "nl") { guideline <- "BRMO" @@ -94,7 +99,7 @@ mdro <- function(x, if (tolower(guideline) == "de") { guideline <- "MRGN" } - if (!tolower(guideline) %in% c("brmo", "mrgn", "eucast", "tb")) { + if (!tolower(guideline) %in% c("brmo", "mrgn", "eucast", "tb", "cmi2012")) { stop("invalid guideline: ", guideline, call. = FALSE) } guideline <- list(code = tolower(guideline)) @@ -114,7 +119,13 @@ mdro <- function(x, stop("`col_mo` must be set.", call. = FALSE) } - if (guideline$code == "eucast") { + if (guideline$code == "cmi2012") { + guideline$name <- "Multidrug-resistant, extensively drug-resistant and pandrug-resistant bacteria: an international expert proposal for interim standard definitions for acquired resistance." + guideline$author <- "Magiorakos AP, Srinivasan A, Carey RB, ..., Vatopoulos A, Weber JT, Monnet DL" + guideline$version <- "N/A" + guideline$source <- "Magiorakos et al. (2012) Clinical Microbiology and Infection 18:3. DOI: 10.1111/j.1469-0691.2011.03570.x" + + } else if (guideline$code == "eucast") { guideline$name <- "EUCAST Expert Rules, \"Intrinsic Resistance and Exceptional Phenotypes Tables\"" guideline$author <- "EUCAST (European Committee on Antimicrobial Susceptibility Testing)" guideline$version <- "3.1" @@ -129,9 +140,10 @@ mdro <- function(x, # support per country: } else if (guideline$code == "mrgn") { guideline$name <- "Cross-border comparison of the Dutch and German guidelines on multidrug-resistant Gram-negative microorganisms" - guideline$author <- "J. M\u00fcller, A. Voss, R. K\u00f6ck, ..., W.V. Kern, C. Wendt, A.W. Friedrich" + guideline$author <- "M\u00fcller J, Voss A, K\u00f6ck R, ..., Kern WV, Wendt C, Friedrich AW" guideline$version <- "N/A" guideline$source <- "M\u00fcller et al. (2015) Antimicrobial Resistance and Infection Control 4:7. DOI: 10.1186/s13756-015-0047-6" + } else if (guideline$code == "brmo") { guideline$name <- "WIP-Richtlijn Bijzonder Resistente Micro-organismen (BRMO)" guideline$author <- "RIVM (Rijksinstituut voor de Volksgezondheid)" @@ -141,16 +153,126 @@ mdro <- function(x, stop("This guideline is currently unsupported: ", guideline$code, call. = FALSE) } - if (info == TRUE) { - cat("Determining multidrug-resistant organisms (MDRO), according to:\n", - "Guideline: ", red(guideline$name), "\n", - "Version: ", red(guideline$version), "\n", - "Author: ", red(guideline$author), "\n", - "Source: ", blue(guideline$source), "\n", - "\n", sep = "") - } - - if (guideline$code == "tb") { + if (guideline$code == "cmi2012") { + cols_ab <- get_column_abx(x = x, + soft_dependencies = c( + # table 1 (S aureus): + "GEN", + "RIF", + "CPT", + "OXA", + "CIP", + "MFX", + "SXT", + "FUS", + "VAN", + "TEC", + "TLV", + "TGC", + "CLI", + "DAP", + "ERY", + "LNZ", + "CHL", + "FOS", + "QDA", + "TCY", + "DOX", + "MNO", + # table 2 (Enterococcus) + "GEH", + "STH", + "IPM", + "MEM", + "DOR", + "CIP", + "LVX", + "MFX", + "VAN", + "TEC", + "TGC", + "DAP", + "LNZ", + "AMP", + "QDA", + "DOX", + "MNO", + # table 3 (Enterobacteriaceae) + "GEN", + "TOB", + "AMK", + "NET", + "CPT", + "TCC", + "TZP", + "ETP", + "IPM", + "MEM", + "DOR", + "CZO", + "CXM", + "CTX", + "CAZ", + "FEP", + "FOX", + "CTT", + "CIP", + "SXT", + "TGC", + "ATM", + "AMP", + "AMC", + "SAM", + "CHL", + "FOS", + "COL", + "TCY", + "DOX", + "MNO", + # table 4 (Pseudomonas) + "GEN", + "TOB", + "AMK", + "NET", + "IPM", + "MEM", + "DOR", + "CAZ", + "FEP", + "CIP", + "LVX", + "TCC", + "TZP", + "ATM", + "FOS", + "COL", + "PLB", + # table 5 (Acinetobacter) + "GEN", + "TOB", + "AMK", + "NET", + "IPM", + "MEM", + "DOR", + "CIP", + "LVX", + "TZP", + "TCC", + "CTX", + "CRO", + "CAZ", + "FEP", + "SXT", + "SAM", + "COL", + "PLB", + "TCY", + "DOX", + "MNO" + ), + verbose = verbose, ...) + } else if (guideline$code == "tb") { cols_ab <- get_column_abx(x = x, soft_dependencies = c("CAP", "ETH", @@ -188,11 +310,14 @@ mdro <- function(x, CLI <- cols_ab["CLI"] CLR <- cols_ab["CLR"] COL <- cols_ab["COL"] + CPT <- cols_ab["CPT"] CRO <- cols_ab["CRO"] + CTT <- cols_ab["CTT"] CTX <- cols_ab["CTX"] CXM <- cols_ab["CXM"] CZO <- cols_ab["CZO"] DAP <- cols_ab["DAP"] + DOR <- cols_ab["DOR"] DOX <- cols_ab["DOX"] ERY <- cols_ab["ERY"] ETP <- cols_ab["ETP"] @@ -201,6 +326,7 @@ mdro <- function(x, FOS <- cols_ab["FOS"] FOX <- cols_ab["FOX"] FUS <- cols_ab["FUS"] + GEH <- cols_ab["GEH"] GEN <- cols_ab["GEN"] IPM <- cols_ab["IPM"] KAN <- cols_ab["KAN"] @@ -219,6 +345,7 @@ mdro <- function(x, NOR <- cols_ab["NOR"] NOV <- cols_ab["NOV"] OFX <- cols_ab["OFX"] + OXA <- cols_ab["OXA"] PEN <- cols_ab["PEN"] PIP <- cols_ab["PIP"] PLB <- cols_ab["PLB"] @@ -227,12 +354,16 @@ mdro <- function(x, RID <- cols_ab["RID"] RIF <- cols_ab["RIF"] RXT <- cols_ab["RXT"] + SAM <- cols_ab["SAM"] SIS <- cols_ab["SIS"] + STH <- cols_ab["STH"] SXT <- cols_ab["SXT"] + TCC <- cols_ab["TCC"] TCY <- cols_ab["TCY"] TEC <- cols_ab["TEC"] TGC <- cols_ab["TGC"] TIC <- cols_ab["TIC"] + TLV <- cols_ab["TLV"] TMP <- cols_ab["TMP"] TOB <- cols_ab["TOB"] TZP <- cols_ab["TZP"] @@ -251,10 +382,22 @@ mdro <- function(x, if (guideline$code == "tb" & length(abx_tb) == 0) { stop("No antimycobacterials found in data set.", call. = FALSE) } + + if (info == TRUE) { + cat("\nDetermining multidrug-resistant organisms (MDRO), according to:\n", + bold("Guideline: "), italic(guideline$name), "\n", + bold("Version: "), guideline$version, "\n", + bold("Author: "), guideline$author, "\n", + bold("Source: "), guideline$source, "\n", + "\n", sep = "") + } ab_missing <- function(ab) { isTRUE(ab %in% c(NULL, NA)) | length(ab) == 0 } + ab_NA <- function(x) { + x[!is.na(x)] + } # antibiotic classes aminoglycosides <- c(TOB, GEN) @@ -280,16 +423,211 @@ mdro <- function(x, x[rows, "MDRO"] <<- to } } - + trans_tbl2 <- function(txt, rows, lst) { + # function specific for the CMI paper of 2012 (Magiorakos et al.) + lst_vector <- unlist(lst)[!is.na(unlist(lst))] + x$total_groups <- NA_integer_ + x$affected_groups <- NA_integer_ + x[rows, "total_groups"] <- length(lst) + # now the hard part - using two sapply()s for super fast results: + # [1] run through all `rows` with sapply() + # [2] within each row, run through all antibiotic groups with another sapply() + # [3] determine for each antibiotic group in that row if at least 1 drug is R of I + # [4] sum the number of TRUEs of this determination + x[rows, "affected_groups"] <- sapply(rows, + function(row, group_tbl = lst) { + sum(sapply(group_tbl, + function(group) { + any(x[row, group[!is.na(group)]] == "R") | + any(x[row, group[!is.na(group)]] == "I") + }), + na.rm = TRUE) + }) + # now set MDROs: + # MDR (=2): >=3 groups affected + x[which(x$row_number %in% rows & x$affected_groups >= 3), "MDRO"] <<- 2 + # XDR (=3): all but <=2 groups affected + x[which(x$row_number %in% rows & x$total_groups - x$affected_groups <= 2), "MDRO"] <<- 3 + # PDR (=4): all agents are R + x[filter_at(x[rows, ], + vars(lst_vector), + all_vars(. %in% c("R", "I")))$row_number, + "MDRO"] <<- 4 + } + x <- x %>% mutate_at(vars(col_mo), as.mo) %>% # join to microorganisms data set left_join_microorganisms(by = col_mo) %>% # add unconfirmed to where genus is available - mutate(MDRO = ifelse(!is.na(genus), 1, NA_integer_)) %>% + mutate(MDRO = ifelse(!is.na(genus), 1, NA_integer_), + row_number = 1:nrow(x)) %>% # transform to data.frame so subsetting is possible with x[y, z] (might not be the case with tibble/data.table/...) as.data.frame(stringsAsFactors = FALSE) + + if (guideline$code == "cmi2012") { + # CMI, 2012 --------------------------------------------------------------- + # Non-susceptible = R and I + # (see header 'Approaches to Creating Definitions for MDR, XDR and PDR' in paper) + # take amoxicillin if ampicillin is unavailable + if (is.na(AMP) & !is.na(AMX)) AMP <- AMX + # take ceftriaxone if cefotaxime is unavailable and vice versa + if (is.na(CRO) & !is.na(CTX)) CRO <- CTX + if (is.na(CTX) & !is.na(CRO)) CTX <- CRO + + # intrinsic resistant must not be considered for the determination of MDR, + # so let's just remove them, meticulously following the paper + x[which(x$genus == "Enterococcus" & x$species == "faecium"), ab_NA(IPM)] <- NA + x[which(x$genus == "Enterococcus" & x$species == "faecalis"), ab_NA(QDA)] <- NA + x[which((x$genus == "Providencia" & x$species == "rettgeri") + | (x$genus == "Providencia" & x$species == "stuartii")), ab_NA(c(GEN, TOB, NET))] <- NA + x[which(x$genus == "Escherichia" & x$species == "hermannii"), ab_NA(c(TCC, TZP))] <- NA + x[which((x$genus == "Citrobacter" & x$species == "freundii") + | (x$genus == "Enterobacter" & x$species == "aerogenes") + | (x$genus == "Enterobacter" & x$species == "cloacae") + | (x$genus == "Hafnia" & x$species == "alvei") + | (x$genus == "Morganella" & x$species == "morganii") + | (x$genus == "Proteus" & x$species == "penneri") + | (x$genus == "Proteus" & x$species == "vulgaris") + | (x$genus == "Serratia" & x$species == "marcescens")), ab_NA(CZO)] <- NA + x[which((x$genus == "Morganella" & x$species == "morganii") + | (x$genus == "Proteus" & x$species == "penneri") + | (x$genus == "Proteus" & x$species == "vulgaris") + | (x$genus == "Serratia" & x$species == "marcescens")), ab_NA(CXM)] <- NA + x[which((x$genus == "Morganella" & x$species == "morganii") + | (x$genus == "Proteus" & x$species == "mirabilis") + | (x$genus == "Proteus" & x$species == "penneri") + | (x$genus == "Proteus" & x$species == "vulgaris") + | (x$genus == "Providencia" & x$species == "rettgeri") + | (x$genus == "Providencia" & x$species == "stuartii")), ab_NA(TGC)] <- NA + x[which((x$genus == "Citrobacter" & x$species == "koseri") + | (x$genus == "Citrobacter" & x$species == "freundii") + | (x$genus == "Enterobacter" & x$species == "aerogenes") + | (x$genus == "Enterobacter" & x$species == "cloacae") + | (x$genus == "Escherichia" & x$species == "hermannii") + | (x$genus == "Hafnia" & x$species == "alvei") + | (x$genus == "Klebsiella") + | (x$genus == "Morganella" & x$species == "morganii") + | (x$genus == "Proteus" & x$species == "penneri") + | (x$genus == "Proteus" & x$species == "vulgaris") + | (x$genus == "Providencia" & x$species == "rettgeri") + | (x$genus == "Providencia" & x$species == "stuartii") + | (x$genus == "Serratia" & x$species == "marcescens")), ab_NA(AMP)] <- NA + x[which((x$genus == "Citrobacter" & x$species == "freundii") + | (x$genus == "Enterobacter" & x$species == "aerogenes") + | (x$genus == "Enterobacter" & x$species == "cloacae") + | (x$genus == "Hafnia" & x$species == "alvei") + | (x$genus == "Morganella" & x$species == "morganii") + | (x$genus == "Providencia" & x$species == "rettgeri") + | (x$genus == "Providencia" & x$species == "stuartii") + | (x$genus == "Serratia" & x$species == "marcescens")), ab_NA(AMC)] <- NA + x[which((x$genus == "Citrobacter" & x$species == "freundii") + | (x$genus == "Citrobacter" & x$species == "koseri") + | (x$genus == "Enterobacter" & x$species == "aerogenes") + | (x$genus == "Enterobacter" & x$species == "cloacae") + | (x$genus == "Hafnia" & x$species == "alvei") + | (x$genus == "Providencia" & x$species == "rettgeri") + | (x$genus == "Serratia" & x$species == "marcescens")), ab_NA(SAM)] <- NA + x[which((x$genus == "Morganella" & x$species == "morganii") + | (x$genus == "Proteus" & x$species == "mirabilis") + | (x$genus == "Proteus" & x$species == "penneri") + | (x$genus == "Proteus" & x$species == "vulgaris") + | (x$genus == "Providencia" & x$species == "rettgeri") + | (x$genus == "Providencia" & x$species == "stuartii") + | (x$genus == "Serratia" & x$species == "marcescens")), ab_NA(COL)] <- NA + x[which((x$genus == "Morganella" & x$species == "morganii") + | (x$genus == "Proteus" & x$species == "mirabilis") + | (x$genus == "Proteus" & x$species == "penneri") + | (x$genus == "Proteus" & x$species == "vulgaris") + | (x$genus == "Providencia" & x$species == "rettgeri") + | (x$genus == "Providencia" & x$species == "stuartii")), ab_NA(TCY)] <- NA + x[which((x$genus == "Morganella" & x$species == "morganii") + | (x$genus == "Proteus" & x$species == "penneri") + | (x$genus == "Proteus" & x$species == "vulgaris") + | (x$genus == "Providencia" & x$species == "rettgeri") + | (x$genus == "Providencia" & x$species == "stuartii")), ab_NA(c(DOX, MNO))] <- NA + + # now add the MDR levels to the data + trans_tbl(2, + which(x$genus == "Staphylococcus" & x$species == "aureus"), + c(OXA, FOX), + "any") + trans_tbl2(paste("Table 1 -", italic("S. aureus")), + which(x$genus == "Staphylococcus" & x$species == "aureus"), + list(GEN, + RIF, + CPT, + c(OXA, FOX), + c(CIP, MFX), + SXT, + FUS, + c(VAN, TEC, TLV), + TGC, + CLI, + DAP, + ERY, + LNZ, + CHL, + FOS, + QDA, + c(TCY, DOX, MNO))) + trans_tbl2(paste("Table 2 -", italic("Enterococcus"), "spp"), + which(x$genus == "Enterococcus"), + list(GEH, + STH, + c(IPM, MEM, DOR), + c(CIP, LVX, MFX), + c(VAN, TEC), + TGC, + DAP, + LNZ, + AMP, + QDA, + c(DOX, MNO))) + trans_tbl2(paste("Table 3 -", italic("Enterobacteriaceae")), + which(x$family == "Enterobacteriaceae"), + list(c(GEN, TOB, AMK, NET), + CPT, + c(TCC, TZP), + c(ETP, IPM, MEM, DOR), + CZO, + CXM, + c(CTX, CAZ, FEP), + c(FOX, CTT), + CIP, + SXT, + TGC, + ATM, + AMP, + c(AMC, SAM), + CHL, + FOS, + COL, + c(TCY, DOX, MNO))) + trans_tbl2(paste("Table 4 -", italic("Pseudomonas aeruginosa")), + which(x$genus == "Pseudomonas" & x$species == "aeruginosa"), + list(c(GEN, TOB, AMK, NET), + c(IPM, MEM, DOR), + c(CAZ, FEP), + c(CIP, LVX), + c(TCC, TZP), + ATM, + FOS, + c(COL, PLB))) + trans_tbl2(paste("Table 5 -", italic("Acinetobacter"), "spp"), + which(x$genus == "Acinetobacter"), + list(c(GEN, TOB, AMK, NET), + c(IPM, MEM, DOR), + c(CIP, LVX), + c(TZP, TCC), + c(CTX, CRO, CAZ, FEP), + SXT, + SAM, + c(COL, PLB), + c(TCY, DOX, MNO))) + } + if (guideline$code == "eucast") { # EUCAST ------------------------------------------------------------------ # Table 5 @@ -534,20 +872,32 @@ mdro <- function(x, second = ifelse(drug_is_R(CAP) | drug_is_R(KAN) | drug_is_R(AMK), TRUE, FALSE), xdr = ifelse(mdr & xdr & second, TRUE, FALSE)) %>% - mutate(mdr_tb = case_when(xdr ~ 5, + mutate(MDRO = case_when(xdr ~ 5, mdr ~ 4, poly ~ 3, mono ~ 2, TRUE ~ 1), # keep all real TB, make other species NA - mdr_tb = ifelse(x$fullname == "Mycobacterium tuberculosis", mdr_tb, NA_real_)) + MDRO = ifelse(x$fullname == "Mycobacterium tuberculosis", MDRO, NA_real_)) + } + + if (info == TRUE) { + cat(bold(paste0("=> Found ", sum(x$MDRO %in% c(2:5), na.rm = TRUE), " MDROs out of ", sum(!is.na(x$MDRO)), + " possible cases (", percentage(sum(x$MDRO %in% c(2:5), na.rm = TRUE) / sum(!is.na(x$MDRO))), ")"))) } # return results - if (guideline$code == "tb") { - factor(x = x$mdr_tb, + if (guideline$code == "cmi2012") { + factor(x = x$MDRO, + levels = 1:4, + labels = c("Negative", "Multi-drug-resistant (MDR)", + "Extensively drug-resistant (XDR)", "Pandrug-resistant (PDR)"), + ordered = TRUE) + } else if (guideline$code == "tb") { + factor(x = x$MDRO, levels = 1:5, - labels = c("Negative", "Mono-resistant", "Poly-resistant", "Multi-drug-resistant", "Extensive drug-resistant"), + labels = c("Negative", "Mono-resistant", "Poly-resistant", + "Multi-drug-resistant", "Extensively drug-resistant"), ordered = TRUE) } else if (guideline$code == "mrgn") { factor(x = x$MDRO, @@ -580,6 +930,13 @@ mdr_tb <- function(x, guideline = "TB", ...) { mdro(x = x, guideline = "TB", ...) } +#' @rdname mdro +#' @export +mdr_cmi2012 <- function(x, guideline = "CMI2012", ...) { + mdro(x = x, guideline = "CMI2012", ...) +} + + #' @rdname mdro #' @export eucast_exceptional_phenotypes <- function(x, guideline = "EUCAST", ...) { diff --git a/data-raw/reproduction_of_antibiotics.R b/data-raw/reproduction_of_antibiotics.R index 782ef4a9..a3ae34ac 100644 --- a/data-raw/reproduction_of_antibiotics.R +++ b/data-raw/reproduction_of_antibiotics.R @@ -305,9 +305,18 @@ antibiotics[which(antibiotics$ab == "FEP"), "abbreviations"][[1]] <- list(c(anti antibiotics[which(antibiotics$ab == "CTC"), "abbreviations"][[1]] <- list(c("xctl")) antibiotics[which(antibiotics$ab == "CTX"), "abbreviations"][[1]] <- list(c(antibiotics[which(antibiotics$ab == "CTX"), "abbreviations"][[1]], "xct")) # High level Gentamcin and Streptomycin -antibiotics[which(antibiotics$ab == "GEH"), "abbreviations"][[1]] <- list(c("gehl")) -antibiotics[which(antibiotics$ab == "STH"), "abbreviations"][[1]] <- list(c("sthl")) +antibiotics[which(antibiotics$ab == "GEH"), "abbreviations"][[1]] <- list(c("gehl", "gentamicin high", "genta high")) +antibiotics[which(antibiotics$ab == "STH"), "abbreviations"][[1]] <- list(c("sthl", "streptomycin high", "strepto high")) +# add imi to imipenem +antibiotics[which(antibiotics$ab == "IPM"), "abbreviations"][[1]] <- list(c("imip", "imi")) +## new ATC codes +# ceftaroline +antibiotics[which(antibiotics$ab == "CPT"), "atc"] <- "J01DI02" +# faropenem +antibiotics[which(antibiotics$ab == "FAR"), "atc"] <- "J01DI03" +# ceftobiprole +antibiotics[which(antibiotics$ab == "BPR"), "atc"] <- "J01DI01" antibiotics <- antibiotics %>% arrange(name) diff --git a/data/antibiotics.rda b/data/antibiotics.rda index a1d088c1..898a512a 100755 Binary files a/data/antibiotics.rda and b/data/antibiotics.rda differ diff --git a/docs/404.html b/docs/404.html index 2dc63781..7fd4293e 100644 --- a/docs/404.html +++ b/docs/404.html @@ -84,7 +84,7 @@ AMR (for R) - 0.8.0.9003 + 0.8.0.9004 diff --git a/docs/LICENSE-text.html b/docs/LICENSE-text.html index eae10881..c1050c8f 100644 --- a/docs/LICENSE-text.html +++ b/docs/LICENSE-text.html @@ -84,7 +84,7 @@ AMR (for R) - 0.8.0.9003 + 0.8.0.9004 diff --git a/docs/articles/index.html b/docs/articles/index.html index ed6229f1..3136c996 100644 --- a/docs/articles/index.html +++ b/docs/articles/index.html @@ -84,7 +84,7 @@ AMR (for R) - 0.8.0.9003 + 0.8.0.9004 diff --git a/docs/authors.html b/docs/authors.html index 0dd667f8..26436eaf 100644 --- a/docs/authors.html +++ b/docs/authors.html @@ -84,7 +84,7 @@ AMR (for R) - 0.8.0.9003 + 0.8.0.9004 diff --git a/docs/index.html b/docs/index.html index 044705a3..1cb0d83e 100644 --- a/docs/index.html +++ b/docs/index.html @@ -45,7 +45,7 @@ AMR (for R) - 0.8.0.9003 + 0.8.0.9004 diff --git a/docs/news/index.html b/docs/news/index.html index 0916eaff..35e7d21c 100644 --- a/docs/news/index.html +++ b/docs/news/index.html @@ -84,7 +84,7 @@ AMR (for R) - 0.8.0.9003 + 0.8.0.9004 @@ -231,11 +231,19 @@ -
+

-AMR 0.8.0.9003 Unreleased +AMR 0.8.0.9004 Unreleased

-

Last updated: 23-Oct-2019

+

Last updated: 26-Oct-2019

+
+

+New

+
    +
  • Support for a new MDRO guideline: Magiorakos AP, Srinivasan A et al. “Multidrug-resistant, extensively drug-resistant and pandrug-resistant bacteria: an international expert proposal for interim standard definitions for acquired resistance.” Clinical Microbiology and Infection (2012). This is now the new default guideline for the mdro() function. +
  • +
+

Changes

@@ -246,6 +254,10 @@
  • Fix for interpreting MIC values with as.rsi() where the input is NA
  • +
  • Added “imi” as allowed abbreviation for Imipenem
  • +
  • Fix for automatically determining columns with antibiotic results in mdro() and eucast_rules() +
  • +
  • Added ATC codes for ceftaroline, ceftobiprole and faropenem
  • @@ -279,9 +291,9 @@ This is important, because a value like "testvalue" could never be
  • Renamed data set septic_patients to example_isolates

  • -
    +

    -New

    +New