AMR/R/atc_online.R

199 lines
7.1 KiB
R
Raw Normal View History

2019-01-26 23:22:56 +01:00
# ==================================================================== #
# TITLE #
# Antimicrobial Resistance (AMR) Analysis #
# #
# SOURCE #
# https://gitlab.com/msberends/AMR #
# #
# LICENCE #
# (c) 2018-2020 Berends MS, Luz CF et al. #
2019-01-26 23:22:56 +01: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. #
2019-04-05 18:47:39 +02:00
# Visit our website for more info: https://msberends.gitlab.io/AMR. #
2019-01-26 23:22:56 +01:00
# ==================================================================== #
2019-01-27 19:30:40 +01:00
#' Get ATC properties from WHOCC website
2019-01-26 23:22:56 +01:00
#'
#' @inheritSection lifecycle Questioning lifecycle
#' @description Gets data from the WHO to determine properties of an ATC (e.g. an antibiotic) like name, defined daily dose (DDD) or standard unit.
#'
#' **This function requires an internet connection.**
2019-01-26 23:22:56 +01:00
#' @param atc_code a character or character vector with ATC code(s) of antibiotic(s)
#' @param property property of an ATC code. Valid values are `"ATC"`, `"Name"`, `"DDD"`, `"U"` (`"unit"`), `"Adm.R"`, `"Note"` and `groups`. For this last option, all hierarchical groups of an ATC code will be returned, see Examples.
#' @param administration type of administration when using `property = "Adm.R"`, see Details
#' @param url url of website of the WHO. The sign `%s` can be used as a placeholder for ATC codes.
#' @param ... parameters to pass on to `atc_property`
2019-01-26 23:22:56 +01:00
#' @details
#' Options for parameter `administration`:
#'
#' - `"Implant"` = Implant
#' - `"Inhal"` = Inhalation
#' - `"Instill"` = Instillation
#' - `"N"` = nasal
#' - `"O"` = oral
#' - `"P"` = parenteral
#' - `"R"` = rectal
#' - `"SL"` = sublingual/buccal
#' - `"TD"` = transdermal
#' - `"V"` = vaginal
2019-01-26 23:22:56 +01:00
#'
#' Abbreviations of return values when using `property = "U"` (unit):
#'
#' - `"g"` = gram
#' - `"mg"` = milligram
#' - `"mcg"`` = microgram
#' - `"U"` = unit
#' - `"TU"` = thousand units
#' - `"MU"` = million units
#' - `"mmol"` = millimole
#' - `"ml"` = milliliter (e.g. eyedrops)
2019-01-26 23:22:56 +01:00
#' @export
#' @rdname atc_online
#' @importFrom dplyr %>% progress_estimated
2019-02-21 18:55:52 +01:00
#' @inheritSection AMR Read more on our website!
#' @source <https://www.whocc.no/atc_ddd_alterations__cumulative/ddd_alterations/abbrevations/>
2019-01-26 23:22:56 +01:00
#' @examples
#' \donttest{
#' # oral DDD (Defined Daily Dose) of amoxicillin
#' atc_online_property("J01CA04", "DDD", "O")
#' # parenteral DDD (Defined Daily Dose) of amoxicillin
#' atc_online_property("J01CA04", "DDD", "P")
#'
#' atc_online_property("J01CA04", property = "groups") # search hierarchical groups of amoxicillin
#' # [1] "ANTIINFECTIVES FOR SYSTEMIC USE"
#' # [2] "ANTIBACTERIALS FOR SYSTEMIC USE"
#' # [3] "BETA-LACTAM ANTIBACTERIALS, PENICILLINS"
#' # [4] "Penicillins with extended spectrum"
#' }
atc_online_property <- function(atc_code,
property,
2019-10-11 17:21:02 +02:00
administration = "O",
url = "https://www.whocc.no/atc_ddd_index/?code=%s&showdescription=no") {
2019-01-26 23:22:56 +01:00
2019-10-06 21:07:38 +02:00
if (!all(c("curl", "rvest", "xml2") %in% rownames(utils::installed.packages()))) {
2019-01-27 19:30:40 +01:00
stop("Packages 'xml2', 'rvest' and 'curl' are required for this function")
}
2019-02-01 16:55:55 +01:00
if (!all(atc_code %in% AMR::antibiotics)) {
atc_code <- as.character(ab_atc(atc_code))
2019-01-26 23:22:56 +01:00
}
2019-02-01 16:55:55 +01:00
if (!curl::has_internet()) {
message("There appears to be no internet connection.")
2019-01-26 23:22:56 +01:00
return(rep(NA, length(atc_code)))
}
if (length(property) != 1L) {
2019-10-11 17:21:02 +02:00
stop("`property` must be of length 1", call. = FALSE)
2019-01-26 23:22:56 +01:00
}
if (length(administration) != 1L) {
2019-10-11 17:21:02 +02:00
stop("`administration` must be of length 1", call. = FALSE)
2019-01-26 23:22:56 +01:00
}
# also allow unit as property
2019-10-11 17:21:02 +02:00
if (property %like% "unit") {
property <- "U"
2019-01-26 23:22:56 +01:00
}
# validation of properties
valid_properties <- c("ATC", "Name", "DDD", "U", "Adm.R", "Note", "groups")
valid_properties.bak <- valid_properties
property <- tolower(property)
valid_properties <- tolower(valid_properties)
if (!property %in% valid_properties) {
2019-10-11 17:21:02 +02:00
stop("Invalid `property`, use one of ", paste(valid_properties.bak, collapse = ", "), ".")
2019-01-26 23:22:56 +01:00
}
2019-10-11 17:21:02 +02:00
if (property == "ddd") {
2019-01-26 23:22:56 +01:00
returnvalue <- rep(NA_real_, length(atc_code))
2019-10-11 17:21:02 +02:00
} else if (property == "groups") {
2019-01-26 23:22:56 +01:00
returnvalue <- list()
} else {
returnvalue <- rep(NA_character_, length(atc_code))
}
progress <- progress_estimated(n = length(atc_code))
2019-10-11 17:21:02 +02:00
for (i in seq_len(length(atc_code))) {
2019-01-26 23:22:56 +01:00
progress$tick()$print()
2019-10-11 17:21:02 +02:00
atc_url <- sub("%s", atc_code[i], url, fixed = TRUE)
2019-01-26 23:22:56 +01:00
if (property == "groups") {
tbl <- xml2::read_html(atc_url) %>%
rvest::html_node("#content") %>%
rvest::html_children() %>%
rvest::html_node("a")
# get URLS of items
hrefs <- tbl %>% rvest::html_attr("href")
# get text of items
texts <- tbl %>% rvest::html_text()
# select only text items where URL like "code="
texts <- texts[grepl("?code=", tolower(hrefs), fixed = TRUE)]
# last one is antibiotics, skip it
2019-10-11 17:21:02 +02:00
texts <- texts[seq_len(length(texts)) - 1]
2019-01-26 23:22:56 +01:00
returnvalue <- c(list(texts), returnvalue)
} else {
tbl <- xml2::read_html(atc_url) %>%
2019-10-11 17:21:02 +02:00
rvest::html_nodes("table") %>%
2019-01-26 23:22:56 +01:00
rvest::html_table(header = TRUE) %>%
as.data.frame(stringsAsFactors = FALSE)
# case insensitive column names
2019-10-11 17:21:02 +02:00
colnames(tbl) <- tolower(colnames(tbl)) %>% gsub("^atc.*", "atc", .)
2019-01-26 23:22:56 +01:00
if (length(tbl) == 0) {
2019-10-11 17:21:02 +02:00
warning("ATC not found: ", atc_code[i], ". Please check ", atc_url, ".", call. = FALSE)
2019-01-26 23:22:56 +01:00
returnvalue[i] <- NA
next
}
2019-10-11 17:21:02 +02:00
if (property %in% c("atc", "name")) {
2019-01-26 23:22:56 +01:00
# ATC and name are only in first row
returnvalue[i] <- tbl[1, property]
} else {
2019-10-11 17:21:02 +02:00
if (!"adm.r" %in% colnames(tbl) | is.na(tbl[1, "adm.r"])) {
2019-01-26 23:22:56 +01:00
returnvalue[i] <- NA
next
} else {
2019-10-15 14:35:23 +02:00
for (j in seq_len(nrow(tbl))) {
2019-10-11 17:21:02 +02:00
if (tbl[j, "adm.r"] == administration) {
2019-01-26 23:22:56 +01:00
returnvalue[i] <- tbl[j, property]
}
}
}
}
}
}
if (property == "groups" & length(returnvalue) == 1) {
returnvalue <- returnvalue[[1]]
}
returnvalue
}
#' @rdname atc_online
#' @export
atc_online_groups <- function(atc_code, ...) {
atc_online_property(atc_code = atc_code, property = "groups", ...)
}
#' @rdname atc_online
#' @export
atc_online_ddd <- function(atc_code, ...) {
atc_online_property(atc_code = atc_code, property = "ddd", ...)
}