diff --git a/DESCRIPTION b/DESCRIPTION
index 34ae0ab2..f06f8f3f 100644
--- a/DESCRIPTION
+++ b/DESCRIPTION
@@ -1,6 +1,6 @@
Package: AMR
Version: 0.2.0
-Date: 2018-04-30
+Date: 2018-05-02
Title: Antimicrobial Resistance Analysis
Authors@R: c(
person(
diff --git a/NAMESPACE b/NAMESPACE
index b027ce30..c74fb9c2 100644
--- a/NAMESPACE
+++ b/NAMESPACE
@@ -38,6 +38,7 @@ export(is.rsi)
export(key_antibiotics)
export(left_join_microorganisms)
export(mo_property)
+export(n_rsi)
export(right_join_microorganisms)
export(rsi)
export(rsi_df)
@@ -96,5 +97,6 @@ importFrom(rvest,html_table)
importFrom(stats,fivenum)
importFrom(stats,quantile)
importFrom(stats,sd)
+importFrom(utils,object.size)
importFrom(utils,packageDescription)
importFrom(xml2,read_html)
diff --git a/NEWS.md b/NEWS.md
index ec2a0d5a..51194f3d 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -2,6 +2,7 @@
#### New
* Full support for Windows, Linux and macOS
* Full support for old R versions, only R-3.0.0 (April 2013) or later is needed (needed packages may have other dependencies)
+* Function `n_rsi` to count cases where antibiotic test results were available, to be used in conjunction with `dplyr::summarise`, see ?rsi
* Function `guess_bactid` to **determine the ID** of a microorganism based on genus/species or known abbreviations like MRSA
* Function `guess_atc` to **determine the ATC** of an antibiotic based on name, trade name, or known abbreviations
* Function `freq` to create **frequency tables**, with additional info in a header
@@ -13,6 +14,7 @@
* New print format for `tibble`s and `data.table`s
#### Changed
+* Fixed `rsi` class for vectors that contain only invalid antimicrobial interpretations
* Renamed dataset `ablist` to `antibiotics`
* Renamed dataset `bactlist` to `microorganisms`
* Added common abbreviations and trade names to the `antibiotics` dataset
diff --git a/R/classes.R b/R/classes.R
index cb0aa73a..20c7db64 100644
--- a/R/classes.R
+++ b/R/classes.R
@@ -93,12 +93,14 @@ print.rsi <- function(x, ...) {
R <- x[x == 'R'] %>% length()
IR <- x[x %in% c('I', 'R')] %>% length()
cat("Class 'rsi'\n")
- cat(n, " results (missing: ", n_total - n, ' = ', percent((n_total - n) / n, force_zero = TRUE), ')\n', sep = "")
- cat('\n')
- cat('Sum of S: ', S, ' (', percent(S / n, force_zero = TRUE), ')\n', sep = "")
- cat('Sum of IR: ', IR, ' (', percent(IR / n, force_zero = TRUE), ')\n', sep = "")
- cat('- Sum of R: ', R, ' (', percent(R / n, force_zero = TRUE), ')\n', sep = "")
- cat('- Sum of I: ', I, ' (', percent(I / n, force_zero = TRUE), ')\n', sep = "")
+ cat(n, " results (missing: ", n_total - n, ' = ', percent((n_total - n) / n_total, force_zero = TRUE), ')\n', sep = "")
+ if (n > 0) {
+ cat('\n')
+ cat('Sum of S: ', S, ' (', percent(S / n, force_zero = TRUE), ')\n', sep = "")
+ cat('Sum of IR: ', IR, ' (', percent(IR / n, force_zero = TRUE), ')\n', sep = "")
+ cat('- Sum of R: ', R, ' (', percent(R / n, force_zero = TRUE), ')\n', sep = "")
+ cat('- Sum of I: ', I, ' (', percent(I / n, force_zero = TRUE), ')\n', sep = "")
+ }
}
#' @exportMethod summary.rsi
diff --git a/R/eucast.R b/R/eucast.R
index 01c3cc5c..3d2575fd 100644
--- a/R/eucast.R
+++ b/R/eucast.R
@@ -36,6 +36,7 @@
#' EUCAST Expert Rules Version 3.1 (Intrinsic Resistance and Exceptional Phenotypes Tables): \cr
#' \url{http://www.eucast.org/fileadmin/src/media/PDFs/EUCAST_files/Expert_Rules/Expert_rules_intrinsic_exceptional_V3.1.pdf}
#' @examples
+#' a <- EUCAST_rules(septic_patients)
#' a <- data.frame(bactid = c("STAAUR", # Staphylococcus aureus
#' "ENCFAE", # Enterococcus faecalis
#' "ESCCOL", # Escherichia coli
diff --git a/R/misc.R b/R/misc.R
index 18a36908..fb6bf27a 100644
--- a/R/misc.R
+++ b/R/misc.R
@@ -48,10 +48,12 @@
# No export, no Rd
percent <- function(x, round = 1, force_zero = FALSE, ...) {
val <- base::round(x * 100, digits = round)
- if (force_zero & any(val == as.integer(val))) {
+ if (force_zero == TRUE & any(val == as.integer(val) & !is.na(val))) {
val[val == as.integer(val)] <- paste0(val[val == as.integer(val)], ".", strrep(0, round))
}
- base::paste0(val, "%")
+ pct <- base::paste0(val, "%")
+ pct[pct == "NA%"] <- NA_character_
+ pct
}
check_available_columns <- function(tbl, col.list, info = TRUE) {
diff --git a/R/print.R b/R/print.R
index 676917bb..09138087 100644
--- a/R/print.R
+++ b/R/print.R
@@ -29,6 +29,7 @@
#' @name print
#' @importFrom dplyr %>% n_groups group_vars group_size filter pull select
#' @importFrom data.table data.table
+#' @importFrom utils object.size
#' @exportMethod print.tbl_df
#' @export
#' @examples
@@ -191,7 +192,8 @@ prettyprint_df <- function(x,
if (n + 1 < nrow(x)) {
# remove in between part, 1 extra for ~~~~ between first and last part
rows_list <- c(1:(n / 2 + 1), (nrow(x) - (n / 2) + 1):nrow(x))
- x <- x %>% filter(row_number() %in% rows_list)
+ x <- as.data.frame(x.bak[rows_list,])
+ colnames(x) <- colnames(x.bak)
rownames(x) <- rownames(x.bak)[rows_list]
# set inbetweener between parts
rownames(x)[n / 2 + 1] <- strrep("~", maxrowchars)
@@ -218,7 +220,11 @@ prettyprint_df <- function(x,
gsub('POSIX', '', .) %>%
paste0(collapse = '/'))
} else {
- c[[1]]
+ if (NCOL(.) > 1) {
+ .[1,]
+ } else {
+ c[[1]]
+ }
}
}) %>%
unlist() %>%
diff --git a/R/rsi_analysis.R b/R/rsi_analysis.R
index 2ec1cdaa..be5874af 100644
--- a/R/rsi_analysis.R
+++ b/R/rsi_analysis.R
@@ -16,40 +16,164 @@
# GNU General Public License for more details. #
# ==================================================================== #
-#' Resistance of isolates in data.frame
+#' Resistance of isolates
#'
-#' \strong{NOTE: use \code{\link{rsi}} in dplyr functions like \code{\link[dplyr]{summarise}}.} \cr Calculate the percentage of S, SI, I, IR or R of a \code{data.frame} containing isolates.
+#' This functions can be used to calculate the (co-)resistance of isolates (i.e. percentage S, SI, I, IR or R [of a vector] of isolates). The functions \code{rsi} and \code{n_rsi} can be used in \code{dplyr}s \code{\link[dplyr]{summarise}} and support grouped variables, see \emph{Examples}.
#' @param tbl \code{data.frame} containing columns with antibiotic interpretations.
#' @param ab character vector with 1, 2 or 3 antibiotics that occur as column names in \code{tbl}, like \code{ab = c("amox", "amcl")}
+#' @param ab1,ab2 vector of antibiotic interpretations, they will be transformed internally with \code{\link{as.rsi}}
#' @param interpretation antimicrobial interpretation of which the portion must be calculated. Valid values are \code{"S"}, \code{"SI"}, \code{"I"}, \code{"IR"} or \code{"R"}.
#' @param minimum minimal amount of available isolates. Any number lower than \code{minimum} will return \code{NA} with a warning (when \code{warning = TRUE}).
-#' @param percent return output as percent (text), will else (at default) be a double
+#' @param as_percent return output as percent (text), will else (at default) be a double
#' @param info calculate the amount of available isolates and print it, like \code{n = 423}
#' @param warning show a warning when the available amount of isolates is below \code{minimum}
#' @details Remember that you should filter your table to let it contain \strong{only first isolates}!
+#'
+#' To calculate the probability (\emph{p}) of susceptibility of one antibiotic, we use this formula:
+#' \if{html}{
+#' \out{
}\figure{mono_therapy.png}\out{
}
+#' }
+#' \if{latex}{
+#' \deqn{p = \frac{\sum{ab1_S}}{\sum{ab1_{R|I|S}}}}
+#' }
+#' \cr
+#' To calculate the probability (\emph{p}) of susceptibility of more antibiotics a combination therapy, we need to check whether one of them has a susceptible result (as numerator) and count all cases where all antibiotics were tested (as denominator). \cr
+#' For two antibiotics:
+#' \if{html}{
+#' \out{}\figure{combi_therapy_2.png}\out{
}
+#' }
+#' \if{latex}{
+#' \deqn{p = \frac{\sum{ab1_S}\mid{ab2_S}}{\sum{ab1_{R|I|S},ab2_{R|I|S}}}}
+#' }
+#' \cr
+#' For three antibiotics:
+#' \if{html}{
+#' \out{}\figure{combi_therapy_3.png}\out{
}
+#' }
+#' \if{latex}{
+#' \deqn{p = \frac{\sum{ab1_S}\mid{ab2_S}\mid{ab3_S}}{\sum{ab1_{R|I|S},ab2_{R|I|S},ab3_{R|I|S}}}}
+#' }
+#'
#' @keywords rsi antibiotics isolate isolates
-#' @return Double or, when \code{percent = TRUE}, a character.
+#' @return Double or, when \code{as_percent = TRUE}, a character.
+#' @rdname rsi
#' @export
#' @importFrom dplyr %>% n_distinct filter filter_at pull vars all_vars any_vars
-#' @seealso \code{\link{rsi}} for the function that can be used with \code{\link[dplyr]{summarise}} directly.
#' @examples
-#' \dontrun{
-#' rsi_df(tbl_with_bloodcultures, 'amcl')
-#'
-#' rsi_df(tbl_with_bloodcultures, c('amcl', 'gent'), interpretation = 'IR')
-#'
#' library(dplyr)
-#' # calculate current empiric therapy of Helicobacter gastritis:
+#'
+#' septic_patients %>%
+#' group_by(hospital_id) %>%
+#' summarise(cipro_susceptibility = rsi(cipr, interpretation = "S"),
+#' n = n_rsi(cipr)) # n_rsi works like n_distinct in dplyr
+#'
+#' septic_patients %>%
+#' group_by(hospital_id) %>%
+#' summarise(cipro_S = rsi(cipr, interpretation = "S",
+#' as_percent = TRUE, warning = FALSE),
+#' cipro_n = n_rsi(cipr),
+#' genta_S = rsi(gent, interpretation = "S",
+#' as_percent = TRUE, warning = FALSE),
+#' genta_n = n_rsi(gent),
+#' combination_S = rsi(cipr, gent, interpretation = "S",
+#' as_percent = TRUE, warning = FALSE),
+#' combination_n = n_rsi(cipr, gent))
+#'
+#' # calculate resistance
+#' rsi(septic_patients$amox)
+#' # or susceptibility
+#' rsi(septic_patients$amox, interpretation = "S")
+#'
+#' # calculate co-resistance between amoxicillin/clav acid and gentamicin,
+#' # so we can review that combination therapy does a lot more than mono therapy:
+#' septic_patients %>% rsi_df(ab = "amcl", interpretation = "S") # = 67.8%
+#' septic_patients %>% rsi_df(ab = "gent", interpretation = "S") # = 69.1%
+#' septic_patients %>% rsi_df(ab = c("amcl", "gent"), interpretation = "S") # = 90.6%
+#'
+#' \dontrun{
+#' # calculate current empiric combination therapy of Helicobacter gastritis:
#' my_table %>%
#' filter(first_isolate == TRUE,
#' genus == "Helicobacter") %>%
-#' rsi_df(ab = c("amox", "metr"))
+#' rsi_df(ab = c("amox", "metr")) # amoxicillin with metronidazole
#' }
+rsi <- function(ab1,
+ ab2 = NA,
+ interpretation = 'IR',
+ minimum = 30,
+ as_percent = FALSE,
+ info = FALSE,
+ warning = TRUE) {
+ ab1.name <- deparse(substitute(ab1))
+ if (ab1.name %like% '.[$].') {
+ ab1.name <- unlist(strsplit(ab1.name, "$", fixed = TRUE))
+ ab1.name <- ab1.name[length(ab1.name)]
+ }
+ if (!ab1.name %like% '^[a-z]{3,4}$') {
+ ab1.name <- 'rsi1'
+ }
+ if (length(ab1) == 1 & is.character(ab1)) {
+ stop('`ab1` must be a vector of antibiotic interpretations.',
+ '\n Try rsi(', ab1, ', ...) instead of rsi("', ab1, '", ...)', call. = FALSE)
+ }
+ ab2.name <- deparse(substitute(ab2))
+ if (ab2.name %like% '.[$].') {
+ ab2.name <- unlist(strsplit(ab2.name, "$", fixed = TRUE))
+ ab2.name <- ab2.name[length(ab2.name)]
+ }
+ if (!ab2.name %like% '^[a-z]{3,4}$') {
+ ab2.name <- 'rsi2'
+ }
+ if (length(ab2) == 1 & is.character(ab2)) {
+ stop('`ab2` must be a vector of antibiotic interpretations.',
+ '\n Try rsi(', ab2, ', ...) instead of rsi("', ab2, '", ...)', call. = FALSE)
+ }
+
+ interpretation <- paste(interpretation, collapse = "")
+
+ ab1 <- as.rsi(ab1)
+ ab2 <- as.rsi(ab2)
+
+ tbl <- tibble(rsi1 = ab1, rsi2 = ab2)
+ colnames(tbl) <- c(ab1.name, ab2.name)
+
+ if (length(ab2) == 1) {
+ r <- rsi_df(tbl = tbl,
+ ab = ab1.name,
+ interpretation = interpretation,
+ minimum = minimum,
+ as_percent = FALSE,
+ info = info,
+ warning = warning)
+ } else {
+ if (length(ab1) != length(ab2)) {
+ stop('`ab1` (n = ', length(ab1), ') and `ab2` (n = ', length(ab2), ') must be of same length.', call. = FALSE)
+ }
+ if (!interpretation %in% c('S', 'IS', 'SI')) {
+ warning('`interpretation` not set to S or I/S, albeit analysing a combination therapy.', call. = FALSE)
+ }
+ r <- rsi_df(tbl = tbl,
+ ab = c(ab1.name, ab2.name),
+ interpretation = interpretation,
+ minimum = minimum,
+ as_percent = FALSE,
+ info = info,
+ warning = warning)
+ }
+ if (as_percent == TRUE) {
+ percent(r, force_zero = TRUE)
+ } else {
+ r
+ }
+}
+
+#' @export
+#' @rdname rsi
rsi_df <- function(tbl,
ab,
interpretation = 'IR',
minimum = 30,
- percent = FALSE,
+ as_percent = FALSE,
info = TRUE,
warning = TRUE) {
@@ -103,6 +227,9 @@ rsi_df <- function(tbl,
nrow()
} else if (length(ab) == 2) {
+ if (interpretations_to_check != 'S') {
+ warning('`interpretation` not set to S or I/S, albeit analysing a combination therapy.', call. = FALSE)
+ }
numerator <- tbl %>%
filter_at(vars(ab[1], ab[2]),
any_vars(. == interpretations_to_check)) %>%
@@ -116,6 +243,9 @@ rsi_df <- function(tbl,
nrow()
} else if (length(ab) == 3) {
+ if (interpretations_to_check != 'S') {
+ warning('`interpretation` not set to S or I/S, albeit analysing a combination therapy.', call. = FALSE)
+ }
numerator <- tbl %>%
filter_at(vars(ab[1], ab[2], ab[3]),
any_vars(. == interpretations_to_check)) %>%
@@ -150,9 +280,10 @@ rsi_df <- function(tbl,
# calculate and format
y <- numerator / denominator
- if (percent == TRUE) {
- y <- percent(y)
+ if (as_percent == TRUE) {
+ y <- percent(y, force_zero = TRUE)
}
+
if (denominator < minimum) {
if (warning == TRUE) {
warning(paste0('TOO FEW ISOLATES OF ', toString(ab), ' (n = ', denominator, ', n < ', minimum, '); NO RESULT.'))
@@ -164,78 +295,29 @@ rsi_df <- function(tbl,
y
}
-#' Resistance of isolates
-#'
-#' This function can be used in \code{dplyr}s \code{\link[dplyr]{summarise}}, see \emph{Examples}. Calculate the percentage S, SI, I, IR or R of a vector of isolates.
-#' @param ab1,ab2 list with interpretations of an antibiotic
-#' @inheritParams rsi_df
-#' @details This function uses the \code{\link{rsi_df}} function internally.
-#' @keywords rsi antibiotics isolate isolates
-#' @return Double or, when \code{percent = TRUE}, a character.
#' @export
-#' @examples
-#' \dontrun{
-#' tbl %>%
-#' group_by(hospital) %>%
-#' summarise(cipr = rsi(cipr))
-#'
-#' tbl %>%
-#' group_by(year, hospital) %>%
-#' summarise(
-#' isolates = n(),
-#' cipro = rsi(cipr %>% as.rsi(), percent = TRUE),
-#' amoxi = rsi(amox %>% as.rsi(), percent = TRUE))
-#'
-#' rsi(as.rsi(isolates$amox))
-#'
-#' rsi(as.rsi(isolates$amcl), interpretation = "S")
-#' }
-rsi <- function(ab1, ab2 = NA, interpretation = 'IR', minimum = 30, percent = FALSE, info = FALSE, warning = FALSE) {
- ab1.name <- deparse(substitute(ab1))
- if (ab1.name %like% '.[$].') {
- ab1.name <- unlist(strsplit(ab1.name, "$", fixed = TRUE))
- ab1.name <- ab1.name[length(ab1.name)]
- }
- if (!ab1.name %like% '^[a-z]{3,4}$') {
- ab1.name <- 'rsi1'
- }
- ab2.name <- deparse(substitute(ab2))
- if (ab2.name %like% '.[$].') {
- ab2.name <- unlist(strsplit(ab2.name, "$", fixed = TRUE))
- ab2.name <- ab2.name[length(ab2.name)]
- }
- if (!ab2.name %like% '^[a-z]{3,4}$') {
- ab2.name <- 'rsi2'
- }
+#' @rdname rsi
+n_rsi <- function(ab1, ab2 = NA) {
- interpretation <- paste(interpretation, collapse = "")
+ if (length(ab1) == 1 & is.character(ab1)) {
+ stop('`ab1` must be a vector of antibiotic interpretations.',
+ '\n Try n_rsi(', ab1, ', ...) instead of n_rsi("', ab1, '", ...)', call. = FALSE)
+ }
+ ab1 <- as.rsi(ab1)
- tbl <- tibble(rsi1 = ab1, rsi2 = ab2)
- colnames(tbl) <- c(ab1.name, ab2.name)
-
- if (length(ab2) == 1) {
- return(rsi_df(tbl = tbl,
- ab = ab1.name,
- interpretation = interpretation,
- minimum = minimum,
- percent = percent,
- info = info,
- warning = warning))
+ if (length(ab2) == 1 & all(is.na(ab2))) {
+ # only 1 antibiotic
+ length(ab1[!is.na(ab1)])
} else {
- if (length(ab1) != length(ab2)) {
- stop('`ab1` (n = ', length(ab1), ') and `ab2` (n = ', length(ab2), ') must be of same length.', call. = FALSE)
+ if (length(ab2) == 1 & is.character(ab2)) {
+ stop('`ab2` must be a vector of antibiotic interpretations.',
+ '\n Try n_rsi(', ab2, ', ...) instead of n_rsi("', ab2, '", ...)', call. = FALSE)
}
- if (interpretation != 'S') {
- warning('`interpretation` is not set to S, albeit analysing a combination therapy.')
- }
- return(rsi_df(tbl = tbl,
- ab = c(ab1.name, ab2.name),
- interpretation = interpretation,
- minimum = minimum,
- percent = percent,
- info = info,
- warning = warning))
+ ab2 <- as.rsi(ab2)
+ tbl <- tibble(ab1, ab2)
+ tbl %>% filter(!is.na(ab1) & !is.na(ab2)) %>% nrow()
}
+
}
#' Predict antimicrobial resistance
diff --git a/README.md b/README.md
index ab51253b..4d889336 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@ This R package contains functions to make **microbiological, epidemiological dat
With `AMR` you can also:
* Create frequency tables with the `freq` function
-* Conduct AMR analysis with the `rsi` function, that can also be used with the `dplyr` package (e.g. in conjunction with `summarise`) to calculate the resistance percentages of different antibiotic columns of a table
+* Conduct AMR analysis with the `rsi` function, that can also be used with the `dplyr` package (e.g. in conjunction with `summarise`) to calculate the resistance percentages (and even co-resistance) of different antibiotic columns of a table
* Predict antimicrobial resistance for the nextcoming years with the `rsi_predict` function
* Apply [EUCAST rules to isolates](http://www.eucast.org/expert_rules_and_intrinsic_resistance/) with the `EUCAST_rules` function
* Identify first isolates of every patient [using guidelines from the CLSI](https://clsi.org/standards/products/microbiology/documents/m39/) (Clinical and Laboratory Standards Institute) with the `first_isolate` function
@@ -264,13 +264,16 @@ abname("J01CR02", from = "atc", to = "umcg") # "AMCL"
### Databases included in package
Datasets to work with antibiotics and bacteria properties.
```r
-# Dataset with 2000 random blood culture isolates from anonymised septic patients between 2001 and 2017 in 5 Dutch hospitals
+# Dataset with 2000 random blood culture isolates from anonymised
+# septic patients between 2001 and 2017 in 5 Dutch hospitals
septic_patients # A tibble: 4,000 x 47
-# Dataset with ATC antibiotics codes, official names, trade names and DDD's (oral and parenteral)
+# Dataset with ATC antibiotics codes, official names, trade names
+# and DDD's (oral and parenteral)
antibiotics # A tibble: 420 x 18
-# Dataset with bacteria codes and properties like gram stain and aerobic/anaerobic
+# Dataset with bacteria codes and properties like gram stain and
+# aerobic/anaerobic
microorganisms # A tibble: 2,453 x 12
```
diff --git a/man/EUCAST.Rd b/man/EUCAST.Rd
index 40c51d84..95c5baa4 100644
--- a/man/EUCAST.Rd
+++ b/man/EUCAST.Rd
@@ -50,6 +50,7 @@ table with edited variables of antibiotics.
Apply expert rules (like intrinsic resistance), as defined by the European Committee on Antimicrobial Susceptibility Testing (EUCAST, \url{http://eucast.org}), see \emph{Source}.
}
\examples{
+a <- EUCAST_rules(septic_patients)
a <- data.frame(bactid = c("STAAUR", # Staphylococcus aureus
"ENCFAE", # Enterococcus faecalis
"ESCCOL", # Escherichia coli
diff --git a/man/figures/combi_therapy_2.png b/man/figures/combi_therapy_2.png
new file mode 100644
index 00000000..c76fbb2a
Binary files /dev/null and b/man/figures/combi_therapy_2.png differ
diff --git a/man/figures/combi_therapy_3.png b/man/figures/combi_therapy_3.png
new file mode 100644
index 00000000..a5f7e030
Binary files /dev/null and b/man/figures/combi_therapy_3.png differ
diff --git a/man/figures/mono_therapy.png b/man/figures/mono_therapy.png
new file mode 100644
index 00000000..f0e14a7c
Binary files /dev/null and b/man/figures/mono_therapy.png differ
diff --git a/man/rsi.Rd b/man/rsi.Rd
index d3b12765..e0da2ee9 100644
--- a/man/rsi.Rd
+++ b/man/rsi.Rd
@@ -2,49 +2,106 @@
% Please edit documentation in R/rsi_analysis.R
\name{rsi}
\alias{rsi}
+\alias{rsi_df}
+\alias{n_rsi}
\title{Resistance of isolates}
\usage{
-rsi(ab1, ab2 = NA, interpretation = "IR", minimum = 30, percent = FALSE,
- info = FALSE, warning = FALSE)
+rsi(ab1, ab2 = NA, interpretation = "IR", minimum = 30,
+ as_percent = FALSE, info = FALSE, warning = TRUE)
+
+rsi_df(tbl, ab, interpretation = "IR", minimum = 30, as_percent = FALSE,
+ info = TRUE, warning = TRUE)
+
+n_rsi(ab1, ab2 = NA)
}
\arguments{
-\item{ab1, ab2}{list with interpretations of an antibiotic}
+\item{ab1, ab2}{vector of antibiotic interpretations, they will be transformed internally with \code{\link{as.rsi}}}
\item{interpretation}{antimicrobial interpretation of which the portion must be calculated. Valid values are \code{"S"}, \code{"SI"}, \code{"I"}, \code{"IR"} or \code{"R"}.}
\item{minimum}{minimal amount of available isolates. Any number lower than \code{minimum} will return \code{NA} with a warning (when \code{warning = TRUE}).}
-\item{percent}{return output as percent (text), will else (at default) be a double}
+\item{as_percent}{return output as percent (text), will else (at default) be a double}
\item{info}{calculate the amount of available isolates and print it, like \code{n = 423}}
\item{warning}{show a warning when the available amount of isolates is below \code{minimum}}
+
+\item{tbl}{\code{data.frame} containing columns with antibiotic interpretations.}
+
+\item{ab}{character vector with 1, 2 or 3 antibiotics that occur as column names in \code{tbl}, like \code{ab = c("amox", "amcl")}}
}
\value{
-Double or, when \code{percent = TRUE}, a character.
+Double or, when \code{as_percent = TRUE}, a character.
}
\description{
-This function can be used in \code{dplyr}s \code{\link[dplyr]{summarise}}, see \emph{Examples}. Calculate the percentage S, SI, I, IR or R of a vector of isolates.
+This functions can be used to calculate the (co-)resistance of isolates (i.e. percentage S, SI, I, IR or R [of a vector] of isolates). The functions \code{rsi} and \code{n_rsi} can be used in \code{dplyr}s \code{\link[dplyr]{summarise}} and support grouped variables, see \emph{Examples}.
}
\details{
-This function uses the \code{\link{rsi_df}} function internally.
+Remember that you should filter your table to let it contain \strong{only first isolates}!
+
+To calculate the probability (\emph{p}) of susceptibility of one antibiotic, we use this formula:
+\if{html}{
+ \out{}\figure{mono_therapy.png}\out{
}
+}
+\if{latex}{
+ \deqn{p = \frac{\sum{ab1_S}}{\sum{ab1_{R|I|S}}}}
+}
+\cr
+To calculate the probability (\emph{p}) of susceptibility of more antibiotics a combination therapy, we need to check whether one of them has a susceptible result (as numerator) and count all cases where all antibiotics were tested (as denominator). \cr
+For two antibiotics:
+\if{html}{
+ \out{}\figure{combi_therapy_2.png}\out{
}
+}
+\if{latex}{
+ \deqn{p = \frac{\sum{ab1_S}\mid{ab2_S}}{\sum{ab1_{R|I|S},ab2_{R|I|S}}}}
+}
+\cr
+For three antibiotics:
+\if{html}{
+ \out{}\figure{combi_therapy_3.png}\out{
}
+}
+\if{latex}{
+ \deqn{p = \frac{\sum{ab1_S}\mid{ab2_S}\mid{ab3_S}}{\sum{ab1_{R|I|S},ab2_{R|I|S},ab3_{R|I|S}}}}
+}
}
\examples{
+library(dplyr)
+
+septic_patients \%>\%
+ group_by(hospital_id) \%>\%
+ summarise(cipro_susceptibility = rsi(cipr, interpretation = "S"),
+ n = n_rsi(cipr)) # n_rsi works like n_distinct in dplyr
+
+septic_patients \%>\%
+ group_by(hospital_id) \%>\%
+ summarise(cipro_S = rsi(cipr, interpretation = "S",
+ as_percent = TRUE, warning = FALSE),
+ cipro_n = n_rsi(cipr),
+ genta_S = rsi(gent, interpretation = "S",
+ as_percent = TRUE, warning = FALSE),
+ genta_n = n_rsi(gent),
+ combination_S = rsi(cipr, gent, interpretation = "S",
+ as_percent = TRUE, warning = FALSE),
+ combination_n = n_rsi(cipr, gent))
+
+# calculate resistance
+rsi(septic_patients$amox)
+# or susceptibility
+rsi(septic_patients$amox, interpretation = "S")
+
+# calculate co-resistance between amoxicillin/clav acid and gentamicin,
+# so we can review that combination therapy does a lot more than mono therapy:
+septic_patients \%>\% rsi_df(ab = "amcl", interpretation = "S") # = 67.8\%
+septic_patients \%>\% rsi_df(ab = "gent", interpretation = "S") # = 69.1\%
+septic_patients \%>\% rsi_df(ab = c("amcl", "gent"), interpretation = "S") # = 90.6\%
+
\dontrun{
-tbl \%>\%
- group_by(hospital) \%>\%
- summarise(cipr = rsi(cipr))
-
-tbl \%>\%
- group_by(year, hospital) \%>\%
- summarise(
- isolates = n(),
- cipro = rsi(cipr \%>\% as.rsi(), percent = TRUE),
- amoxi = rsi(amox \%>\% as.rsi(), percent = TRUE))
-
-rsi(as.rsi(isolates$amox))
-
-rsi(as.rsi(isolates$amcl), interpretation = "S")
+# calculate current empiric combination therapy of Helicobacter gastritis:
+my_table \%>\%
+ filter(first_isolate == TRUE,
+ genus == "Helicobacter") \%>\%
+ rsi_df(ab = c("amox", "metr")) # amoxicillin with metronidazole
}
}
\keyword{antibiotics}
diff --git a/man/rsi_df.Rd b/man/rsi_df.Rd
deleted file mode 100644
index af883915..00000000
--- a/man/rsi_df.Rd
+++ /dev/null
@@ -1,54 +0,0 @@
-% Generated by roxygen2: do not edit by hand
-% Please edit documentation in R/rsi_analysis.R
-\name{rsi_df}
-\alias{rsi_df}
-\title{Resistance of isolates in data.frame}
-\usage{
-rsi_df(tbl, ab, interpretation = "IR", minimum = 30, percent = FALSE,
- info = TRUE, warning = TRUE)
-}
-\arguments{
-\item{tbl}{\code{data.frame} containing columns with antibiotic interpretations.}
-
-\item{ab}{character vector with 1, 2 or 3 antibiotics that occur as column names in \code{tbl}, like \code{ab = c("amox", "amcl")}}
-
-\item{interpretation}{antimicrobial interpretation of which the portion must be calculated. Valid values are \code{"S"}, \code{"SI"}, \code{"I"}, \code{"IR"} or \code{"R"}.}
-
-\item{minimum}{minimal amount of available isolates. Any number lower than \code{minimum} will return \code{NA} with a warning (when \code{warning = TRUE}).}
-
-\item{percent}{return output as percent (text), will else (at default) be a double}
-
-\item{info}{calculate the amount of available isolates and print it, like \code{n = 423}}
-
-\item{warning}{show a warning when the available amount of isolates is below \code{minimum}}
-}
-\value{
-Double or, when \code{percent = TRUE}, a character.
-}
-\description{
-\strong{NOTE: use \code{\link{rsi}} in dplyr functions like \code{\link[dplyr]{summarise}}.} \cr Calculate the percentage of S, SI, I, IR or R of a \code{data.frame} containing isolates.
-}
-\details{
-Remember that you should filter your table to let it contain \strong{only first isolates}!
-}
-\examples{
-\dontrun{
-rsi_df(tbl_with_bloodcultures, 'amcl')
-
-rsi_df(tbl_with_bloodcultures, c('amcl', 'gent'), interpretation = 'IR')
-
-library(dplyr)
-# calculate current empiric therapy of Helicobacter gastritis:
-my_table \%>\%
- filter(first_isolate == TRUE,
- genus == "Helicobacter") \%>\%
- rsi_df(ab = c("amox", "metr"))
-}
-}
-\seealso{
-\code{\link{rsi}} for the function that can be used with \code{\link[dplyr]{summarise}} directly.
-}
-\keyword{antibiotics}
-\keyword{isolate}
-\keyword{isolates}
-\keyword{rsi}
diff --git a/tests/testthat/test-eucast.R b/tests/testthat/test-eucast.R
index c52b5a6c..a7d8a0e1 100644
--- a/tests/testthat/test-eucast.R
+++ b/tests/testthat/test-eucast.R
@@ -1,6 +1,8 @@
context("eucast.R")
test_that("EUCAST rules work", {
+ a <- EUCAST_rules(septic_patients)
+
a <- data.frame(bactid = c("KLEPNE", # Klebsiella pneumoniae
"PSEAER", # Pseudomonas aeruginosa
"ENTAER"), # Enterobacter aerogenes
diff --git a/tests/testthat/test-rsi_analysis.R b/tests/testthat/test-rsi_analysis.R
index 1d5e48b3..3077987f 100644
--- a/tests/testthat/test-rsi_analysis.R
+++ b/tests/testthat/test-rsi_analysis.R
@@ -29,6 +29,21 @@ test_that("rsi works", {
info = FALSE),
0.9858,
tolerance = 0.0001)
+
+ # count of cases
+ expect_equal(septic_patients %>%
+ group_by(hospital_id) %>%
+ summarise(cipro_S = rsi(cipr, interpretation = "S",
+ as_percent = TRUE, warning = FALSE),
+ cipro_n = n_rsi(cipr),
+ genta_S = rsi(gent, interpretation = "S",
+ as_percent = TRUE, warning = FALSE),
+ genta_n = n_rsi(gent),
+ combination_S = rsi(cipr, gent, interpretation = "S",
+ as_percent = TRUE, warning = FALSE),
+ combination_n = n_rsi(cipr, gent)) %>%
+ pull(combination_n),
+ c(138, 474, 170, 464, 183))
})
test_that("prediction of rsi works", {