AMR/R/atc_online.R

198 lines
7.4 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) 2019 Berends MS (m.s.berends@umcg.nl), Luz CF (c.f.luz@umcg.nl) #
# #
# 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. #
# #
# This R package was created for academic research and 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
#'
#' Gets data from the WHO to determine properties of an ATC (e.g. an antibiotic) like name, defined daily dose (DDD) or standard unit. \cr \strong{This function requires an internet connection.}
#' @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 \code{"ATC"}, \code{"Name"}, \code{"DDD"}, \code{"U"} (\code{"unit"}), \code{"Adm.R"}, \code{"Note"} and \code{groups}. For this last option, all hierarchical groups of an ATC code will be returned, see Examples.
#' @param administration type of administration when using \code{property = "Adm.R"}, see Details
#' @param url url of website of the WHO. The sign \code{\%s} can be used as a placeholder for ATC codes.
#' @param ... parameters to pass on to \code{atc_property}
#' @details
#' Options for parameter \code{administration}:
#' \itemize{
#' \item{\code{"Implant"}}{ = Implant}
#' \item{\code{"Inhal"}}{ = Inhalation}
#' \item{\code{"Instill"}}{ = Instillation}
#' \item{\code{"N"}}{ = nasal}
#' \item{\code{"O"}}{ = oral}
#' \item{\code{"P"}}{ = parenteral}
#' \item{\code{"R"}}{ = rectal}
#' \item{\code{"SL"}}{ = sublingual/buccal}
#' \item{\code{"TD"}}{ = transdermal}
#' \item{\code{"V"}}{ = vaginal}
#' }
#'
#' Abbreviations of return values when using \code{property = "U"} (unit):
#' \itemize{
#' \item{\code{"g"}}{ = gram}
#' \item{\code{"mg"}}{ = milligram}
#' \item{\code{"mcg"}}{ = microgram}
#' \item{\code{"U"}}{ = unit}
#' \item{\code{"TU"}}{ = thousand units}
#' \item{\code{"MU"}}{ = million units}
#' \item{\code{"mmol"}}{ = millimole}
#' \item{\code{"ml"}}{ = milliliter (e.g. eyedrops)}
#' }
#' @export
#' @rdname atc_online
#' @importFrom dplyr %>% progress_estimated
2019-02-21 18:55:52 +01:00
#' @inheritSection AMR Read more on our website!
2019-01-26 23:22:56 +01:00
#' @source \url{https://www.whocc.no/atc_ddd_alterations__cumulative/ddd_alterations/abbrevations/}
#' @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-11 17:21:02 +02:00
for (j in seq_len(length(tbl))) {
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", ...)
}