(v1.2.0.9017) ab_from_text() improvement

This commit is contained in:
dr. M.S. (Matthijs) Berends 2020-06-26 12:31:27 +02:00
parent b31003c0b6
commit 4f6f056077
19 changed files with 239 additions and 118 deletions

View File

@ -1,5 +1,5 @@
Package: AMR
Version: 1.2.0.9016
Version: 1.2.0.9017
Date: 2020-06-26
Title: Antimicrobial Resistance Analysis
Authors@R: c(

18
NEWS.md
View File

@ -1,11 +1,18 @@
# AMR 1.2.0.9016
# AMR 1.2.0.9017
## <small>Last updated: 26-Jun-2020</small>
### New
* Function `ab_from_text()` to retrieve antimicrobial drugs from clinical texts in e.g. health care records, which also corrects for misspelling since it uses `as.ab()` internally:
```r
ab_from_text("28/03/2020 regular amoxiciliin 500mg po tds")
#> [1] "Amoxicillin"
ab_from_text(c("28/03/2020 regular amoxiciliin 500mg po tds",
"15/04/2020 started on ciprofloxi-thingy and tobra today"))
#> [[1]]
#> Class <ab>
#> [1] AMX
#>
#> [[2]]
#> Class <ab>
#> [1] CIP TOB
```
* [Tidyverse selections](https://tidyselect.r-lib.org/reference/language.html) for antibiotic classes, that help to select the columns of antibiotics that are of a specific antibiotic class, without the need to define the columns or antibiotic abbreviations. They can be used in any function that allows Tidyverse selections, like `dplyr::select()` and `tidyr::pivot_longer()`:
```r
@ -29,6 +36,7 @@
* Added function `filter_penicillins()` to filter isolates on a specific result in any column with a name in the antimicrobial 'penicillins' class (more specific: ATC subgroup *Beta-lactam antibacterials, penicillins*)
* Added official antimicrobial names to all `filter_ab_class()` functions, such as `filter_aminoglycosides()`
* Added antibiotics code "FOX1" for cefoxitin screening (abbreviation "cfsc") to the `antibiotics` data set
* Added Monuril as trade name for fosfomycin
### Changed
* Using unexisting columns in all `count_*()`, `proportion_*()`, `susceptibility()` and `resistance()` functions wil now return an error instead of dropping them silently
@ -40,8 +48,8 @@
* Fixed a bug in `bug_drug_combinations()` for when only one antibiotic was in the input data
* Changed the summary for class `<mo>`, to highlight the %SI vs. %R
* Improved error handling, giving more useful info when functions return an error
* Algorithm improvements to `as.ab()`, many more misspellings are now translatable
* Added Monuril as trade name for fosfomycin
* Algorithm improvements to `as.ab()`, many more misspellings are now translatable. The `as.ab()` function will now throw a note if more than 1 antimicrobial drug could be retrieved from a single input value.
* Added progress bar to `as.ab()`
# AMR 1.2.0

111
R/ab.R
View File

@ -24,6 +24,7 @@
#' Use this function to determine the antibiotic code of one or more antibiotics. The data set [antibiotics] will be searched for abbreviations, official names and synonyms (brand names).
#' @inheritSection lifecycle Maturing lifecycle
#' @param x character vector to determine to antibiotic ID
#' @param flag_multiple_results logical to indicate whether a note should be printed to the console that probably more than one antibiotic code or name can be retrieved from a single input value.
#' @param ... arguments passed on to internal functions
#' @rdname as.ab
#' @inheritSection WHOCC WHOCC
@ -67,7 +68,7 @@
#' # they use as.ab() internally:
#' ab_name("J01FA01") # "Erythromycin"
#' ab_name("eryt") # "Erythromycin"
as.ab <- function(x, ...) {
as.ab <- function(x, flag_multiple_results = TRUE, ...) {
check_dataset_integrity()
@ -75,7 +76,7 @@ as.ab <- function(x, ...) {
return(x)
}
initial <- is.null(list(...)$initial)
initial_search <- is.null(list(...)$initial_search)
already_regex <- isTRUE(list(...)$already_regex)
if (all(toupper(x) %in% antibiotics$ab)) {
@ -114,7 +115,24 @@ as.ab <- function(x, ...) {
x_new <- rep(NA_character_, length(x))
x_unknown <- character(0)
note_if_more_than_one_found <- function(found, index, from_text) {
if (initial_search == TRUE & isTRUE(length(from_text) > 1)) {
message(font_blue(paste0("NOTE: more than one result was found for item ", index, ": ",
paste0(ab_name(from_text, tolower = TRUE, initial_search = FALSE), collapse = ", "))))
}
found[1L]
}
if (initial_search == TRUE) {
progress <- progress_estimated(n = length(x), n_min = 25) # start if n >= 25
on.exit(close(progress))
}
for (i in seq_len(length(x))) {
if (initial_search == TRUE) {
progress$tick()
}
if (is.na(x[i]) | is.null(x[i])) {
next
}
@ -127,31 +145,37 @@ as.ab <- function(x, ...) {
next
}
if (isTRUE(flag_multiple_results) & x[i] %like% "[ ]") {
from_text <- suppressWarnings(ab_from_text(x[i], initial_search = FALSE, translate_ab = FALSE))
} else {
from_text <- character(0)
}
# exact AB code
found <- antibiotics[which(antibiotics$ab == x[i]), ]$ab
if (length(found) > 0) {
x_new[i] <- found[1L]
x_new[i] <- note_if_more_than_one_found(found, i, from_text)
next
}
# exact ATC code
found <- antibiotics[which(antibiotics$atc == x[i]), ]$ab
if (length(found) > 0) {
x_new[i] <- found[1L]
x_new[i] <- note_if_more_than_one_found(found, i, from_text)
next
}
# exact CID code
found <- antibiotics[which(antibiotics$cid == x[i]), ]$ab
if (length(found) > 0) {
x_new[i] <- found[1L]
x_new[i] <- note_if_more_than_one_found(found, i, from_text)
next
}
# exact name
found <- antibiotics[which(toupper(antibiotics$name) == x[i]), ]$ab
if (length(found) > 0) {
x_new[i] <- found[1L]
x_new[i] <- note_if_more_than_one_found(found, i, from_text)
next
}
@ -160,7 +184,7 @@ as.ab <- function(x, ...) {
function(s) x[i] %in% s))
found <- antibiotics$ab[loinc_found == TRUE]
if (length(found) > 0) {
x_new[i] <- found[1L]
x_new[i] <- note_if_more_than_one_found(found, i, from_text)
next
}
@ -169,7 +193,7 @@ as.ab <- function(x, ...) {
function(s) x[i] %in% toupper(s)))
found <- antibiotics$ab[synonym_found == TRUE]
if (length(found) > 0) {
x_new[i] <- found[1L]
x_new[i] <- note_if_more_than_one_found(found, i, from_text)
next
}
@ -178,7 +202,7 @@ as.ab <- function(x, ...) {
function(a) x[i] %in% toupper(a)))
found <- antibiotics$ab[abbr_found == TRUE]
if (length(found) > 0) {
x_new[i] <- found[1L]
x_new[i] <- note_if_more_than_one_found(found, i, from_text)
next
}
@ -213,13 +237,13 @@ as.ab <- function(x, ...) {
# try if name starts with it
found <- antibiotics[which(antibiotics$name %like% paste0("^", x_spelling)), ]$ab
if (length(found) > 0) {
x_new[i] <- found[1L]
x_new[i] <- note_if_more_than_one_found(found, i, from_text)
next
}
# try if name ends with it
found <- antibiotics[which(antibiotics$name %like% paste0(x_spelling, "$")), ]$ab
if (nchar(x[i]) >= 4 & length(found) > 0) {
x_new[i] <- found[1L]
x_new[i] <- note_if_more_than_one_found(found, i, from_text)
next
}
# and try if any synonym starts with it
@ -227,29 +251,29 @@ as.ab <- function(x, ...) {
function(s) any(s %like% paste0("^", x_spelling))))
found <- antibiotics$ab[synonym_found == TRUE]
if (length(found) > 0) {
x_new[i] <- found[1L]
x_new[i] <- note_if_more_than_one_found(found, i, from_text)
next
}
# INITIAL - More uncertain results ----
# INITIAL SEARCH - More uncertain results ----
if (initial == TRUE) {
if (initial_search == TRUE) {
# only run on first try
# try by removing all spaces
if (x[i] %like% " ") {
found <- suppressWarnings(as.ab(gsub(" +", "", x[i]), initial = FALSE))
found <- suppressWarnings(as.ab(gsub(" +", "", x[i]), initial_search = FALSE))
if (length(found) > 0 & !is.na(found)) {
x_new[i] <- found[1L]
x_new[i] <- note_if_more_than_one_found(found, i, from_text)
next
}
}
# try by removing all spaces and numbers
if (x[i] %like% " " | x[i] %like% "[0-9]") {
found <- suppressWarnings(as.ab(gsub("[ 0-9]", "", x[i]), initial = FALSE))
found <- suppressWarnings(as.ab(gsub("[ 0-9]", "", x[i]), initial_search = FALSE))
if (length(found) > 0 & !is.na(found)) {
x_new[i] <- found[1L]
x_new[i] <- note_if_more_than_one_found(found, i, from_text)
next
}
}
@ -266,7 +290,7 @@ as.ab <- function(x, ...) {
y
})[[1]],
collapse = "/")
x_translated_guess <- suppressWarnings(as.ab(x_translated, initial = FALSE))
x_translated_guess <- suppressWarnings(as.ab(x_translated, initial_search = FALSE))
if (!is.na(x_translated_guess)) {
x_new[i] <- x_translated_guess
next
@ -276,7 +300,7 @@ as.ab <- function(x, ...) {
x_translated <- paste(lapply(strsplit(x_translated, "[^A-Z0-9 ]"),
function(y) {
for (i in seq_len(length(y))) {
y_name <- suppressWarnings(ab_name(y[i], language = NULL, initial = FALSE))
y_name <- suppressWarnings(ab_name(y[i], language = NULL, initial_search = FALSE))
y[i] <- ifelse(!is.na(y_name),
y_name,
y[i])
@ -284,7 +308,7 @@ as.ab <- function(x, ...) {
y
})[[1]],
collapse = "/")
x_translated_guess <- suppressWarnings(as.ab(x_translated, initial = FALSE))
x_translated_guess <- suppressWarnings(as.ab(x_translated, initial_search = FALSE))
if (!is.na(x_translated_guess)) {
x_new[i] <- x_translated_guess
next
@ -292,60 +316,65 @@ as.ab <- function(x, ...) {
# try by removing all trailing capitals
if (x[i] %like_case% "[a-z]+[A-Z]+$") {
found <- suppressWarnings(as.ab(gsub("[A-Z]+$", "", x[i]), initial = FALSE))
found <- suppressWarnings(as.ab(gsub("[A-Z]+$", "", x[i]), initial_search = FALSE))
if (!is.na(found)) {
x_new[i] <- found[1L]
x_new[i] <- note_if_more_than_one_found(found, i, from_text)
next
}
}
# keep only letters
found <- suppressWarnings(as.ab(gsub("[^A-Z]", "", x[i]), initial = FALSE))
found <- suppressWarnings(as.ab(gsub("[^A-Z]", "", x[i]), initial_search = FALSE))
if (!is.na(found)) {
x_new[i] <- found[1L]
x_new[i] <- note_if_more_than_one_found(found, i, from_text)
next
}
# try from a bigger text, like from a health care record, see ?ab_from_text
found <- suppressWarnings(ab_from_text(x[i], initial = FALSE, translate_ab = FALSE)[1L])
# already calculated above if flag_multiple_results = TRUE
if (isTRUE(flag_multiple_results)) {
found <- from_text[1L]
} else {
found <- suppressWarnings(ab_from_text(x[i], initial_search = FALSE, translate_ab = FALSE)[1L])
}
if (!is.na(found)) {
x_new[i] <- found[1L]
x_new[i] <- note_if_more_than_one_found(found, i, from_text)
next
}
# first 5 except for cephalosporins, then first 7 (those cephalosporins all start quite the same!)
found <- suppressWarnings(as.ab(substr(x[i], 1, 5), initial = FALSE))
if (!is.na(found) && !ab_group(found, initial = FALSE) %like% "cephalosporins") {
x_new[i] <- found[1L]
found <- suppressWarnings(as.ab(substr(x[i], 1, 5), initial_search = FALSE))
if (!is.na(found) && !ab_group(found, initial_search = FALSE) %like% "cephalosporins") {
x_new[i] <- note_if_more_than_one_found(found, i, from_text)
next
}
found <- suppressWarnings(as.ab(substr(x[i], 1, 7), initial = FALSE))
found <- suppressWarnings(as.ab(substr(x[i], 1, 7), initial_search = FALSE))
if (!is.na(found)) {
x_new[i] <- found[1L]
x_new[i] <- note_if_more_than_one_found(found, i, from_text)
next
}
# make all consonants facultative
search_str <- gsub("([BCDFGHJKLMNPQRSTVWXZ])", "\\1*", x[i])
found <- suppressWarnings(as.ab(search_str, initial = FALSE, already_regex = TRUE))
found <- suppressWarnings(as.ab(search_str, initial_search = FALSE, already_regex = TRUE))
# keep at least 4 normal characters
if (nchar(gsub(".\\*", "", search_str)) < 4) {
found <- NA
}
if (!is.na(found)) {
x_new[i] <- found[1L]
x_new[i] <- note_if_more_than_one_found(found, i, from_text)
next
}
# make all vowels facultative
search_str <- gsub("([AEIOUY])", "\\1*", x[i])
found <- suppressWarnings(as.ab(search_str, initial = FALSE, already_regex = TRUE))
found <- suppressWarnings(as.ab(search_str, initial_search = FALSE, already_regex = TRUE))
# keep at least 5 normal characters
if (nchar(gsub(".\\*", "", search_str)) < 5) {
found <- NA
}
if (!is.na(found)) {
x_new[i] <- found[1L]
x_new[i] <- note_if_more_than_one_found(found, i, from_text)
next
}
@ -355,17 +384,21 @@ as.ab <- function(x, ...) {
x_spelling <- gsub("I+", "[AEIOU]+", x_spelling, fixed = TRUE)
x_spelling <- gsub("O+", "[AEIOU]+", x_spelling, fixed = TRUE)
x_spelling <- gsub("U+", "[AEIOU]+", x_spelling, fixed = TRUE)
found <- suppressWarnings(as.ab(x_spelling, initial = FALSE, already_regex = TRUE))
found <- suppressWarnings(as.ab(x_spelling, initial_search = FALSE, already_regex = TRUE))
if (!is.na(found)) {
x_new[i] <- found[1L]
x_new[i] <- note_if_more_than_one_found(found, i, from_text)
next
}
} # end of initial = TRUE
} # end of initial_search = TRUE
# not found
x_unknown <- c(x_unknown, x_bak[x[i] == x_bak_clean][1])
}
if (initial_search == TRUE) {
close(progress)
}
# take failed ATC codes apart from rest
x_unknown_ATCs <- x_unknown[x_unknown %like% "[A-Z][0-9][0-9][A-Z][A-Z][0-9][0-9]"]

View File

@ -19,18 +19,24 @@
# Visit our website for more info: https://msberends.gitlab.io/AMR. #
# ==================================================================== #
#' Retrieve antimicrobial drugs from text
#' Retrieve antimicrobial drugs from clinical text
#'
#' Use this function on e.g. clinical texts from health care records. It returns a vector of antimicrobial drugs found in the texts.
#' Use this function on e.g. clinical texts from health care records. It returns a [list] with all antimicrobial drugs found in the texts.
#' @param text text to analyse
#' @param collapse character to pass on to `paste(..., collapse = ...)` to only return one character per element of `text`, see Examples
#' @param translate_ab a column name of the [antibiotics] data set to translate the antibiotic abbreviations to, using [ab_property()]. Defaults to "name", which is equal to using `TRUE`. Use a value `FALSE`, `NULL` or `NA` to prevent translation of the `<ab>` code.
#' @param translate_ab a column name of the [antibiotics] data set to translate the antibiotic abbreviations to, using [ab_property()]. Defaults to `FALSE`. Using `TRUE` is equal to using "name".
#' @param ... parameters passed on to [as.ab()]
#' @details To use this for creating a new variable in a data set (e.g. with `mutate()`), it could be convenient to paste the outcome together with the `collapse` parameter so every value in your new variable will be a character of length 1:\cr
#' @details Without using `collapse`, this function will return a [list]. This can be convenient to use e.g. inside a `mutate()`):\cr
#' `df %>% mutate(abx = ab_from_text(clinical_text))`
#'
#' The returned AB codes can be transformed to official names, groups, etc. with all [ab_property()] functions like [ab_name()] and [ab_group()], or by using the `translate_ab` parameter.
#'
#' With using `collapse`, this function will return a [character]:\cr
#' `df %>% mutate(abx = ab_from_text(clinical_text, collapse = "|"))`
#'
#' This function is also internally used by [as.ab()], although it then only returns the first hit.
#' This function is also internally used by [as.ab()], although it then only returns the first hit and will throw a note if more results could have been returned.
#' @export
#' @return A [list], or a [character] if `collapse` is not `NULL`
#' @examples
#' # mind the bad spelling of amoxicillin in this line,
#' # straight from a true health care record:
@ -41,10 +47,23 @@
#'
#' # if you want to know which antibiotic groups were administered, check it:
#' abx <- ab_from_text("administered amoxi/clav and cipro")
#' ab_group(abx)
ab_from_text <- function(text, collapse = NULL, translate_ab = "name", ...) {
#' ab_group(abx[[1]])
#'
#' if (require(dplyr)) {
#' tibble(clinical_text = c("given cipro and mero",
#' "started on doxy today")) %>%
#' mutate(abx = ab_from_text(clinical_text),
#' abx2 = ab_from_text(clinical_text,
#' collapse = "|"),
#' abx3 = ab_from_text(clinical_text,
#' collapse = "|",
#' translate_ab = "name"))
#'
#' }
ab_from_text <- function(text, collapse = NULL, translate_ab = FALSE, ...) {
text <- tolower(text)
text <- tolower(as.character(text))
translate_ab <- get_translate_ab(translate_ab)
abbr <- unlist(antibiotics$abbreviations)
abbr <- abbr[nchar(abbr) >= 4]
@ -57,24 +76,29 @@ ab_from_text <- function(text, collapse = NULL, translate_ab = "name", ...) {
").*")
}
text_split <- unlist(strsplit(text, "[ ;.,:/\\|-]"))
result <- suppressWarnings(
as.ab(unique(c(text_split[grep(to_regex(abbr), text_split)],
text_split[grep(to_regex(names), text_split)],
# regular expression must not be too long, so split synonyms in two:
text_split[grep(to_regex(synonyms[c(1:0.5 * length(synonyms))]), text_split)],
text_split[grep(to_regex(synonyms[c(0.5 * length(synonyms):length(synonyms))]), text_split)])),
...))
result <- result[!is.na(result)]
if (length(result) == 0) {
result <- as.ab(NA)
}
translate_ab <- get_translate_ab(translate_ab)
if (!isFALSE(translate_ab)) {
result <- ab_property(result, property = translate_ab)
}
text_split_all <- strsplit(text, "[ ;.,:/\\|-]")
result <- lapply(text_split_all, function(text_split) {
suppressWarnings(
out <- as.ab(unique(c(text_split[grep(to_regex(abbr), text_split)],
text_split[grep(to_regex(names), text_split)],
# regular expression must not be too long, so split synonyms in two:
text_split[grep(to_regex(synonyms[c(1:0.5 * length(synonyms))]), text_split)],
text_split[grep(to_regex(synonyms[c(0.5 * length(synonyms):length(synonyms))]), text_split)])),
...))
out <- out[!is.na(out)]
if (length(out) == 0) {
as.ab(NA)
} else {
if (!isFALSE(translate_ab)) {
out <- ab_property(out, property = translate_ab, initial = FALSE)
}
out
}
})
if (!is.null(collapse)) {
result <- paste0(result, collapse = collapse)
result <- sapply(result, function(x) paste0(x, collapse = collapse))
}
result
}

View File

@ -291,7 +291,8 @@ first_isolate <- function(x,
# did find some isolates - add new index numbers of rows
x$newvar_row_index_sorted <- seq_len(nrow(x))
scope.size <- row.end - row.start + 1
scope.size <- nrow(x[which(x$newvar_row_index_sorted %in% c(row.start + 1:row.end) &
!is.na(x$newvar_mo)), , drop = FALSE])
identify_new_year <- function(x, episode_days) {
# I asked on StackOverflow:
@ -390,7 +391,7 @@ first_isolate <- function(x,
# handle empty microorganisms
if (any(x$newvar_mo == "UNKNOWN", na.rm = TRUE) & info == TRUE) {
message(font_blue(paste0("NOTE: ", ifelse(include_unknown == TRUE, "Included ", "Excluded "),
format(sum(x$newvar_mo == "UNKNOWN"),
format(sum(x$newvar_mo == "UNKNOWN", na.rm = TRUE),
decimal.mark = decimal.mark, big.mark = big.mark),
" isolates with a microbial ID 'UNKNOWN' (column `", font_bold(col_mo), "`)")))
}
@ -398,7 +399,7 @@ first_isolate <- function(x,
# exclude all NAs
if (any(is.na(x$newvar_mo)) & info == TRUE) {
message(font_blue(paste0("NOTE: Excluded ", format(sum(is.na(x$newvar_mo)),
message(font_blue(paste0("NOTE: Excluded ", format(sum(is.na(x$newvar_mo), na.rm = TRUE),
decimal.mark = decimal.mark, big.mark = big.mark),
" isolates with a microbial ID 'NA' (column `", font_bold(col_mo), "`)")))
}
@ -410,18 +411,18 @@ first_isolate <- function(x,
if (info == TRUE) {
n_found <- base::sum(x$newvar_first_isolate, na.rm = TRUE)
p_found_total <- percentage(n_found / nrow(x))
p_found_total <- percentage(n_found / nrow(x[which(!is.na(x$newvar_mo)), , drop = FALSE]))
p_found_scope <- percentage(n_found / scope.size)
# mark up number of found
n_found <- base::format(n_found, big.mark = big.mark, decimal.mark = decimal.mark)
if (p_found_total != p_found_scope) {
msg_txt <- paste0("=> Found ",
font_bold(paste0(n_found, " first ", weighted.notice, "isolates")),
" (", p_found_scope, " within scope and ", p_found_total, " of total)")
" (", p_found_scope, " within scope and ", p_found_total, " of total where a microbial ID was available)")
} else {
msg_txt <- paste0("=> Found ",
font_bold(paste0(n_found, " first ", weighted.notice, "isolates")),
" (", p_found_total, " of total)")
" (", p_found_total, " of total where a microbial ID was available)")
}
message(font_black(msg_txt))
}

View File

@ -81,7 +81,7 @@
</button>
<span class="navbar-brand">
<a class="navbar-link" href="https://msberends.gitlab.io/AMR/index.html">AMR (for R)</a>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.2.0.9016</span>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.2.0.9017</span>
</span>
</div>

View File

@ -81,7 +81,7 @@
</button>
<span class="navbar-brand">
<a class="navbar-link" href="index.html">AMR (for R)</a>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.2.0.9016</span>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.2.0.9017</span>
</span>
</div>

View File

@ -81,7 +81,7 @@
</button>
<span class="navbar-brand">
<a class="navbar-link" href="../index.html">AMR (for R)</a>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.2.0.9016</span>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.2.0.9017</span>
</span>
</div>

View File

@ -81,7 +81,7 @@
</button>
<span class="navbar-brand">
<a class="navbar-link" href="index.html">AMR (for R)</a>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.2.0.9016</span>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.2.0.9017</span>
</span>
</div>

View File

@ -43,7 +43,7 @@
</button>
<span class="navbar-brand">
<a class="navbar-link" href="index.html">AMR (for R)</a>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.2.0.9016</span>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.2.0.9017</span>
</span>
</div>

View File

@ -81,7 +81,7 @@
</button>
<span class="navbar-brand">
<a class="navbar-link" href="../index.html">AMR (for R)</a>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.2.0.9016</span>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.2.0.9017</span>
</span>
</div>
@ -229,9 +229,9 @@
<small>Source: <a href='https://gitlab.com/msberends/AMR/blob/master/NEWS.md'><code>NEWS.md</code></a></small>
</div>
<div id="amr-1209016" class="section level1">
<h1 class="page-header" data-toc-text="1.2.0.9016">
<a href="#amr-1209016" class="anchor"></a>AMR 1.2.0.9016<small> Unreleased </small>
<div id="amr-1209017" class="section level1">
<h1 class="page-header" data-toc-text="1.2.0.9017">
<a href="#amr-1209017" class="anchor"></a>AMR 1.2.0.9017<small> Unreleased </small>
</h1>
<div id="last-updated-26-jun-2020" class="section level2">
<h2 class="hasAnchor">
@ -243,8 +243,15 @@
<ul>
<li>
<p>Function <code><a href="../reference/ab_from_text.html">ab_from_text()</a></code> to retrieve antimicrobial drugs from clinical texts in e.g. health care records, which also corrects for misspelling since it uses <code><a href="../reference/as.ab.html">as.ab()</a></code> internally:</p>
<div class="sourceCode" id="cb1"><pre class="r"><span class="fu"><a href="../reference/ab_from_text.html">ab_from_text</a></span>(<span class="st">"28/03/2020 regular amoxiciliin 500mg po tds"</span>)
<span class="co">#&gt; [1] "Amoxicillin"</span></pre></div>
<div class="sourceCode" id="cb1"><pre class="r"><span class="fu"><a href="../reference/ab_from_text.html">ab_from_text</a></span>(<span class="fu"><a href="https://rdrr.io/r/base/c.html">c</a></span>(<span class="st">"28/03/2020 regular amoxiciliin 500mg po tds"</span>,
<span class="st">"15/04/2020 started on ciprofloxi-thingy and tobra today"</span>))
<span class="co">#&gt; [[1]]</span>
<span class="co">#&gt; Class &lt;ab&gt;</span>
<span class="co">#&gt; [1] AMX</span>
<span class="co">#&gt; </span>
<span class="co">#&gt; [[2]]</span>
<span class="co">#&gt; Class &lt;ab&gt;</span>
<span class="co">#&gt; [1] CIP TOB</span></pre></div>
</li>
<li>
<p><a href="https://tidyselect.r-lib.org/reference/language.html">Tidyverse selections</a> for antibiotic classes, that help to select the columns of antibiotics that are of a specific antibiotic class, without the need to define the columns or antibiotic abbreviations. They can be used in any function that allows Tidyverse selections, like <code><a href="https://dplyr.tidyverse.org/reference/select.html">dplyr::select()</a></code> and <code><a href="https://tidyr.tidyverse.org/reference/pivot_longer.html">tidyr::pivot_longer()</a></code>:</p>
@ -268,6 +275,7 @@
<li><p>Added function <code><a href="../reference/filter_ab_class.html">filter_penicillins()</a></code> to filter isolates on a specific result in any column with a name in the antimicrobial penicillins class (more specific: ATC subgroup <em>Beta-lactam antibacterials, penicillins</em>)</p></li>
<li><p>Added official antimicrobial names to all <code><a href="../reference/filter_ab_class.html">filter_ab_class()</a></code> functions, such as <code><a href="../reference/filter_ab_class.html">filter_aminoglycosides()</a></code></p></li>
<li><p>Added antibiotics code “FOX1” for cefoxitin screening (abbreviation “cfsc”) to the <code>antibiotics</code> data set</p></li>
<li><p>Added Monuril as trade name for fosfomycin</p></li>
</ul>
</div>
<div id="changed" class="section level3">
@ -284,8 +292,9 @@
<li>Fixed a bug in <code><a href="../reference/bug_drug_combinations.html">bug_drug_combinations()</a></code> for when only one antibiotic was in the input data</li>
<li>Changed the summary for class <code>&lt;mo&gt;</code>, to highlight the %SI vs. %R</li>
<li>Improved error handling, giving more useful info when functions return an error</li>
<li>Algorithm improvements to <code><a href="../reference/as.ab.html">as.ab()</a></code>, many more misspellings are now translatable</li>
<li>Added Monuril as trade name for fosfomycin</li>
<li>Algorithm improvements to <code><a href="../reference/as.ab.html">as.ab()</a></code>, many more misspellings are now translatable. The <code><a href="../reference/as.ab.html">as.ab()</a></code> function will now throw a note if more than 1 antimicrobial drug could be retrieved from a single input value.</li>
<li>Added progress bar to <code><a href="../reference/as.ab.html">as.ab()</a></code>
</li>
</ul>
</div>
</div>

View File

@ -10,7 +10,7 @@ articles:
WHONET: WHONET.html
benchmarks: benchmarks.html
resistance_predict: resistance_predict.html
last_built: 2020-06-26T08:20Z
last_built: 2020-06-26T10:31Z
urls:
reference: https://msberends.gitlab.io/AMR/reference
article: https://msberends.gitlab.io/AMR/articles

View File

@ -6,7 +6,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Retrieve antimicrobial drugs from text — ab_from_text • AMR (for R)</title>
<title>Retrieve antimicrobial drugs from clinical text — ab_from_text • AMR (for R)</title>
<!-- favicons -->
<link rel="icon" type="image/png" sizes="16x16" href="../favicon-16x16.png">
@ -48,8 +48,8 @@
<link href="../extra.css" rel="stylesheet">
<script src="../extra.js"></script>
<meta property="og:title" content="Retrieve antimicrobial drugs from text — ab_from_text" />
<meta property="og:description" content="Use this function on e.g. clinical texts from health care records. It returns a vector of antimicrobial drugs found in the texts." />
<meta property="og:title" content="Retrieve antimicrobial drugs from clinical text — ab_from_text" />
<meta property="og:description" content="Use this function on e.g. clinical texts from health care records. It returns a list with all antimicrobial drugs found in the texts." />
<meta property="og:image" content="https://msberends.gitlab.io/AMR/logo.svg" />
@ -82,7 +82,7 @@
</button>
<span class="navbar-brand">
<a class="navbar-link" href="../index.html">AMR (for R)</a>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.2.0.9016</span>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.2.0.9017</span>
</span>
</div>
@ -226,16 +226,16 @@
<div class="row">
<div class="col-md-9 contents">
<div class="page-header">
<h1>Retrieve antimicrobial drugs from text</h1>
<h1>Retrieve antimicrobial drugs from clinical text</h1>
<small class="dont-index">Source: <a href='https://gitlab.com/msberends/AMR/blob/master/R/ab_from_text.R'><code>R/ab_from_text.R</code></a></small>
<div class="hidden name"><code>ab_from_text.Rd</code></div>
</div>
<div class="ref-description">
<p>Use this function on e.g. clinical texts from health care records. It returns a vector of antimicrobial drugs found in the texts.</p>
<p>Use this function on e.g. clinical texts from health care records. It returns a <a href='https://rdrr.io/r/base/list.html'>list</a> with all antimicrobial drugs found in the texts.</p>
</div>
<pre class="usage"><span class='fu'>ab_from_text</span>(<span class='no'>text</span>, <span class='kw'>collapse</span> <span class='kw'>=</span> <span class='kw'>NULL</span>, <span class='kw'>translate_ab</span> <span class='kw'>=</span> <span class='st'>"name"</span>, <span class='no'>...</span>)</pre>
<pre class="usage"><span class='fu'>ab_from_text</span>(<span class='no'>text</span>, <span class='kw'>collapse</span> <span class='kw'>=</span> <span class='kw'>NULL</span>, <span class='kw'>translate_ab</span> <span class='kw'>=</span> <span class='fl'>FALSE</span>, <span class='no'>...</span>)</pre>
<h2 class="hasAnchor" id="arguments"><a class="anchor" href="#arguments"></a>Arguments</h2>
<table class="ref-arguments">
@ -250,7 +250,7 @@
</tr>
<tr>
<th>translate_ab</th>
<td><p>a column name of the <a href='antibiotics.html'>antibiotics</a> data set to translate the antibiotic abbreviations to, using <code><a href='ab_property.html'>ab_property()</a></code>. Defaults to "name", which is equal to using <code>TRUE</code>. Use a value <code>FALSE</code>, <code>NULL</code> or <code>NA</code> to prevent translation of the <code>&lt;ab&gt;</code> code.</p></td>
<td><p>a column name of the <a href='antibiotics.html'>antibiotics</a> data set to translate the antibiotic abbreviations to, using <code><a href='ab_property.html'>ab_property()</a></code>. Defaults to <code>FALSE</code>. Using <code>TRUE</code> is equal to using "name".</p></td>
</tr>
<tr>
<th>...</th>
@ -258,11 +258,17 @@
</tr>
</table>
<h2 class="hasAnchor" id="value"><a class="anchor" href="#value"></a>Value</h2>
<p>A <a href='https://rdrr.io/r/base/list.html'>list</a>, or a <a href='https://rdrr.io/r/base/character.html'>character</a> if <code>collapse</code> is not <code>NULL</code></p>
<h2 class="hasAnchor" id="details"><a class="anchor" href="#details"></a>Details</h2>
<p>To use this for creating a new variable in a data set (e.g. with <code>mutate()</code>), it could be convenient to paste the outcome together with the <code>collapse</code> parameter so every value in your new variable will be a character of length 1:<br />
<p>Without using <code>collapse</code>, this function will return a <a href='https://rdrr.io/r/base/list.html'>list</a>. This can be convenient to use e.g. inside a <code><a href='https://dplyr.tidyverse.org/reference/mutate.html'>mutate()</a></code>):<br />
<code>df %&gt;% mutate(abx = ab_from_text(clinical_text))</code></p>
<p>The returned AB codes can be transformed to official names, groups, etc. with all <code><a href='ab_property.html'>ab_property()</a></code> functions like <code><a href='ab_property.html'>ab_name()</a></code> and <code><a href='ab_property.html'>ab_group()</a></code>, or by using the <code>translate_ab</code> parameter.</p>
<p>With using <code>collapse</code>, this function will return a <a href='https://rdrr.io/r/base/character.html'>character</a>:<br />
<code>df %&gt;% mutate(abx = ab_from_text(clinical_text, collapse = "|"))</code></p>
<p>This function is also internally used by <code><a href='as.ab.html'>as.ab()</a></code>, although it then only returns the first hit.</p>
<p>This function is also internally used by <code><a href='as.ab.html'>as.ab()</a></code>, although it then only returns the first hit and will throw a note if more results could have been returned.</p>
<h2 class="hasAnchor" id="examples"><a class="anchor" href="#examples"></a>Examples</h2>
<pre class="examples"><span class='co'># mind the bad spelling of amoxicillin in this line, </span>
@ -274,7 +280,19 @@
<span class='co'># if you want to know which antibiotic groups were administered, check it:</span>
<span class='no'>abx</span> <span class='kw'>&lt;-</span> <span class='fu'>ab_from_text</span>(<span class='st'>"administered amoxi/clav and cipro"</span>)
<span class='fu'><a href='ab_property.html'>ab_group</a></span>(<span class='no'>abx</span>)</pre>
<span class='fu'><a href='ab_property.html'>ab_group</a></span>(<span class='no'>abx</span><span class='kw'>[[</span><span class='fl'>1</span>]])
<span class='kw'>if</span> (<span class='fu'><a href='https://rdrr.io/r/base/library.html'>require</a></span>(<span class='no'>dplyr</span>)) {
<span class='fu'><a href='https://dplyr.tidyverse.org/reference/reexports.html'>tibble</a></span>(<span class='kw'>clinical_text</span> <span class='kw'>=</span> <span class='fu'><a href='https://rdrr.io/r/base/c.html'>c</a></span>(<span class='st'>"given cipro and mero"</span>,
<span class='st'>"started on doxy today"</span>)) <span class='kw'>%&gt;%</span>
<span class='fu'><a href='https://dplyr.tidyverse.org/reference/mutate.html'>mutate</a></span>(<span class='kw'>abx</span> <span class='kw'>=</span> <span class='fu'>ab_from_text</span>(<span class='no'>clinical_text</span>),
<span class='kw'>abx2</span> <span class='kw'>=</span> <span class='fu'>ab_from_text</span>(<span class='no'>clinical_text</span>,
<span class='kw'>collapse</span> <span class='kw'>=</span> <span class='st'>"|"</span>),
<span class='kw'>abx3</span> <span class='kw'>=</span> <span class='fu'>ab_from_text</span>(<span class='no'>clinical_text</span>,
<span class='kw'>collapse</span> <span class='kw'>=</span> <span class='st'>"|"</span>,
<span class='kw'>translate_ab</span> <span class='kw'>=</span> <span class='st'>"name"</span>))
}</pre>
</div>
<div class="col-md-3 hidden-xs hidden-sm" id="pkgdown-sidebar">
<nav id="toc" data-toggle="toc" class="sticky-top">

View File

@ -82,7 +82,7 @@
</button>
<span class="navbar-brand">
<a class="navbar-link" href="../index.html">AMR (for R)</a>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.2.0.9016</span>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.2.0.9017</span>
</span>
</div>
@ -235,7 +235,7 @@
<p>Use this function to determine the antibiotic code of one or more antibiotics. The data set <a href='antibiotics.html'>antibiotics</a> will be searched for abbreviations, official names and synonyms (brand names).</p>
</div>
<pre class="usage"><span class='fu'>as.ab</span>(<span class='no'>x</span>, <span class='no'>...</span>)
<pre class="usage"><span class='fu'>as.ab</span>(<span class='no'>x</span>, <span class='kw'>flag_multiple_results</span> <span class='kw'>=</span> <span class='fl'>TRUE</span>, <span class='no'>...</span>)
<span class='fu'>is.ab</span>(<span class='no'>x</span>)</pre>
@ -246,6 +246,10 @@
<th>x</th>
<td><p>character vector to determine to antibiotic ID</p></td>
</tr>
<tr>
<th>flag_multiple_results</th>
<td><p>logical to indicate whether a note should be printed to the console that probably more than one antibiotic code or name can be retrieved from a single input value.</p></td>
</tr>
<tr>
<th>...</th>
<td><p>arguments passed on to internal functions</p></td>

View File

@ -81,7 +81,7 @@
</button>
<span class="navbar-brand">
<a class="navbar-link" href="../index.html">AMR (for R)</a>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.2.0.9016</span>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.2.0.9017</span>
</span>
</div>
@ -289,7 +289,7 @@
<td>
<p><code><a href="ab_from_text.html">ab_from_text()</a></code> </p>
</td>
<td><p>Retrieve antimicrobial drugs from text</p></td>
<td><p>Retrieve antimicrobial drugs from clinical text</p></td>
</tr><tr>
<td>

View File

@ -2,27 +2,35 @@
% Please edit documentation in R/ab_from_text.R
\name{ab_from_text}
\alias{ab_from_text}
\title{Retrieve antimicrobial drugs from text}
\title{Retrieve antimicrobial drugs from clinical text}
\usage{
ab_from_text(text, collapse = NULL, translate_ab = "name", ...)
ab_from_text(text, collapse = NULL, translate_ab = FALSE, ...)
}
\arguments{
\item{text}{text to analyse}
\item{collapse}{character to pass on to \code{paste(..., collapse = ...)} to only return one character per element of \code{text}, see Examples}
\item{translate_ab}{a column name of the \link{antibiotics} data set to translate the antibiotic abbreviations to, using \code{\link[=ab_property]{ab_property()}}. Defaults to "name", which is equal to using \code{TRUE}. Use a value \code{FALSE}, \code{NULL} or \code{NA} to prevent translation of the \verb{<ab>} code.}
\item{translate_ab}{a column name of the \link{antibiotics} data set to translate the antibiotic abbreviations to, using \code{\link[=ab_property]{ab_property()}}. Defaults to \code{FALSE}. Using \code{TRUE} is equal to using "name".}
\item{...}{parameters passed on to \code{\link[=as.ab]{as.ab()}}}
}
\value{
A \link{list}, or a \link{character} if \code{collapse} is not \code{NULL}
}
\description{
Use this function on e.g. clinical texts from health care records. It returns a vector of antimicrobial drugs found in the texts.
Use this function on e.g. clinical texts from health care records. It returns a \link{list} with all antimicrobial drugs found in the texts.
}
\details{
To use this for creating a new variable in a data set (e.g. with \code{mutate()}), it could be convenient to paste the outcome together with the \code{collapse} parameter so every value in your new variable will be a character of length 1:\cr
Without using \code{collapse}, this function will return a \link{list}. This can be convenient to use e.g. inside a \code{mutate()}):\cr
\code{df \%>\% mutate(abx = ab_from_text(clinical_text))}
The returned AB codes can be transformed to official names, groups, etc. with all \code{\link[=ab_property]{ab_property()}} functions like \code{\link[=ab_name]{ab_name()}} and \code{\link[=ab_group]{ab_group()}}, or by using the \code{translate_ab} parameter.
With using \code{collapse}, this function will return a \link{character}:\cr
\code{df \%>\% mutate(abx = ab_from_text(clinical_text, collapse = "|"))}
This function is also internally used by \code{\link[=as.ab]{as.ab()}}, although it then only returns the first hit.
This function is also internally used by \code{\link[=as.ab]{as.ab()}}, although it then only returns the first hit and will throw a note if more results could have been returned.
}
\examples{
# mind the bad spelling of amoxicillin in this line,
@ -34,5 +42,17 @@ ab_from_text("administered amoxi/clav and cipro", collapse = ", ")
# if you want to know which antibiotic groups were administered, check it:
abx <- ab_from_text("administered amoxi/clav and cipro")
ab_group(abx)
ab_group(abx[[1]])
if (require(dplyr)) {
tibble(clinical_text = c("given cipro and mero",
"started on doxy today")) \%>\%
mutate(abx = ab_from_text(clinical_text),
abx2 = ab_from_text(clinical_text,
collapse = "|"),
abx3 = ab_from_text(clinical_text,
collapse = "|",
translate_ab = "name"))
}
}

View File

@ -6,13 +6,15 @@
\alias{is.ab}
\title{Transform to antibiotic ID}
\usage{
as.ab(x, ...)
as.ab(x, flag_multiple_results = TRUE, ...)
is.ab(x)
}
\arguments{
\item{x}{character vector to determine to antibiotic ID}
\item{flag_multiple_results}{logical to indicate whether a note should be printed to the console that probably more than one antibiotic code or name can be retrieved from a single input value.}
\item{...}{arguments passed on to internal functions}
}
\value{

View File

@ -54,6 +54,8 @@ test_that("as.ab works", {
expect_equal(as.character(as.ab("Amoxy + clavulaanzuur")),
"AMC")
expect_message(as.ab("cipro mero"))
# assigning and subsetting
x <- antibiotics$ab

View File

@ -23,10 +23,10 @@ context("ab_from_text.R")
test_that("ab_from_text works", {
expect_identical(ab_from_text("28/03/2020 regular amoxicilliin 500mg po tds"),
expect_identical(ab_from_text("28/03/2020 regular amoxicilliin 500mg po tds")[[1]],
as.ab("Amoxicillin"))
expect_identical(ab_from_text("28/03/2020 regular amoxicilliin 500mg po tds", translate_ab = TRUE)[[1]],
"Amoxicillin")
expect_identical(ab_from_text("28/03/2020 regular amoxicilliin 500mg po tds", translate_ab = FALSE),
as.ab("AMX"))
expect_identical(ab_from_text("administered amoxi/clav and cipro", collapse = ", "),
"Amoxicillin, Ciprofloxacin")
expect_identical(ab_from_text("administered amoxi/clav and cipro", collapse = ", ")[[1]],
"AMX, CIP")
})