extend vctrs support

This commit is contained in:
dr. M.S. (Matthijs) Berends 2022-10-31 11:19:06 +01:00
parent 9444ed6d1d
commit 796b972f8a
6 changed files with 145 additions and 29 deletions

View File

@ -1,6 +1,6 @@
Package: AMR Package: AMR
Version: 1.8.2.9039 Version: 1.8.2.9040
Date: 2022-10-30 Date: 2022-10-31
Title: Antimicrobial Resistance Data Analysis Title: Antimicrobial Resistance Data Analysis
Description: Functions to simplify and standardise antimicrobial resistance (AMR) Description: Functions to simplify and standardise antimicrobial resistance (AMR)
data analysis and to work with microbial and antimicrobial properties by data analysis and to work with microbial and antimicrobial properties by

33
NEWS.md
View File

@ -1,4 +1,4 @@
# AMR 1.8.2.9039 # AMR 1.8.2.9040
This version will eventually become v2.0! We're happy to reach a new major milestone soon! This version will eventually become v2.0! We're happy to reach a new major milestone soon!
@ -15,32 +15,35 @@ This version will eventually become v2.0! We're happy to reach a new major miles
### New ### New
* EUCAST 2022 and CLSI 2022 guidelines have been added for `as.rsi()`. EUCAST 2022 is now the new default guideline for all MIC and disks diffusion interpretations. * EUCAST 2022 and CLSI 2022 guidelines have been added for `as.rsi()`. EUCAST 2022 is now the new default guideline for all MIC and disks diffusion interpretations.
* Support for the following languages: Chinese, Greek, Japanese, Polish, Turkish and Ukrainian. We are very grateful for the valuable input by our colleagues from other countries. The `AMR` package is now available in 16 languages. The automatic language determination will give a note at start-up on systems in supported languages.
* All new algorithm for `as.mo()` (and thus all `mo_*()` functions) while still following our original set-up as described in our paper (DOI 10.18637/jss.v104.i03). * All new algorithm for `as.mo()` (and thus all `mo_*()` functions) while still following our original set-up as described in our paper (DOI 10.18637/jss.v104.i03).
* A new argument `keep_synonyms` allows to *not* correct for updated taxonomy, in favour of the now deleted argument `allow_uncertain` * A new argument `keep_synonyms` allows to *not* correct for updated taxonomy, in favour of the now deleted argument `allow_uncertain`
* It has increased tremendously in speed and returns generally more consequent results * It has increased tremendously in speed and returns generally more consequent results
* Sequential coercion is now extremely fast as results are stored to the package environment, although coercion of unknown values must be run once per session. Previous results can be reset/removed with the new `mo_reset_session()` function. * Sequential coercion is now extremely fast as results are stored to the package environment, although coercion of unknown values must be run once per session. Previous results can be reset/removed with the new `mo_reset_session()` function.
* Support for microorganism codes of the ASIan Antimicrobial Resistance Surveillance Network (ASIARS-Net) * Support for microorganism codes of the ASIan Antimicrobial Resistance Surveillance Network (ASIARS-Net)
* Function `rsi_confidence_interval()` to add confidence intervals in AMR calculation. This is also included in `rsi_df()` and `proportion_df()`
* Function `mean_amr_distance()` to calculate the mean AMR distance. The mean AMR distance is a normalised numeric value to compare AMR test results and can help to identify similar isolates, without comparing antibiograms by hand. * New functions!
* Function `rsi_interpretation_history()` to view the history of previous runs of `as.rsi()`. This returns a 'logbook' with the selected guideline, reference table and specific interpretation of each row in a data set on which `as.rsi()` was run. * Function `rsi_confidence_interval()` to add confidence intervals in AMR calculation. This is also included in `rsi_df()` and `proportion_df()`
* Function `mo_current()` to get the currently valid taxonomic name of a microorganism * Function `mean_amr_distance()` to calculate the mean AMR distance. The mean AMR distance is a normalised numeric value to compare AMR test results and can help to identify similar isolates, without comparing antibiograms by hand.
* Function `add_custom_antimicrobials()` to add custom antimicrobial codes and names to the `AMR` package * Function `rsi_interpretation_history()` to view the history of previous runs of `as.rsi()`. This returns a 'logbook' with the selected guideline, reference table and specific interpretation of each row in a data set on which `as.rsi()` was run.
* Support for `data.frame`-enhancing R packages, more specifically: `data.table::data.table`, `janitor::tabyl`, `tibble::tibble`, and `tsibble::tsibble`. AMR package functions that have a data set as output (such as `rsi_df()` and `bug_drug_combinations()`), will now return the same data type as the input. * Function `mo_current()` to get the currently valid taxonomic name of a microorganism
* All data sets in this package are now exported as `tibble`, instead of base R `data.frame`s. Older R versions are still supported. * Function `add_custom_antimicrobials()` to add custom antimicrobial codes and names to the `AMR` package
* Support for the following languages: Chinese, Greek, Japanese, Polish, Turkish and Ukrainian. We are very grateful for the valuable input by our colleagues from other countries. The `AMR` package is now available in 16 languages. The automatic language determination will give a note at start-up on systems in supported languages.
* Our data sets are now also continually exported to Apache Feather and Apache Parquet formats. You can find more info [in this article on our website](https://msberends.github.io/AMR/articles/datasets.html).
* Support for using antibiotic selectors in scoped `dplyr` verbs (with or without `vars()`), such as in: `... %>% summarise_at(aminoglycosides(), resistance)`, see `resistance()`
* Support for antimicrobial interpretation of anaerobic bacteria, by adding a 'placeholder' code `B_ANAER` to the `microorganisms` data set and add the breakpoints of anaerobics to the `rsi_interpretation` data set, which is used by `as.rsi()` when interpreting MIC and disk diffusion values
* New and updated entries for the `antibiotics` data set * New and updated entries for the `antibiotics` data set
* The following 20 antibiotics have been added (also includes the [new J01RA ATC group](https://www.whocc.no/atc_ddd_index/?code=J01RA&showdescription=no)): azithromycin/fluconazole/secnidazole (AFC), cefepime/amikacin (CFA), cefixime/ornidazole (CEO), ceftriaxone/beta-lactamase inhibitor (CEB), ciprofloxacin/metronidazole (CIM), ciprofloxacin/ornidazole (CIO), ciprofloxacin/tinidazole (CIT), furazidin (FUR), isoniazid/sulfamethoxazole/trimethoprim/pyridoxine (IST), lascufloxacin (LSC), levofloxacin/ornidazole (LEO), nemonoxacin (NEM), norfloxacin/metronidazole (NME), norfloxacin/tinidazole (NTI), ofloxacin/ornidazole (OOR), oteseconazole (OTE), rifampicin/ethambutol/isoniazid (REI), sarecycline (SRC), tetracycline/oleandomycin (TOL), and thioacetazone (TAT) * The following 20 antibiotics have been added (also includes the [new J01RA ATC group](https://www.whocc.no/atc_ddd_index/?code=J01RA&showdescription=no)): azithromycin/fluconazole/secnidazole (AFC), cefepime/amikacin (CFA), cefixime/ornidazole (CEO), ceftriaxone/beta-lactamase inhibitor (CEB), ciprofloxacin/metronidazole (CIM), ciprofloxacin/ornidazole (CIO), ciprofloxacin/tinidazole (CIT), furazidin (FUR), isoniazid/sulfamethoxazole/trimethoprim/pyridoxine (IST), lascufloxacin (LSC), levofloxacin/ornidazole (LEO), nemonoxacin (NEM), norfloxacin/metronidazole (NME), norfloxacin/tinidazole (NTI), ofloxacin/ornidazole (OOR), oteseconazole (OTE), rifampicin/ethambutol/isoniazid (REI), sarecycline (SRC), tetracycline/oleandomycin (TOL), and thioacetazone (TAT)
* Added some missing ATC codes * Added some missing ATC codes
* Updated DDDs and PubChem Compound IDs * Updated DDDs and PubChem Compound IDs
* Updated some antibiotic name spelling, now used by WHOCC (such as cephalexin -> cefalexin, and phenethicillin -> pheneticillin) * Updated some antibiotic name spelling, now used by WHOCC (such as cephalexin -> cefalexin, and phenethicillin -> pheneticillin)
* Antibiotic code "CEI" for ceftolozane/tazobactam has been replaced with "CZT" to comply with EARS-Net and WHONET 2022. The old code will still work in all cases when using `as.ab()` or any of the `ab_*()` functions.
* Support for antimicrobial interpretation of anaerobic bacteria, by adding a 'placeholder' code `B_ANAER` to the `microorganisms` data set and add the breakpoints of anaerobics to the `rsi_interpretation` data set, which is used by `as.rsi()` when interpreting MIC and disk diffusion values
* Support for `data.frame`-enhancing R packages, more specifically: `data.table::data.table`, `janitor::tabyl`, `tibble::tibble`, and `tsibble::tsibble`. AMR package functions that have a data set as output (such as `rsi_df()` and `bug_drug_combinations()`), will now return the same data type as the input.
* All data sets in this package are now exported as `tibble`, instead of base R `data.frame`s. Older R versions are still supported.
* Our data sets are now also continually exported to Apache Feather and Apache Parquet formats. You can find more info [in this article on our website](https://msberends.github.io/AMR/articles/datasets.html).
* Support for using antibiotic selectors in scoped `dplyr` verbs (with or without `vars()`), such as in: `... %>% summarise_at(aminoglycosides(), resistance)`, see `resistance()`
### Changed ### Changed
* Fix for using `as.rsi()` on certain EUCAST breakpoints for MIC values * Fix for using `as.rsi()` on certain EUCAST breakpoints for MIC values
* Fix for using `as.rsi()` on `NA` values (e.g. `as.rsi(as.disk(NA), ...)`) * Fix for using `as.rsi()` on `NA` values (e.g. `as.rsi(as.disk(NA), ...)`)
* Fix for using `as.rsi()` on drug-drug combinations with multiple breakpoints for different body sites * Fix for using `as.rsi()` on bug-drug combinations with multiple breakpoints for different body sites
* Removed `as.integer()` for MIC values, since MIC are not integer values and running `table()` on MIC values consequently failed for not being able to retrieve the level position (as that's how normally `as.integer()` on `factor`s work) * Removed `as.integer()` for MIC values, since MIC are not integer values and running `table()` on MIC values consequently failed for not being able to retrieve the level position (as that's how normally `as.integer()` on `factor`s work)
* `droplevels()` on MIC will now return a common `factor` at default and will lose the `mic` class. Use `droplevels(..., as.mic = TRUE)` to keep the `mic` class. * `droplevels()` on MIC will now return a common `factor` at default and will lose the `mic` class. Use `droplevels(..., as.mic = TRUE)` to keep the `mic` class.
* Small fix for using `ab_from_text()` * Small fix for using `ab_from_text()`
@ -48,7 +51,7 @@ This version will eventually become v2.0! We're happy to reach a new major miles
* Using any `random_*()` function (such as `random_mic()`) is now possible by directly calling the package without loading it first: `AMR::random_mic(10)` * Using any `random_*()` function (such as `random_mic()`) is now possible by directly calling the package without loading it first: `AMR::random_mic(10)`
* Added *Toxoplasma gondii* (`P_TXPL_GOND`) to the `microorganisms` data set, together with its genus, family, and order * Added *Toxoplasma gondii* (`P_TXPL_GOND`) to the `microorganisms` data set, together with its genus, family, and order
* Changed value in column `prevalence` of the `microorganisms` data set from 3 to 2 for these genera: *Acholeplasma*, *Alistipes*, *Alloprevotella*, *Bergeyella*, *Borrelia*, *Brachyspira*, *Butyricimonas*, *Cetobacterium*, *Chlamydia*, *Chlamydophila*, *Deinococcus*, *Dysgonomonas*, *Elizabethkingia*, *Empedobacter*, *Haloarcula*, *Halobacterium*, *Halococcus*, *Myroides*, *Odoribacter*, *Ornithobacterium*, *Parabacteroides*, *Pedobacter*, *Phocaeicola*, *Porphyromonas*, *Riemerella*, *Sphingobacterium*, *Streptobacillus*, *Tenacibaculum*, *Terrimonas*, *Victivallis*, *Wautersiella*, *Weeksella* * Changed value in column `prevalence` of the `microorganisms` data set from 3 to 2 for these genera: *Acholeplasma*, *Alistipes*, *Alloprevotella*, *Bergeyella*, *Borrelia*, *Brachyspira*, *Butyricimonas*, *Cetobacterium*, *Chlamydia*, *Chlamydophila*, *Deinococcus*, *Dysgonomonas*, *Elizabethkingia*, *Empedobacter*, *Haloarcula*, *Halobacterium*, *Halococcus*, *Myroides*, *Odoribacter*, *Ornithobacterium*, *Parabacteroides*, *Pedobacter*, *Phocaeicola*, *Porphyromonas*, *Riemerella*, *Sphingobacterium*, *Streptobacillus*, *Tenacibaculum*, *Terrimonas*, *Victivallis*, *Wautersiella*, *Weeksella*
* Fix for using the form `df[carbapenems() == "R", ]` when using the latest `vctrs` package * Extended support for the `vctrs` package, used internally by the tidyverse. This allows to change values of class `mic`, `disk`, `rsi`, `mo` and `ab` in tibbles, and to use antibiotic selectors for selecting/filtering, e.g. `df[carbapenems() == "R", ]`
* Fix for using `info = FALSE` in `mdro()` * Fix for using `info = FALSE` in `mdro()`
* For all interpretation guidelines using `as.rsi()` on amoxicillin, the rules for ampicillin will be used if amoxicillin rules are not available * For all interpretation guidelines using `as.rsi()` on amoxicillin, the rules for ampicillin will be used if amoxicillin rules are not available
* Fix for using `ab_atc()` on non-existing ATC codes * Fix for using `ab_atc()` on non-existing ATC codes

View File

@ -64,7 +64,10 @@ vec_ptype2.ab.character <- function(x, y, ...) {
y y
} }
vec_cast.character.ab <- function(x, to, ...) { vec_cast.character.ab <- function(x, to, ...) {
unclass(x) as.character(x)
}
vec_cast.ab.character <- function(x, to, ...) {
return_after_integrity_check(x, "antimicrobial code", as.character(AMR_env$AB_lookup$ab))
} }
# S3: mo # S3: mo
@ -75,7 +78,10 @@ vec_ptype2.mo.character <- function(x, y, ...) {
y y
} }
vec_cast.character.mo <- function(x, to, ...) { vec_cast.character.mo <- function(x, to, ...) {
unclass(x) as.character(x)
}
vec_cast.mo.character <- function(x, to, ...) {
return_after_integrity_check(x, "microorganism code", as.character(AMR::microorganisms$mo))
} }
# S3: disk # S3: disk
@ -88,15 +94,49 @@ vec_ptype2.disk.integer <- function(x, y, ...) {
vec_cast.integer.disk <- function(x, to, ...) { vec_cast.integer.disk <- function(x, to, ...) {
unclass(x) unclass(x)
} }
vec_cast.disk.integer <- function(x, to, ...) {
as.disk(x)
}
vec_cast.double.disk <- function(x, to, ...) {
unclass(x)
}
vec_cast.disk.double <- function(x, to, ...) {
as.disk(x)
}
vec_cast.character.disk <- function(x, to, ...) {
unclass(x)
}
vec_cast.disk.character <- function(x, to, ...) {
as.disk(x)
}
# S3: mic # S3: mic
vec_cast.character.mic <- function(x, to, ...) { vec_cast.character.mic <- function(x, to, ...) {
as.character(x) as.character(x)
} }
vec_cast.double.mic <- function(x, to, ...) { vec_cast.double.mic <- function(x, to, ...) {
# this calls as.double.mic()
as.double(x) as.double(x)
} }
vec_cast.mic.double <- function(x, to, ...) {
as.mic(x)
}
vec_cast.mic.character <- function(x, to, ...) {
as.mic(x)
}
vec_math.mic <- function(.fn, x, ...) { vec_math.mic <- function(.fn, x, ...) {
.fn(as.double(x), ...) .fn(as.double(x), ...)
} }
# S3: rsi
vec_ptype2.character.rsi <- function(x, y, ...) {
x
}
vec_ptype2.rsi.character <- function(x, y, ...) {
y
}
vec_cast.character.rsi <- function(x, to, ...) {
as.character(x)
}
vec_cast.rsi.character <- function(x, to, ...) {
as.rsi(x)
}

38
R/zzz.R
View File

@ -116,24 +116,44 @@ if (utf8_supported && !is_latex) {
s3_register("ggplot2::fortify", "mic") s3_register("ggplot2::fortify", "mic")
s3_register("ggplot2::fortify", "disk") s3_register("ggplot2::fortify", "disk")
# Support vctrs package for use in e.g. dplyr verbs # Support vctrs package for use in e.g. dplyr verbs
s3_register("vctrs::vec_ptype2", "ab.character") # S3: ab_selector
s3_register("vctrs::vec_ptype2", "character.ab")
s3_register("vctrs::vec_cast", "character.ab")
s3_register("vctrs::vec_ptype2", "mo.character")
s3_register("vctrs::vec_ptype2", "character.mo")
s3_register("vctrs::vec_cast", "character.mo")
s3_register("vctrs::vec_ptype2", "ab_selector.character")
s3_register("vctrs::vec_ptype2", "character.ab_selector") s3_register("vctrs::vec_ptype2", "character.ab_selector")
s3_register("vctrs::vec_ptype2", "ab_selector.character")
s3_register("vctrs::vec_cast", "character.ab_selector") s3_register("vctrs::vec_cast", "character.ab_selector")
s3_register("vctrs::vec_ptype2", "ab_selector_any_all.logical") # S3: ab_selector_any_all
s3_register("vctrs::vec_ptype2", "logical.ab_selector_any_all") s3_register("vctrs::vec_ptype2", "logical.ab_selector_any_all")
s3_register("vctrs::vec_ptype2", "ab_selector_any_all.logical")
s3_register("vctrs::vec_cast", "logical.ab_selector_any_all") s3_register("vctrs::vec_cast", "logical.ab_selector_any_all")
s3_register("vctrs::vec_ptype2", "disk.integer") # S3: ab
s3_register("vctrs::vec_ptype2", "character.ab")
s3_register("vctrs::vec_ptype2", "ab.character")
s3_register("vctrs::vec_cast", "character.ab")
s3_register("vctrs::vec_cast", "ab.character")
# S3: mo
s3_register("vctrs::vec_ptype2", "character.mo")
s3_register("vctrs::vec_ptype2", "mo.character")
s3_register("vctrs::vec_cast", "character.mo")
s3_register("vctrs::vec_cast", "mo.character")
# S3: disk
s3_register("vctrs::vec_ptype2", "integer.disk") s3_register("vctrs::vec_ptype2", "integer.disk")
s3_register("vctrs::vec_ptype2", "disk.integer")
s3_register("vctrs::vec_cast", "integer.disk") s3_register("vctrs::vec_cast", "integer.disk")
s3_register("vctrs::vec_cast", "disk.integer")
s3_register("vctrs::vec_cast", "double.disk")
s3_register("vctrs::vec_cast", "disk.double")
s3_register("vctrs::vec_cast", "character.disk")
s3_register("vctrs::vec_cast", "disk.character")
# S3: mic
s3_register("vctrs::vec_cast", "character.mic") s3_register("vctrs::vec_cast", "character.mic")
s3_register("vctrs::vec_cast", "double.mic") s3_register("vctrs::vec_cast", "double.mic")
s3_register("vctrs::vec_cast", "mic.character")
s3_register("vctrs::vec_cast", "mic.double")
s3_register("vctrs::vec_math", "mic") s3_register("vctrs::vec_math", "mic")
# S3: rsi
s3_register("vctrs::vec_ptype2", "character.rsi")
s3_register("vctrs::vec_ptype2", "rsi.character")
s3_register("vctrs::vec_cast", "character.rsi")
s3_register("vctrs::vec_cast", "rsi.character")
# if mo source exists, fire it up (see mo_source()) # if mo source exists, fire it up (see mo_source())
if (tryCatch(file.exists(getOption("AMR_mo_source", "~/mo_source.rds")), error = function(e) FALSE)) { if (tryCatch(file.exists(getOption("AMR_mo_source", "~/mo_source.rds")), error = function(e) FALSE)) {

Binary file not shown.

53
inst/tinytest/test-vctrs.R Executable file
View File

@ -0,0 +1,53 @@
# ==================================================================== #
# TITLE #
# AMR: An R Package for Working with Antimicrobial Resistance Data #
# #
# SOURCE #
# https://github.com/msberends/AMR #
# #
# CITE AS #
# Berends MS, Luz CF, Friedrich AW, Sinha BNM, Albers CJ, Glasner C #
# (2022). AMR: An R Package for Working with Antimicrobial Resistance #
# Data. Journal of Statistical Software, 104(3), 1-31. #
# doi:10.18637/jss.v104.i03 #
# #
# 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 data analysis: https://msberends.github.io/AMR/ #
# ==================================================================== #
# extra tests for {vctrs} pkg support
if (pkg_is_available("dplyr", also_load = FALSE)) {
test <- dplyr::tibble(ab = as.ab("CIP"),
mo = as.mo("Escherichia coli"),
mic = as.mic(2),
disk = as.disk(20),
rsi = as.rsi("S"))
check1 <- lapply(test, class)
test[1, "ab"] <- "GEN"
test[1, "mo"] <- "B_KLBSL_PNMN"
test[1, "mic"] <- ">=32"
test[1, "mic"] <- 32
test[1, "disk"] <- "35"
test[1, "disk"] <- 25
test[1, "disk"] <- 26L
test[1, "rsi"] <- "R"
check2 <- lapply(test, class)
expect_identical(check1, check2)
test <- dplyr::tibble(cipro = as.rsi("S"),
variable = "test")
expect_equal(nrow(test[quinolones() == "S", ]), 1)
expect_equal(nrow(test[quinolones() == "R", ]), 0)
}