2019-05-10 16:44:59 +02:00
# ==================================================================== #
# TITLE #
2021-02-02 23:57:35 +01:00
# Antimicrobial Resistance (AMR) Data Analysis for R #
2019-05-10 16:44:59 +02:00
# #
# SOURCE #
2020-07-08 14:48:06 +02:00
# https://github.com/msberends/AMR #
2019-05-10 16:44:59 +02:00
# #
# LICENCE #
2020-12-27 00:30:28 +01:00
# (c) 2018-2021 Berends MS, Luz CF et al. #
2020-10-08 11:16:03 +02:00
# Developed at the University of Groningen, the Netherlands, in #
# collaboration with non-profit organisations Certe Medical #
# Diagnostics & Advice, and University Medical Center Groningen. #
2019-05-10 16:44:59 +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. #
2020-01-05 17:22:09 +01:00
# 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. #
2020-10-08 11:16:03 +02:00
# #
# Visit our website for the full manual and a complete tutorial about #
2021-02-02 23:57:35 +01:00
# how to conduct AMR data analysis: https://msberends.github.io/AMR/ #
2019-05-10 16:44:59 +02:00
# ==================================================================== #
2021-01-18 16:57:56 +01:00
#' Get Properties of an Antibiotic
2019-05-10 16:44:59 +02:00
#'
2019-11-28 22:32:17 +01:00
#' Use these functions to return a specific property of an antibiotic from the [antibiotics] data set. All input values will be evaluated internally with [as.ab()].
2021-01-18 16:57:56 +01:00
#' @inheritSection lifecycle Stable Lifecycle
2020-07-30 15:15:52 +02:00
#' @param x any (vector of) text that can be coerced to a valid antibiotic code with [as.ab()]
2021-05-12 18:15:03 +02:00
#' @param tolower a [logical] to indicate whether the first [character] of every output should be transformed to a lower case [character]. This will lead to e.g. "polymyxin B" and not "polymyxin b".
2021-07-04 22:10:46 +02:00
#' @param snake_case a [logical] to indicate whether the names should be returned in so-called [snake case](https://en.wikipedia.org/wiki/Snake_case): in lower case and all spaces/slashes replaced with an underscore (`_`). This is useful for column renaming.
2019-11-28 22:32:17 +01:00
#' @param property one of the column names of one of the [antibiotics] data set
#' @param language language of the returned text, defaults to system language (see [get_locale()]) and can also be set with `getOption("AMR_locale")`. Use `language = NULL` or `language = ""` to prevent translation.
#' @param administration way of administration, either `"oral"` or `"iv"`
2021-05-12 18:15:03 +02:00
#' @param units a [logical] to indicate whether the units instead of the DDDs itself must be returned, see *Examples*
2020-05-22 20:29:55 +02:00
#' @param open browse the URL using [utils::browseURL()]
2020-12-22 00:51:17 +01:00
#' @param ... other arguments passed on to [as.ab()]
2021-02-08 14:18:42 +01:00
#' @details All output [will be translated][translate] where possible.
2020-05-22 20:15:19 +02:00
#'
2020-05-25 01:01:14 +02:00
#' The function [ab_url()] will return the direct URL to the official WHO website. A warning will be returned if the required ATC code is not available.
2019-05-10 16:44:59 +02:00
#' @inheritSection as.ab Source
#' @rdname ab_property
#' @name ab_property
2019-11-28 22:32:17 +01:00
#' @return
2020-09-18 16:05:53 +02:00
#' - An [integer] in case of [ab_cid()]
#' - A named [list] in case of [ab_info()] and multiple [ab_synonyms()]/[ab_tradenames()]
#' - A [double] in case of [ab_ddd()]
#' - A [character] in all other cases
2019-05-10 16:44:59 +02:00
#' @export
2019-11-28 22:32:17 +01:00
#' @seealso [antibiotics]
2021-01-18 16:57:56 +01:00
#' @inheritSection AMR Reference Data Publicly Available
#' @inheritSection AMR Read more on Our Website!
2019-05-10 16:44:59 +02:00
#' @examples
#' # all properties:
#' ab_name("AMX") # "Amoxicillin"
#' ab_atc("AMX") # J01CA04 (ATC code from the WHO)
#' ab_cid("AMX") # 33613 (Compound ID from PubChem)
#' ab_synonyms("AMX") # a list with brand names of amoxicillin
#' ab_tradenames("AMX") # same
#' ab_group("AMX") # "Beta-lactams/penicillins"
#' ab_atc_group1("AMX") # "Beta-lactam antibacterials, penicillins"
#' ab_atc_group2("AMX") # "Penicillins with extended spectrum"
2020-05-22 20:15:19 +02:00
#' ab_url("AMX") # link to the official WHO page
2019-05-10 16:44:59 +02:00
#'
2020-01-26 20:20:00 +01:00
#' # smart lowercase tranformation
2019-05-10 16:44:59 +02:00
#' ab_name(x = c("AMC", "PLB")) # "Amoxicillin/clavulanic acid" "Polymyxin B"
#' ab_name(x = c("AMC", "PLB"),
#' tolower = TRUE) # "amoxicillin/clavulanic acid" "polymyxin B"
#'
2020-01-26 20:20:00 +01:00
#' # defined daily doses (DDD)
2019-05-10 16:44:59 +02:00
#' ab_ddd("AMX", "oral") # 1
#' ab_ddd("AMX", "oral", units = TRUE) # "g"
#' ab_ddd("AMX", "iv") # 1
#' ab_ddd("AMX", "iv", units = TRUE) # "g"
#'
2019-05-16 21:20:00 +02:00
#' ab_info("AMX") # all properties as a list
#'
2020-01-26 20:20:00 +01:00
#' # all ab_* functions use as.ab() internally, so you can go from 'any' to 'any':
#' ab_atc("AMP") # ATC code of AMP (ampicillin)
#' ab_group("J01CA01") # Drug group of ampicillins ATC code
#' ab_loinc("ampicillin") # LOINC codes of ampicillin
#' ab_name("21066-6") # "Ampicillin" (using LOINC)
#' ab_name(6249) # "Ampicillin" (using CID)
#' ab_name("J01CA01") # "Ampicillin" (using ATC)
2020-01-08 11:30:33 +01:00
#'
#' # spelling from different languages and dyslexia are no problem
#' ab_atc("ceftriaxon")
#' ab_atc("cephtriaxone")
#' ab_atc("cephthriaxone")
#' ab_atc("seephthriaaksone")
2021-07-04 22:10:46 +02:00
ab_name <- function ( x , language = get_locale ( ) , tolower = FALSE , snake_case = FALSE , ... ) {
2020-10-20 21:00:57 +02:00
meet_criteria ( x , allow_NA = TRUE )
2020-10-19 17:09:19 +02:00
meet_criteria ( language , has_length = 1 , is_in = c ( LANGUAGES_SUPPORTED , " " ) , allow_NULL = TRUE , allow_NA = TRUE )
meet_criteria ( tolower , allow_class = " logical" , has_length = 1 )
2021-07-04 22:10:46 +02:00
meet_criteria ( snake_case , allow_class = " logical" , has_length = 1 )
2020-10-19 17:09:19 +02:00
2021-05-17 11:26:12 +02:00
x <- translate_AMR ( ab_validate ( x = x , property = " name" , ... ) , language = language , only_affect_ab_names = TRUE )
2019-05-10 16:44:59 +02:00
if ( tolower == TRUE ) {
# use perl to only transform the first character
# as we want "polymyxin B", not "polymyxin b"
2019-06-11 14:18:25 +02:00
x <- gsub ( " ^([A-Z])" , " \\L\\1" , x , perl = TRUE )
2019-05-10 16:44:59 +02:00
}
2021-07-04 22:10:46 +02:00
if ( snake_case == TRUE ) {
x <- tolower ( gsub ( " [^a-zA-Z0-9]+" , " _" , x ) )
}
2019-06-11 14:18:25 +02:00
x
2019-05-10 16:44:59 +02:00
}
#' @rdname ab_property
2019-11-06 14:43:23 +01:00
#' @aliases ATC
2019-05-10 16:44:59 +02:00
#' @export
ab_atc <- function ( x , ... ) {
2020-10-20 21:00:57 +02:00
meet_criteria ( x , allow_NA = TRUE )
2019-05-10 16:44:59 +02:00
ab_validate ( x = x , property = " atc" , ... )
}
#' @rdname ab_property
#' @export
ab_cid <- function ( x , ... ) {
2020-10-20 21:00:57 +02:00
meet_criteria ( x , allow_NA = TRUE )
2019-05-10 16:44:59 +02:00
ab_validate ( x = x , property = " cid" , ... )
}
#' @rdname ab_property
#' @export
ab_synonyms <- function ( x , ... ) {
2020-10-20 21:00:57 +02:00
meet_criteria ( x , allow_NA = TRUE )
2019-05-10 16:44:59 +02:00
syns <- ab_validate ( x = x , property = " synonyms" , ... )
names ( syns ) <- x
if ( length ( syns ) == 1 ) {
unname ( unlist ( syns ) )
} else {
syns
}
}
#' @rdname ab_property
#' @export
ab_tradenames <- function ( x , ... ) {
2020-10-20 21:00:57 +02:00
meet_criteria ( x , allow_NA = TRUE )
2019-05-10 16:44:59 +02:00
ab_synonyms ( x , ... )
}
#' @rdname ab_property
#' @export
2019-05-16 21:20:00 +02:00
ab_group <- function ( x , language = get_locale ( ) , ... ) {
2020-10-20 21:00:57 +02:00
meet_criteria ( x , allow_NA = TRUE )
2020-10-19 17:09:19 +02:00
meet_criteria ( language , has_length = 1 , is_in = c ( LANGUAGES_SUPPORTED , " " ) , allow_NULL = TRUE , allow_NA = TRUE )
2021-05-17 11:26:12 +02:00
translate_AMR ( ab_validate ( x = x , property = " group" , ... ) , language = language , only_affect_ab_names = TRUE )
2019-05-10 16:44:59 +02:00
}
#' @rdname ab_property
#' @export
2019-05-16 21:20:00 +02:00
ab_atc_group1 <- function ( x , language = get_locale ( ) , ... ) {
2020-10-20 21:00:57 +02:00
meet_criteria ( x , allow_NA = TRUE )
2020-10-19 17:09:19 +02:00
meet_criteria ( language , has_length = 1 , is_in = c ( LANGUAGES_SUPPORTED , " " ) , allow_NULL = TRUE , allow_NA = TRUE )
2021-05-17 11:26:12 +02:00
translate_AMR ( ab_validate ( x = x , property = " atc_group1" , ... ) , language = language , only_affect_ab_names = TRUE )
2019-05-10 16:44:59 +02:00
}
#' @rdname ab_property
#' @export
2019-05-16 21:20:00 +02:00
ab_atc_group2 <- function ( x , language = get_locale ( ) , ... ) {
2020-10-20 21:00:57 +02:00
meet_criteria ( x , allow_NA = TRUE )
2020-10-19 17:09:19 +02:00
meet_criteria ( language , has_length = 1 , is_in = c ( LANGUAGES_SUPPORTED , " " ) , allow_NULL = TRUE , allow_NA = TRUE )
2021-05-17 11:26:12 +02:00
translate_AMR ( ab_validate ( x = x , property = " atc_group2" , ... ) , language = language , only_affect_ab_names = TRUE )
2019-05-10 16:44:59 +02:00
}
2020-01-26 20:20:00 +01:00
#' @rdname ab_property
#' @export
ab_loinc <- function ( x , ... ) {
2020-10-20 21:00:57 +02:00
meet_criteria ( x , allow_NA = TRUE )
2020-01-26 20:20:00 +01:00
loincs <- ab_validate ( x = x , property = " loinc" , ... )
names ( loincs ) <- x
if ( length ( loincs ) == 1 ) {
unname ( unlist ( loincs ) )
} else {
loincs
}
}
2019-05-10 16:44:59 +02:00
#' @rdname ab_property
#' @export
ab_ddd <- function ( x , administration = " oral" , units = FALSE , ... ) {
2020-10-20 21:00:57 +02:00
meet_criteria ( x , allow_NA = TRUE )
2020-10-19 17:09:19 +02:00
meet_criteria ( administration , is_in = c ( " oral" , " iv" ) , has_length = 1 )
meet_criteria ( units , allow_class = " logical" , has_length = 1 )
2019-05-10 16:44:59 +02:00
ddd_prop <- administration
if ( units == TRUE ) {
ddd_prop <- paste0 ( ddd_prop , " _units" )
} else {
ddd_prop <- paste0 ( ddd_prop , " _ddd" )
}
ab_validate ( x = x , property = ddd_prop , ... )
}
2019-05-16 22:07:31 +02:00
#' @rdname ab_property
#' @export
2019-05-16 21:20:00 +02:00
ab_info <- function ( x , language = get_locale ( ) , ... ) {
2020-10-20 21:00:57 +02:00
meet_criteria ( x , allow_NA = TRUE )
2020-10-19 17:09:19 +02:00
meet_criteria ( language , has_length = 1 , is_in = c ( LANGUAGES_SUPPORTED , " " ) , allow_NULL = TRUE , allow_NA = TRUE )
2020-02-14 19:54:13 +01:00
x <- as.ab ( x , ... )
2020-09-03 12:31:48 +02:00
list ( ab = as.character ( x ) ,
2019-06-27 11:57:45 +02:00
atc = ab_atc ( x ) ,
2019-05-16 21:20:00 +02:00
cid = ab_cid ( x ) ,
name = ab_name ( x , language = language ) ,
group = ab_group ( x , language = language ) ,
atc_group1 = ab_atc_group1 ( x , language = language ) ,
atc_group2 = ab_atc_group2 ( x , language = language ) ,
tradenames = ab_tradenames ( x ) ,
ddd = list ( oral = list ( amount = ab_ddd ( x , administration = " oral" , units = FALSE ) ,
units = ab_ddd ( x , administration = " oral" , units = TRUE ) ) ,
iv = list ( amount = ab_ddd ( x , administration = " iv" , units = FALSE ) ,
units = ab_ddd ( x , administration = " iv" , units = TRUE ) ) ) )
}
2020-05-22 20:15:19 +02:00
#' @rdname ab_property
#' @export
ab_url <- function ( x , open = FALSE , ... ) {
2020-10-20 21:00:57 +02:00
meet_criteria ( x , allow_NA = TRUE )
2020-10-19 17:09:19 +02:00
meet_criteria ( open , allow_class = " logical" , has_length = 1 )
2020-05-22 20:15:19 +02:00
ab <- as.ab ( x = x , ... = ... )
u <- paste0 ( " https://www.whocc.no/atc_ddd_index/?code=" , ab_atc ( ab ) , " &showdescription=no" )
u [is.na ( ab_atc ( ab ) ) ] <- NA_character_
names ( u ) <- ab_name ( ab )
NAs <- ab_name ( ab , tolower = TRUE , language = NULL ) [ ! is.na ( ab ) & is.na ( ab_atc ( ab ) ) ]
if ( length ( NAs ) > 0 ) {
2021-02-04 16:48:16 +01:00
warning_ ( " No ATC code available for " , vector_and ( NAs , quotes = FALSE ) , " ." )
2020-05-22 20:15:19 +02:00
}
if ( open == TRUE ) {
if ( length ( u ) > 1 & ! is.na ( u [1L ] ) ) {
2020-11-10 16:35:56 +01:00
warning_ ( " Only the first URL will be opened, as `browseURL()` only suports one string." )
2020-05-22 20:15:19 +02:00
}
if ( ! is.na ( u [1L ] ) ) {
utils :: browseURL ( u [1L ] )
}
}
u
}
2019-05-10 16:44:59 +02:00
#' @rdname ab_property
#' @export
2019-10-11 17:21:02 +02:00
ab_property <- function ( x , property = " name" , language = get_locale ( ) , ... ) {
2020-10-20 21:00:57 +02:00
meet_criteria ( x , allow_NA = TRUE )
2020-10-19 17:09:19 +02:00
meet_criteria ( property , is_in = colnames ( antibiotics ) , has_length = 1 )
meet_criteria ( language , is_in = c ( LANGUAGES_SUPPORTED , " " ) , has_length = 1 , allow_NULL = TRUE , allow_NA = TRUE )
2019-06-11 14:18:25 +02:00
translate_AMR ( ab_validate ( x = x , property = property , ... ) , language = language )
2019-05-10 16:44:59 +02:00
}
ab_validate <- function ( x , property , ... ) {
2020-02-14 19:54:13 +01:00
check_dataset_integrity ( )
2020-12-22 00:51:17 +01:00
# try to catch an error when inputting an invalid argument
2019-05-10 16:44:59 +02:00
# so the 'call.' can be set to FALSE
2020-02-14 19:54:13 +01:00
tryCatch ( x [1L ] %in% antibiotics [1 , property ] ,
2019-05-10 16:44:59 +02:00
error = function ( e ) stop ( e $ message , call. = FALSE ) )
2019-10-08 22:21:33 +02:00
x_bak <- x
2020-02-14 19:54:13 +01:00
if ( ! all ( x %in% antibiotics [ , property ] ) ) {
2020-09-18 16:05:53 +02:00
x <- data.frame ( ab = as.ab ( x , ... ) , stringsAsFactors = FALSE ) %pm>%
pm_left_join ( antibiotics , by = " ab" ) %pm>%
2020-12-12 23:17:29 +01:00
pm_pull ( property )
2019-05-10 16:44:59 +02:00
}
2019-06-27 11:57:45 +02:00
if ( property == " ab" ) {
2020-11-16 16:57:55 +01:00
return ( set_clean_class ( x , new_class = c ( " ab" , " character" ) ) )
2019-05-10 16:44:59 +02:00
} else if ( property == " cid" ) {
return ( as.integer ( x ) )
} else if ( property %like% " ddd" ) {
return ( as.double ( x ) )
} else {
2020-05-22 20:15:19 +02:00
x [is.na ( x ) & ! is.na ( x_bak ) ] <- NA
2019-05-10 16:44:59 +02:00
return ( x )
}
}