From 450992baeabf1dcfc64872e65847e8bee3b3ce49 Mon Sep 17 00:00:00 2001 From: "Matthijs S. Berends" Date: Tue, 25 Sep 2018 16:44:40 +0200 Subject: [PATCH] new: 1680 old taxonomic names --- .travis.yml | 3 +- R/ab_property.R | 4 +- R/data.R | 2 +- R/misc.R | 20 ------ R/mo.R | 112 ++++++++++++++++++++---------- R/mo_property.R | 17 +++-- README.md | 2 +- data/microorganisms.old.rda | Bin 1751 -> 28271 bytes man/ab_property.Rd | 2 +- man/as.mo.Rd | 2 +- man/microorganisms.Rd | 2 +- man/microorganisms.old.Rd | 4 +- man/mo_property.Rd | 6 +- tests/testthat/test-mo_property.R | 12 ++-- 14 files changed, 102 insertions(+), 86 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2d91175c..71ceb601 100755 --- a/.travis.yml +++ b/.travis.yml @@ -43,8 +43,7 @@ before_install: - if [ $TRAVIS_OS_NAME = osx ]; then brew install libgit2; fi install: - - Rscript -e "install.packages('devtools')" - - Rscript -e "install.packages('knitr')" + - Rscript -e "install.packages(c('devtools', 'backports', 'clipr', 'curl', 'data.table', 'dplyr', 'hms', 'knitr', 'readr', 'rlang', 'rvest', 'xml2'))" - if [ $TRAVIS_OS_NAME = osx ]; then Rscript -e "devtools::install_github('r-lib/rlang')"; fi # postrun diff --git a/R/ab_property.R b/R/ab_property.R index b8befa3e..1005b102 100644 --- a/R/ab_property.R +++ b/R/ab_property.R @@ -21,7 +21,7 @@ #' Use these functions to return a specific property of an antibiotic from the \code{\link{antibiotics}} data set, based on their ATC code. Get such a code with \code{\link{as.atc}}. #' @param x a (vector of a) valid \code{\link{atc}} code or any text that can be coerced to a valid atc with \code{\link{as.atc}} #' @param property one of the column names of one of the \code{\link{antibiotics}} data set, like \code{"atc"} and \code{"official"} -#' @param language language of the returned text, defaults to the systems language. Either one of \code{"en"} (English) or \code{"nl"} (Dutch). +#' @param language language of the returned text, defaults to English (\code{"en"}) and can be set with \code{\link{getOption}("AMR_locale")}. Either one of \code{"en"} (English) or \code{"nl"} (Dutch). #' @rdname ab_property #' @return A vector of values. In case of \code{ab_tradenames}, if \code{x} is of length one, a vector will be returned. Otherwise a \code{\link{list}}, with \code{x} as names. #' @export @@ -60,7 +60,7 @@ ab_atc <- function(x) { ab_official <- function(x, language = NULL) { if (is.null(language)) { - language <- Sys.locale() + language <- getOption("AMR_locale", default = "en")[1L] } else { language <- tolower(language[1]) } diff --git a/R/data.R b/R/data.R index b01e2fd7..bb529c12 100755 --- a/R/data.R +++ b/R/data.R @@ -150,7 +150,7 @@ #' #' A data set containing old, previously valid, taxonomic names. This data set is used internally by \code{\link{as.mo}}. #' @inheritSection as.mo ITIS -#' @format A \code{\link{data.frame}} with 58 observations and 5 variables: +#' @format A \code{\link{data.frame}} with 1,682 observations and 5 variables: #' \describe{ #' \item{\code{tsn}}{Old Taxonomic Serial Number (TSN), as defined by ITIS} #' \item{\code{name}}{Old taxonomic name of the microorganism as found in ITIS, see Source} diff --git a/R/misc.R b/R/misc.R index 56d8b746..f5097fa3 100755 --- a/R/misc.R +++ b/R/misc.R @@ -155,26 +155,6 @@ tbl_parse_guess <- function(tbl, tbl } -#' @importFrom dplyr case_when -Sys.locale <- function() { - alreadyset <- getOption("AMR_locale") - if (!is.null(alreadyset)) { - if (tolower(alreadyset) %in% c("en", "de", "nl", "es", "fr", "pt", "it")) { - return(tolower(alreadyset)) - } - } - sys <- base::Sys.getlocale() - case_when( - sys %like% '(Deutsch|German|de_)' ~ "de", - sys %like% '(Nederlands|Dutch|nl_)' ~ "nl", - sys %like% '(Espa.ol|Spanish|es_)' ~ "es", - sys %like% '(Fran.ais|French|fr_)' ~ "fr", - sys %like% '(Portugu.s|Portuguese|pt_)' ~ "pt", - sys %like% '(Italiano|Italian|it_)' ~ "it", - TRUE ~ "en" - ) -} - # transforms date format like "dddd d mmmm yyyy" to "%A %e %B %Y" date_generic <- function(format) { if (!grepl('%', format, fixed = TRUE)) { diff --git a/R/mo.R b/R/mo.R index ce8c1078..1cd4797e 100644 --- a/R/mo.R +++ b/R/mo.R @@ -60,7 +60,7 @@ #' \code{guess_mo} is an alias of \code{as.mo}. #' @section ITIS: #' \if{html}{\figure{itis_logo.jpg}{options: height=60px style=margin-bottom:5px} \cr} -#' This \code{AMR} package contains the \strong{complete microbial taxonomic data} from the publicly available Integrated Taxonomic Information System (ITIS, https://www.itis.gov). ITIS is a partnership of U.S., Canadian, and Mexican agencies and taxonomic specialists [3]. The complete taxonomic kingdoms Bacteria, Fungi and Protozoa (from subkingdom to the subspecies level) are included in this package. +#' This \code{AMR} package contains the \strong{complete microbial taxonomic data} (with seven taxonomic ranks - from subkingdom to subspecies) from the publicly available Integrated Taxonomic Information System (ITIS, https://www.itis.gov). ITIS is a partnership of U.S., Canadian, and Mexican agencies and taxonomic specialists [3]. The complete taxonomic kingdoms Bacteria, Fungi and Protozoa are included in this package, as well as all previously accepted names known to ITIS. # (source as section, so it can be inherited by mo_property:) #' @section Source: #' [1] Becker K \emph{et al.} \strong{Coagulase-Negative Staphylococci}. 2014. Clin Microbiol Rev. 27(4): 870–926. \url{https://dx.doi.org/10.1128/CMR.00109-13} @@ -302,7 +302,8 @@ as.mo <- function(x, Becker = FALSE, Lancefield = FALSE, allow_uncertain = FALSE next } found <- MOs_mostprevalent[mo.old == toupper(x_backup[i]) - | (substr(x_backup[i], 4, 6) == "SPP" & mo.old == substr(x_backup[i], 1, 3)), mo] + | (substr(x_backup[i], 4, 6) == "SPP" & mo.old == substr(x_backup[i], 1, 3)) + | mo.old == substr(x_backup[i], 1, 3), mo] # is a valid old mo if (length(found) > 0) { x[i] <- found[1L] @@ -395,7 +396,9 @@ as.mo <- function(x, Becker = FALSE, Lancefield = FALSE, allow_uncertain = FALSE x[i] <- found[1L] next } - found <- MOs_allothers[mo.old == toupper(x_backup[i]), mo] + found <- MOs_allothers[mo.old == toupper(x_backup[i]) + | (substr(x_backup[i], 4, 6) == "SPP" & mo.old == substr(x_backup[i], 1, 3)) + | mo.old == substr(x_backup[i], 1, 3), mo] # is a valid old mo if (length(found) > 0) { x[i] <- found[1L] @@ -463,27 +466,47 @@ as.mo <- function(x, Becker = FALSE, Lancefield = FALSE, allow_uncertain = FALSE # look for old taxonomic names ---- if (is.null(MOs_old)) { - MOs_old <- as.data.table(microorganisms.old) + MOs_old <- as.data.table(AMR::microorganisms.old) setkey(MOs_old, name, tsn_new) } found <- MOs_old[tolower(name) == tolower(x_backup[i]) | tsn == x_trimmed[i],] if (NROW(found) > 0) { x[i] <- MOs[tsn == found[1, tsn_new], mo] - message("Note: '", found[1, name], "' was renamed to '", - MOs[tsn == found[1, tsn_new], fullname], "' by ", - found[1, authors], " in ", found[1, year]) + renamed_note(name_old = found[1, name], + name_new = MOs[tsn == found[1, tsn_new], fullname], + authors = found[1, authors], + year = found[1, year]) next } # check for uncertain results ---- - # (1) try to strip off one element and check the remains if (allow_uncertain == TRUE) { + # (1) look again for old taxonomic names, now for G. species ---- + found <- MOs_old[name %like% x_withspaces[i] + | name %like% x_withspaces_start[i] + | name %like% x[i],] + if (NROW(found) > 0) { + x[i] <- MOs[tsn == found[1, tsn_new], mo] + warning("Uncertain interpretation: '", + x_backup[i], "' -> '", found[1, name], "'", + call. = FALSE, immediate. = TRUE) + renamed_note(name_old = found[1, name], + name_new = MOs[tsn == found[1, tsn_new], fullname], + authors = found[1, authors], + year = found[1, year]) + + next + } + + # (2) try to strip off one element and check the remains x_strip <- x_backup[i] %>% strsplit(" ") %>% unlist() x_strip <- x_strip[1:length(x_strip) - 1] x[i] <- suppressWarnings(suppressMessages(as.mo(x_strip))) if (!is.na(x[i])) { - warning("Uncertain result: '", x_backup[i], "' -> '", MOs[mo == x[i], fullname], "' (", x[i], ")") + warning("Uncertain interpretation: '", + x_backup[i], "' -> '", MOs[mo == x[i], fullname], "' (", x[i], ")", + call. = FALSE, immediate. = TRUE) next } } @@ -506,28 +529,24 @@ as.mo <- function(x, Becker = FALSE, Lancefield = FALSE, allow_uncertain = FALSE if (Becker == TRUE | Becker == "all") { # See Source. It's this figure: # https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4187637/figure/F3/ - CoNS <- MOs %>% - filter(genus == "Staphylococcus", - species %in% c("arlettae", "auricularis", "capitis", - "caprae", "carnosus", "cohnii", "condimenti", - "devriesei", "epidermidis", "equorum", - "fleurettii", "gallinarum", "haemolyticus", - "hominis", "jettensis", "kloosii", "lentus", - "lugdunensis", "massiliensis", "microti", - "muscae", "nepalensis", "pasteuri", "petrasii", - "pettenkoferi", "piscifermentans", "rostri", - "saccharolyticus", "saprophyticus", "sciuri", - "stepanovicii", "simulans", "succinus", - "vitulinus", "warneri", "xylosus")) %>% - pull(mo) - CoPS <- MOs %>% - filter(genus == "Staphylococcus", - species %in% c("simiae", "agnetis", "chromogenes", - "delphini", "felis", "lutrae", - "hyicus", "intermedius", - "pseudintermedius", "pseudointermedius", - "schleiferi")) %>% - pull(mo) + MOs_staph <- MOs[genus == "Staphylococcus"] + setkey(MOs_staph, species) + CoNS <- MOs_staph[species %in% c("arlettae", "auricularis", "capitis", + "caprae", "carnosus", "cohnii", "condimenti", + "devriesei", "epidermidis", "equorum", + "fleurettii", "gallinarum", "haemolyticus", + "hominis", "jettensis", "kloosii", "lentus", + "lugdunensis", "massiliensis", "microti", + "muscae", "nepalensis", "pasteuri", "petrasii", + "pettenkoferi", "piscifermentans", "rostri", + "saccharolyticus", "saprophyticus", "sciuri", + "stepanovicii", "simulans", "succinus", + "vitulinus", "warneri", "xylosus"), mo] + CoPS <- MOs_staph[species %in% c("simiae", "agnetis", "chromogenes", + "delphini", "felis", "lutrae", + "hyicus", "intermedius", + "pseudintermedius", "pseudointermedius", + "schleiferi"), mo] x[x %in% CoNS] <- "B_STPHY_CNS" x[x %in% CoPS] <- "B_STPHY_CPS" if (Becker == "all") { @@ -559,16 +578,24 @@ as.mo <- function(x, Becker = FALSE, Lancefield = FALSE, allow_uncertain = FALSE } # left join the found results to the original input values (x_input) - df_found <- data.frame(input = as.character(unique(x_input)), + DT_found <- data.table(input = as.character(unique(x_input)), found = x, + key = "input", stringsAsFactors = FALSE) - df_input <- data.frame(input = as.character(x_input), + DT_input <- data.table(input = as.character(x_input), + key = "input", stringsAsFactors = FALSE) + x <- DT_found[DT_input, on = "input", found] - x <- df_input %>% - left_join(df_found, - by = "input") %>% - pull(found) + # df_found <- data.frame(input = as.character(unique(x_input)), + # found = x, + # stringsAsFactors = FALSE) + # df_input <- data.frame(input = as.character(x_input), + # stringsAsFactors = FALSE) + # x <- df_input %>% + # left_join(df_found, + # by = "input") %>% + # pull(found) class(x) <- "mo" attr(x, 'package') <- 'AMR' @@ -576,6 +603,17 @@ as.mo <- function(x, Becker = FALSE, Lancefield = FALSE, allow_uncertain = FALSE x } +renamed_note <- function(name_old, name_new, authors, year) { + msg <- paste0("Note: '", name_old, "' was renamed to '", name_new, "'") + if (!authors %in% c("", NA)) { + msg <- paste0(msg, " by ", authors) + } + if (!year %in% c("", NA)) { + msg <- paste0(msg, " in ", year) + } + base::message(msg) +} + #' @rdname as.mo #' @export diff --git a/R/mo_property.R b/R/mo_property.R index 910e969d..89f9061a 100644 --- a/R/mo_property.R +++ b/R/mo_property.R @@ -20,9 +20,9 @@ #' #' Use these functions to return a specific property of a microorganism from the \code{\link{microorganisms}} data set. All input values will be evaluated internally with \code{\link{as.mo}}. #' @param x any (vector of) text that can be coerced to a valid microorganism code with \code{\link{as.mo}} -#' @param property one of the column names of one of the \code{\link{microorganisms}} data set, like \code{"mo"}, \code{"bactsys"}, \code{"family"}, \code{"genus"}, \code{"species"}, \code{"fullname"}, \code{"gramstain"} and \code{"aerobic"} +#' @param property one of the column names of one of the \code{\link{microorganisms}} data set or \code{"shortname"} #' @inheritParams as.mo -#' @param language language of the returned text, defaults to the systems language but can also be set with \code{\link{getOption}("AMR_locale")}. Either one of \code{"en"} (English), \code{"de"} (German), \code{"nl"} (Dutch), \code{"es"} (Spanish) or \code{"pt"} (Portuguese). +#' @param language language of the returned text, defaults to English (\code{"en"}) and can also be set with \code{\link{getOption}("AMR_locale")}. Either one of \code{"en"} (English), \code{"de"} (German), \code{"nl"} (Dutch), \code{"es"} (Spanish) or \code{"pt"} (Portuguese). #' @inheritSection as.mo ITIS #' @inheritSection as.mo Source #' @rdname mo_property @@ -113,8 +113,8 @@ mo_shortname <- function(x, Becker = FALSE, Lancefield = FALSE, language = NULL) res2_fullname <- gsub("Streptococcus (group|Gruppe|gruppe|groep|grupo|gruppo|groupe) (.)", "G\\2S", res2_fullname) # turn "Streptococcus group A" and "Streptococcus grupo A" to "GAS" - res2_fullname_vector <- res2_fullname[res2_fullname == mo_fullname(x)] - res2_fullname[res2_fullname == mo_fullname(x)] <- paste0(substr(mo_genus(res2_fullname_vector), 1, 1), + res2_fullname_vector <- res2_fullname[res2_fullname == mo_fullname(res1)] + res2_fullname[res2_fullname == mo_fullname(res1)] <- paste0(substr(mo_genus(res2_fullname_vector), 1, 1), ". ", suppressWarnings(mo_species(res2_fullname_vector))) if (sum(res1 == res2, na.rm = TRUE) > 0) { @@ -125,6 +125,7 @@ mo_shortname <- function(x, Becker = FALSE, Lancefield = FALSE, language = NULL) res1[res1 != res2] <- res2_fullname result <- as.character(res1) } else { + x <- AMR::as.mo(x) # return G. species result <- paste0(substr(mo_genus(x), 1, 1), ". ", suppressWarnings(mo_species(x))) } @@ -208,11 +209,9 @@ mo_property <- function(x, property = 'fullname', Becker = FALSE, Lancefield = F } if (Becker == TRUE | Lancefield == TRUE | !is.mo(x)) { # this will give a warning if x cannot be coerced - result1 <- AMR::as.mo(x = x, Becker = Becker, Lancefield = Lancefield) - } else { - result1 <- x + x <- AMR::as.mo(x = x, Becker = Becker, Lancefield = Lancefield) } - A <- data.table(mo = result1, stringsAsFactors = FALSE) + A <- data.table(mo = x, stringsAsFactors = FALSE) B <- as.data.table(AMR::microorganisms) setkey(B, mo) result2 <- B[A, on = 'mo', ..property][[1]] @@ -246,7 +245,7 @@ mo_taxonomy <- function(x) { #' @importFrom dplyr %>% case_when mo_translate <- function(x, language) { if (is.null(language)) { - language <- Sys.locale() + language <- getOption("AMR_locale", default = "en")[1L] } else { language <- tolower(language[1]) } diff --git a/README.md b/README.md index d30fddd7..1920a06d 100755 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ This R package was intended **to make microbial epidemiology easier**. Most func -This `AMR` package contains the *complete microbial taxonomic data* from the publicly available Integrated Taxonomic Information System (ITIS, https://www.itis.gov). ITIS is a partnership of U.S., Canadian, and Mexican agencies and taxonomic specialists. The complete taxonomic kingdoms Bacteria, Fungi and Protozoa (from subkingdom to the subspecies level) are included in this package. This allows users to use authoritative taxonomic information for their data analyses on any microorganisms, not only human pathogens. +This `AMR` package contains the **complete microbial taxonomic data** (with seven taxonomic ranks - from subkingdom to subspecies) from the publicly available Integrated Taxonomic Information System (ITIS, https://www.itis.gov). ITIS is a partnership of U.S., Canadian, and Mexican agencies and taxonomic specialists. The complete taxonomic kingdoms Bacteria, Fungi and Protozoa are included in this package, as well as all previously accepted names known to ITIS. This allows users to use authoritative taxonomic information for their data analyses on any microorganisms, not only human pathogens. Combined with several new functions, this `AMR` package basically does four important things: diff --git a/data/microorganisms.old.rda b/data/microorganisms.old.rda index 155803aafd53ce3af77695d45aacd1fc6a9960cd..e6b9233b7738eb324c18bea472eebd7d443b6e90 100644 GIT binary patch literal 28271 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 literal 1751 zcmV;|1}OPLT4*^jL0KkKSq9_-%m4$$|Ns8K|Ns8S`gA|u-tfQw|KwkQz(DW_I3>UT zZoDY|@W0>&Jw@w2ne34zP$(23s7jxcRQ9CVOwv6xO)_8;AjyFSm}p{XH8BkU4A5vA z8cc_hdQ8%ONxe*VlYiKU$5+V~s(J~rMG!sxfO*J&o zG|{F_4FCtJ`hfrgMnUQ^G|14%27mw!4Ago13r;d4G&6b3NnTxE$L+<*g2s-7~@HZ}hmOj6T6?e!}c`Y3jMJi^fuW`IrmBnC)>&&cRaunM^CnH4 zOyNE2tdMQd5+9I;a5Q?EfDr@aF3<2~aq(#ZsuSqGzycQQ74{Lnp7{$jUPoFSswR@T z)otk@01^2}Jzy3IML9qO0DVe7r2+u*8c1IKo@@WC5F)Hig`x!5zw<;e8xm~}Aw**! zOhFLen!G-*g#M!f7(S;Nh)4j#0JYl=00e)47bLS`0OBiXk_Z?<=i@*?NR(J{Z^9U< zX$qUxE^gk~*4P%SHC_rkPEuD@g3$I9q^9Jo!gAQ#8)MpXI<3A*IdTeeZ>$zfNo!1> zA3ravJl#hke5OIbnPG5=1RmBys1`RGQgahbU7}>dJ1i!W=|Sl9l1o8GOr#+Sgv&T^ zWn|TC z=XtEMoXt=o0xCV|mr}3ro*{QVr^P#@`-*nOJ%l#eBesPs?qbsnwYzhV!(G<3bN0uc zdExz@NiiPO^8MklEt%_dh30DAH3CK7_}kV71TwAi(>(7hLSmomdgvl+ep$M zk-}Md$v$8CG$>9-LK^|r+@gtmY>Mcx)kI(go}pqW%j zM5>dbQ*AubidxKkRL-^Lkv&XOa>a`903om;!38D_^oRl06ywBp08>g9feo^lj_3xU z=~Ar%ZGaxG6jUw(Ga_>APk&+*Rfj!nMB=yflNQ9>df6Lhd<+G> zZgWJo6;|3}yb)=Q#%?vVAc;i+X4)o}Tr|%&eR0k=v1cd-SZZhtWTE?oJEDf7uzd@{ z6B77Ag-FE#3W5v3PcSdSVrxABfk9he5`$GH;8KhWHn9#yCt1$&;!p==7!tK~8sSo? zX^ku}XApv*GCPaDhlYIUN$_VtNX%4|)3u9LiEA z6js<;Fpk2dDFzJC;MYx|~|xP~1a=)DVsMH4V3Dp>3gAbgLU<9WknVh=pSjaw2mr>#>bY zs~ZPvfWo!p(TkTvBtR7lKUkHgR=_H6h|?7z!*p7=EZ)(i6Val77 zePTk_3Yayx9j4*atlNj^e0@Ug`tRB#CGU={{!ID9n8G{>fx5=*is>fMdN4rCKtX6h tEJVemQcOTDy&wkRkkTnGR-G%+q%Sbdg}f(KftY{scO+AV2>@% filter(!is.na(mo), - species != "species", - dplyr::row_number() %in% rnd) - expect_identical(MOs$fullname, mo_fullname(MOs$fullname, language = "en")) + # library(dplyr) + # rnd <- sample(1:nrow(AMR::microorganisms), 500, replace = FALSE) # random 500 rows + # MOs <- AMR::microorganisms %>% filter(!is.na(mo), + # species != "species", + # dplyr::row_number() %in% rnd) + # expect_identical(MOs$fullname, mo_fullname(MOs$fullname, language = "en")) # check languages expect_equal(mo_type("E. coli", language = "de"), "Bakterien")