AMR/R/custom_antimicrobials.R

173 lines
7.9 KiB
R
Raw Normal View History

2022-10-10 20:20:39 +02:00
# ==================================================================== #
# TITLE: #
2022-10-10 20:20:39 +02:00
# AMR: An R Package for Working with Antimicrobial Resistance Data #
# #
# SOURCE CODE: #
2022-10-10 20:20:39 +02:00
# https://github.com/msberends/AMR #
# #
# PLEASE CITE THIS SOFTWARE AS: #
# Berends MS, Luz CF, Friedrich AW, et al. (2022). #
# AMR: An R Package for Working with Antimicrobial Resistance Data. #
# Journal of Statistical Software, 104(3), 1-31. #
2023-05-27 10:39:22 +02:00
# https://doi.org/10.18637/jss.v104.i03 #
2022-10-10 20:20:39 +02:00
# #
2022-12-27 15:16:15 +01:00
# Developed at the University of Groningen and the University Medical #
# Center Groningen in The Netherlands, in collaboration with many #
# colleagues from around the world, see our website. #
2022-10-10 20:20:39 +02:00
# #
# 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/ #
# ==================================================================== #
2023-01-14 19:50:25 +01:00
#' Add Custom Antimicrobials
2022-10-30 14:31:45 +01:00
#'
2023-01-14 19:50:25 +01:00
#' With [add_custom_antimicrobials()] you can add your own custom antimicrobial drug names and codes.
2022-10-10 20:20:39 +02:00
#' @param x a [data.frame] resembling the [antibiotics] data set, at least containing columns "ab" and "name"
2023-01-23 15:01:21 +01:00
#' @details **Important:** Due to how \R works, the [add_custom_antimicrobials()] function has to be run in every \R session - added antimicrobials are not stored between sessions and are thus lost when \R is exited.
#'
2023-03-12 13:02:37 +01:00
#' There are two ways to circumvent this and automate the process of adding antimicrobials:
2023-01-23 15:01:21 +01:00
#'
#' **Method 1:** Using the [package option][AMR-options] [`AMR_custom_ab`][AMR-options], which is the preferred method. To use this method:
2023-01-23 15:01:21 +01:00
#'
2022-12-27 15:16:15 +01:00
#' 1. Create a data set in the structure of the [antibiotics] data set (containing at the very least columns "ab" and "name") and save it with [saveRDS()] to a location of choice, e.g. `"~/my_custom_ab.rds"`, or any remote location.
2023-01-23 15:01:21 +01:00
#'
#' 2. Set the file location to the [package option][AMR-options] [`AMR_custom_ab`][AMR-options]: `options(AMR_custom_ab = "~/my_custom_ab.rds")`. This can even be a remote file location, such as an https URL. Since options are not saved between \R sessions, it is best to save this option to the `.Rprofile` file so that it will be loaded on start-up of \R. To do this, open the `.Rprofile` file using e.g. `utils::file.edit("~/.Rprofile")`, add this text and save the file:
2022-10-30 14:31:45 +01:00
#'
2022-12-27 15:16:15 +01:00
#' ```r
2023-01-23 20:07:57 +01:00
#' # Add custom antimicrobial codes:
2022-12-27 15:16:15 +01:00
#' options(AMR_custom_ab = "~/my_custom_ab.rds")
#' ```
2023-01-23 15:01:21 +01:00
#'
2022-12-27 15:16:15 +01:00
#' Upon package load, this file will be loaded and run through the [add_custom_antimicrobials()] function.
2023-01-23 15:01:21 +01:00
#'
2023-03-12 13:02:37 +01:00
#' **Method 2:** Loading the antimicrobial additions directly from your `.Rprofile` file. Note that the definitions will be stored in a user-specific \R file, which is a suboptimal workflow. To use this method:
2023-01-23 15:01:21 +01:00
#'
2022-12-27 15:16:15 +01:00
#' 1. Edit the `.Rprofile` file using e.g. `utils::file.edit("~/.Rprofile")`.
2022-10-10 21:03:39 +02:00
#'
2022-12-27 15:16:15 +01:00
#' 2. Add a text like below and save the file:
#'
#' ```r
#' # Add custom antibiotic drug codes:
2023-01-23 20:07:57 +01:00
#' AMR::add_custom_antimicrobials(
2022-12-27 15:16:15 +01:00
#' data.frame(ab = "TESTAB",
#' name = "Test Antibiotic",
#' group = "Test Group")
#' )
#' ```
2022-10-30 14:31:45 +01:00
#'
2022-10-10 20:20:39 +02:00
#' Use [clear_custom_antimicrobials()] to clear the previously added antimicrobials.
2023-01-14 19:50:25 +01:00
#' @seealso [add_custom_microorganisms()] to add custom microorganisms.
2022-10-10 20:20:39 +02:00
#' @rdname add_custom_antimicrobials
#' @export
2022-10-30 14:31:45 +01:00
#' @examples
2022-10-15 15:20:13 +02:00
#' \donttest{
#'
2023-01-14 19:50:25 +01:00
#' # returns NA and throws a warning (which is suppressed here):
2022-10-10 21:03:39 +02:00
#' suppressWarnings(
2022-10-30 21:05:46 +01:00
#' as.ab("testab")
2022-10-10 21:03:39 +02:00
#' )
2022-10-30 14:31:45 +01:00
#'
2022-10-10 21:38:39 +02:00
#' # now add a custom entry - it will be considered by as.ab() and
2022-10-10 20:20:39 +02:00
#' # all ab_*() functions
#' add_custom_antimicrobials(
2022-10-30 14:31:45 +01:00
#' data.frame(
2022-10-30 21:05:46 +01:00
#' ab = "TESTAB",
2022-10-30 14:31:45 +01:00
#' name = "Test Antibiotic",
#' # you can add any property present in the
#' # 'antibiotics' data set, such as 'group':
#' group = "Test Group"
#' )
2022-10-10 20:20:39 +02:00
#' )
2022-10-30 14:31:45 +01:00
#'
2022-10-30 21:05:46 +01:00
#' # "testab" is now a new antibiotic:
#' as.ab("testab")
#' ab_name("testab")
#' ab_group("testab")
2022-10-30 14:31:45 +01:00
#'
2022-10-30 21:05:46 +01:00
#' ab_info("testab")
2022-10-30 14:31:45 +01:00
#'
#'
#' # Add Co-fluampicil, which is one of the many J01CR50 codes, see
2024-03-03 23:24:57 +01:00
#' # https://atcddd.fhi.no/ddd/list_of_ddds_combined_products/
#' add_custom_antimicrobials(
2022-10-30 14:31:45 +01:00
#' data.frame(
#' ab = "COFLU",
#' name = "Co-fluampicil",
#' atc = "J01CR50",
2022-12-27 15:16:15 +01:00
#' group = "Beta-lactams/penicillins"
2022-10-30 14:31:45 +01:00
#' )
#' )
#' ab_atc("Co-fluampicil")
#' ab_name("J01CR50")
2022-10-30 14:31:45 +01:00
#'
#' # even antibiotic selectors work
2022-10-30 14:31:45 +01:00
#' x <- data.frame(
2022-10-30 21:05:46 +01:00
#' random_column = "some value",
2023-01-21 23:47:20 +01:00
#' coflu = as.sir("S"),
#' ampicillin = as.sir("R")
2022-10-30 14:31:45 +01:00
#' )
#' x
#' x[, betalactams()]
2022-10-15 15:20:13 +02:00
#' }
2022-10-10 20:20:39 +02:00
add_custom_antimicrobials <- function(x) {
meet_criteria(x, allow_class = "data.frame")
2022-10-30 14:31:45 +01:00
stop_ifnot(
all(c("ab", "name") %in% colnames(x)),
"`x` must contain columns \"ab\" and \"name\"."
)
stop_if(
any(x$ab %in% AMR_env$AB_lookup$ab),
2022-11-13 13:44:25 +01:00
"Antimicrobial drug code(s) ", vector_and(x$ab[x$ab %in% AMR_env$AB_lookup$ab]), " already exist in the internal `antibiotics` data set."
2022-10-30 14:31:45 +01:00
)
2022-12-27 15:16:15 +01:00
# remove any extra class/type, such as grouped tbl, or data.table:
x <- as.data.frame(x, stringsAsFactors = FALSE)
# keep only columns available in the antibiotics data set
2022-10-14 13:02:50 +02:00
x <- x[, colnames(AMR_env$AB_lookup)[colnames(AMR_env$AB_lookup) %in% colnames(x)], drop = FALSE]
2022-10-10 20:20:39 +02:00
x$generalised_name <- generalise_antibiotic_name(x$name)
x$generalised_all <- as.list(x$generalised_name)
2022-12-27 15:16:15 +01:00
for (col in colnames(x)) {
2022-12-30 12:57:27 +01:00
if (is.list(AMR_env$AB_lookup[, col, drop = TRUE]) & !is.list(x[, col, drop = TRUE])) {
2022-12-27 15:16:15 +01:00
x[, col] <- as.list(x[, col, drop = TRUE])
}
}
2023-01-23 15:01:21 +01:00
AMR_env$custom_ab_codes <- c(AMR_env$custom_ab_codes, x$ab)
2022-10-15 15:20:13 +02:00
class(AMR_env$AB_lookup$ab) <- "character"
2023-01-23 15:01:21 +01:00
2022-10-22 10:20:09 +02:00
new_df <- AMR_env$AB_lookup[0, , drop = FALSE][seq_len(NROW(x)), , drop = FALSE]
rownames(new_df) <- NULL
list_cols <- vapply(FUN.VALUE = logical(1), new_df, is.list)
for (l in which(list_cols)) {
# prevent binding NULLs in lists, replace with NA
new_df[, l] <- as.list(NA_character_)
}
for (col in colnames(x)) {
# assign new values
new_df[, col] <- x[, col, drop = TRUE]
2022-10-15 15:20:13 +02:00
}
2023-03-12 13:02:37 +01:00
AMR_env$AB_lookup <- unique(rbind_AMR(AMR_env$AB_lookup, new_df))
2023-01-23 15:01:21 +01:00
2022-12-30 12:57:27 +01:00
AMR_env$ab_previously_coerced <- AMR_env$ab_previously_coerced[which(!AMR_env$ab_previously_coerced$ab %in% x$ab), , drop = FALSE]
2022-10-15 15:20:13 +02:00
class(AMR_env$AB_lookup$ab) <- c("ab", "character")
message_("Added ", nr2char(nrow(x)), " record", ifelse(nrow(x) > 1, "s", ""), " to the internal `antibiotics` data set.")
2022-10-10 20:20:39 +02:00
}
#' @rdname add_custom_antimicrobials
#' @export
clear_custom_antimicrobials <- function() {
2022-12-27 15:16:15 +01:00
n <- nrow(AMR_env$AB_lookup)
2023-01-21 23:47:20 +01:00
AMR_env$AB_lookup <- cbind(AMR::antibiotics, AB_LOOKUP)
2022-12-27 15:16:15 +01:00
n2 <- nrow(AMR_env$AB_lookup)
AMR_env$custom_ab_codes <- character(0)
2022-12-30 12:57:27 +01:00
AMR_env$ab_previously_coerced <- AMR_env$ab_previously_coerced[which(AMR_env$ab_previously_coerced$ab %in% AMR_env$AB_lookup$ab), , drop = FALSE]
2022-12-27 15:16:15 +01:00
message_("Cleared ", nr2char(n - n2), " custom record", ifelse(n - n2 > 1, "s", ""), " from the internal `antibiotics` data set.")
2022-10-10 20:20:39 +02:00
}