From d9e204031d6bf1715ae0972e23acdd3bc0add909 Mon Sep 17 00:00:00 2001 From: "Matthijs S. Berends" Date: Wed, 25 Jul 2018 14:17:04 +0200 Subject: [PATCH] update to septic_patients, speed improvements --- DESCRIPTION | 4 +- NAMESPACE | 1 - NEWS.md | 7 +- R/bactid.R | 1 - R/classes.R | 16 ++-- R/data.R | 24 ++--- R/first_isolate.R | 25 +++++- R/freq.R | 3 - R/join_microorganisms.R | 24 ++--- R/key_antibiotics.R | 132 ++++++++++++++-------------- README.md | 108 ++++++++++++----------- data/septic_patients.rda | Bin 35508 -> 30732 bytes man/as.mic.Rd | 9 +- man/as.rsi.Rd | 7 +- man/first_isolate.Rd | 20 ++++- man/key_antibiotics.Rd | 29 +++--- man/microorganisms.Rd | 3 - man/microorganisms.umcg.Rd | 3 - man/septic_patients.Rd | 21 ++--- tests/testthat/test-bactid.R | 4 +- tests/testthat/test-first_isolate.R | 16 ++-- tests/testthat/test-freq.R | 4 +- tests/testthat/test-kurtosis.R | 6 +- tests/testthat/test-mdro.R | 3 +- tests/testthat/test-resistance.R | 30 +++---- tests/testthat/test-skewness.R | 6 +- 26 files changed, 273 insertions(+), 233 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index b28deb19..55fc3de8 100755 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: AMR -Version: 0.2.0.9015 -Date: 2018-07-23 +Version: 0.2.0.9016 +Date: 2018-07-25 Title: Antimicrobial Resistance Analysis Authors@R: c( person( diff --git a/NAMESPACE b/NAMESPACE index 60753e49..e2927e21 100755 --- a/NAMESPACE +++ b/NAMESPACE @@ -154,7 +154,6 @@ importFrom(utils,View) importFrom(utils,browseVignettes) importFrom(utils,installed.packages) importFrom(utils,object.size) -importFrom(utils,packageDescription) importFrom(utils,read.delim) importFrom(utils,write.table) importFrom(xml2,read_html) diff --git a/NEWS.md b/NEWS.md index 850c2a17..19eae140 100755 --- a/NEWS.md +++ b/NEWS.md @@ -2,8 +2,9 @@ #### New * **BREAKING**: `rsi_df` was removed in favour of new functions `resistance` and `susceptibility`. Now, all functions used to calculate resistance (`resistance` and `susceptibility`) use **hybrid evaluation**. This means calculations are not done in R directly but rather in C++ using the `Rcpp` package, making them 25 to 30 times faster. The function `rsi` still works, but is deprecated. * **BREAKING**: the methodology for determining first weighted isolates was changed. The antibiotics that are compared between isolates (call *key antibiotics*) to include more first isolates (afterwards called first *weighted* isolates) are now as follows: - * Gram-positive: amoxicillin, amoxicillin/clavlanic acid, cefuroxime, piperacillin/tazobactam, ciprofloxacin, trimethoprim/sulfamethoxazole, vancomycin, teicoplanin, tetracycline, erythromycin, oxacillin, rifampicin - * Gram-negative: amoxicillin, amoxicillin/clavlanic acid, cefuroxime, piperacillin/tazobactam, ciprofloxacin, trimethoprim/sulfamethoxazole, gentamicin, tobramycin, colistin, cefotaxime, ceftazidime, meropenem + * Universal: amoxicillin, amoxicillin/clavlanic acid, cefuroxime, piperacillin/tazobactam, ciprofloxacin, trimethoprim/sulfamethoxazole + * Gram-positive: vancomycin, teicoplanin, tetracycline, erythromycin, oxacillin, rifampicin + * Gram-negative: gentamicin, tobramycin, colistin, cefotaxime, ceftazidime, meropenem * Functions `as.bactid` and `is.bactid` to transform/look up microbial ID's; this replaces the function `guess_bactid` but it will remain available for backwards compatibility * For convience, new descriptive statistical functions `kurtosis` and `skewness` that are lacking in base R - they are generic functions and have support for vectors, data.frames and matrices * Function `g.test` to perform the Χ2 distributed [*G*-test](https://en.wikipedia.org/wiki/G-test), which use is the same as `chisq.test` @@ -23,6 +24,7 @@ * Possibility to globally set the default for the amount of items to print, with `options(max.print.freq = n)` where *n* is your preset value #### Changed +* Updates version of the `setic_patients` dataset to better reflect the reality * Pretty printing for tibbles removed as it is not really the scope of this package * Improved speed of key antibiotics comparison for determining first isolates * Column names for the `key_antibiotics` function are now generic: 6 for broadspectrum ABs, 6 for Gram-positive specific and 6 for Gram-negative specific ABs @@ -36,6 +38,7 @@ * `as.rsi("<=0.002; S")` will return `S` * `as.mic("<=0.002; S")` will return `<=0.002` * Now possible to coerce MIC values with a space between operator and value, i.e. `as.mic("<= 0.002")` now works +* Classes `rsi` and `mic` do not add the attribute `package.version` anymore * Added `"groups"` option for `atc_property(..., property)`. It will return a vector of the ATC hierarchy as defined by the [WHO](https://www.whocc.no/atc/structure_and_principles/). The new function `atc_groups` is a convenient wrapper around this. * Build-in host check for `atc_property` as it requires the host set by `url` to be responsive * Improved `first_isolate` algorithm to exclude isolates where bacteria ID or genus is unavailable diff --git a/R/bactid.R b/R/bactid.R index 93c10e7f..c91a30c2 100644 --- a/R/bactid.R +++ b/R/bactid.R @@ -221,7 +221,6 @@ as.bactid <- function(x) { } class(x) <- "bactid" attr(x, 'package') <- 'AMR' - attr(x, 'package.version') <- packageDescription('AMR')$Version x } diff --git a/R/classes.R b/R/classes.R index 14fcf66d..e75ee0e3 100755 --- a/R/classes.R +++ b/R/classes.R @@ -21,18 +21,18 @@ #' This transforms a vector to a new class \code{rsi}, which is an ordered factor with levels \code{S < I < R}. Invalid antimicrobial interpretations will be translated as \code{NA} with a warning. #' @rdname as.rsi #' @param x vector -#' @return Ordered factor with new class \code{rsi} and new attributes \code{package} and \code{package.version} +#' @return Ordered factor with new class \code{rsi} and new attribute \code{package} #' @keywords rsi #' @export #' @importFrom dplyr %>% -#' @importFrom utils packageDescription +#' @seealso \code{\link{as.mic}} #' @examples #' rsi_data <- as.rsi(c(rep("S", 474), rep("I", 36), rep("R", 370))) #' rsi_data <- as.rsi(c(rep("S", 474), rep("I", 36), rep("R", 370), "A", "B", "C")) #' is.rsi(rsi_data) #' #' # this can also coerce combined MIC/RSI values: -#' as.rsi("<= 0.002; R") # will return R +#' as.rsi("<= 0.002; S") # will return S #' #' plot(rsi_data) # for percentages #' barplot(rsi_data) # for frequencies @@ -76,7 +76,6 @@ as.rsi <- function(x) { x <- x %>% factor(levels = c("S", "I", "R"), ordered = TRUE) class(x) <- c('rsi', 'ordered', 'factor') attr(x, 'package') <- 'AMR' - attr(x, 'package.version') <- packageDescription('AMR')$Version x } } @@ -196,21 +195,21 @@ barplot.rsi <- function(height, ...) { #' Class 'mic' #' -#' This transforms a vector to a new class\code{mic}, which is an ordered factor with valid MIC values as levels. Invalid MIC values will be translated as \code{NA} with a warning. +#' This transforms a vector to a new class \code{mic}, which is an ordered factor with valid MIC values as levels. Invalid MIC values will be translated as \code{NA} with a warning. #' @rdname as.mic #' @param x vector #' @param na.rm a logical indicating whether missing values should be removed -#' @return Ordered factor with new class \code{mic} and new attributes \code{package} and \code{package.version} +#' @return Ordered factor with new class \code{mic} and new attribute \code{package} #' @keywords mic #' @export #' @importFrom dplyr %>% -#' @importFrom utils packageDescription +#' @seealso \code{\link{as.rsi}} #' @examples #' mic_data <- as.mic(c(">=32", "1.0", "1", "1.00", 8, "<=0.128", "8", "16", "16")) #' is.mic(mic_data) #' #' # this can also coerce combined MIC/RSI values: -#' as.mic("<=0.002; R") # will return <=0.002 +#' as.mic("<=0.002; S") # will return <=0.002 #' #' plot(mic_data) #' barplot(mic_data) @@ -319,7 +318,6 @@ as.mic <- function(x, na.rm = FALSE) { ordered = TRUE) class(x) <- c('mic', 'ordered', 'factor') attr(x, 'package') <- 'AMR' - attr(x, 'package.version') <- packageDescription('AMR')$Version x } } diff --git a/R/data.R b/R/data.R index 8f6a0291..a83b798c 100755 --- a/R/data.R +++ b/R/data.R @@ -252,7 +252,7 @@ #' \item{\code{type_nl}}{Type of microorganism in Dutch, like \code{"Bacterie"} and \code{"Schimmel/gist"}} #' \item{\code{gramstain_nl}}{Gram of microorganism in Dutch, like \code{"Negatieve staven"}} #' } -#' @source MOLIS (LIS of Certe) - \url{https://www.certe.nl} +# source MOLIS (LIS of Certe) - \url{https://www.certe.nl} #' @seealso \code{\link{guess_bactid}} \code{\link{antibiotics}} \code{\link{microorganisms.umcg}} "microorganisms" @@ -264,14 +264,14 @@ #' \item{\code{mocode}}{Code of microorganism according to UMCG MMB} #' \item{\code{bactid}}{Code of microorganism in \code{\link{microorganisms}}} #' } -#' @source MOLIS (LIS of Certe) - \url{https://www.certe.nl} \cr \cr GLIMS (LIS of UMCG) - \url{https://www.umcg.nl} +# source MOLIS (LIS of Certe) - \url{https://www.certe.nl} \cr \cr GLIMS (LIS of UMCG) - \url{https://www.umcg.nl} #' @seealso \code{\link{guess_bactid}} \code{\link{microorganisms}} "microorganisms.umcg" #' Dataset with 2000 blood culture isolates of septic patients #' #' An anonymised dataset containing 2000 microbial blood culture isolates with their antibiogram of septic patients found in 5 different hospitals in the Netherlands, between 2001 and 2017. This data.frame can be used to practice AMR analysis. For examples, press F1. -#' @format A data.frame with 2000 observations and 47 variables: +#' @format A data.frame with 2000 observations and 49 variables: #' \describe{ #' \item{\code{date}}{date of receipt at the laboratory} #' \item{\code{hospital_id}}{ID of the hospital} @@ -282,9 +282,9 @@ #' \item{\code{sex}}{sex of the patient} #' \item{\code{patient_id}}{ID of the patient, first 10 characters of an SHA hash containing irretrievable information} #' \item{\code{bactid}}{ID of microorganism, see \code{\link{microorganisms}}} -#' \item{\code{peni:mupi}}{38 different antibiotics with class \code{rsi} (see \code{\link{as.rsi}}); these column names occur in \code{\link{antibiotics}} and can be translated with \code{\link{abname}}} +#' \item{\code{peni:rifa}}{40 different antibiotics with class \code{rsi} (see \code{\link{as.rsi}}); these column names occur in \code{\link{antibiotics}} data set and can be translated with \code{\link{abname}}} #' } -#' @source MOLIS (LIS of Certe) - \url{https://www.certe.nl} +# source MOLIS (LIS of Certe) - \url{https://www.certe.nl} #' @examples #' # ----------- # #' # PREPARATION # @@ -304,15 +304,15 @@ #' # ANALYSIS # #' # -------- # #' -#' # 1. Get the amoxicillin resistance percentages -#' # of E. coli, divided by hospital: +#' # 1. Get the amoxicillin resistance percentages (p) +#' # and numbers (n) of E. coli, divided by hospital: #' #' my_data %>% -#' filter(bactid == "ESCCOL", +#' filter(bactid == guess_bactid("E. coli"), #' first_isolates == TRUE) %>% #' group_by(hospital_id) %>% -#' summarise(n = n(), -#' amoxicillin_resistance = rsi(amox)) +#' summarise(n = n_rsi(amox), +#' p = resistance(amox)) #' #' #' # 2. Get the amoxicillin/clavulanic acid resistance @@ -322,6 +322,6 @@ #' filter(bactid == guess_bactid("E. coli"), #' first_isolates == TRUE) %>% #' group_by(year = format(date, "%Y")) %>% -#' summarise(n = n(), -#' amoxclav_resistance = rsi(amcl, minimum = 20)) +#' summarise(n = n_rsi(amcl), +#' p = resistance(amcl, minimum = 20)) "septic_patients" diff --git a/R/first_isolate.R b/R/first_isolate.R index fd97bcf4..ca07f1d4 100755 --- a/R/first_isolate.R +++ b/R/first_isolate.R @@ -41,7 +41,7 @@ #' @details \strong{WHY THIS IS SO IMPORTANT} \cr #' To conduct an analysis of antimicrobial resistance, you should only include the first isolate of every patient per episode \href{https://www.ncbi.nlm.nih.gov/pubmed/17304462}{[1]}. If you would not do this, you could easily get an overestimate or underestimate of the resistance of an antibiotic. Imagine that a patient was admitted with an MRSA and that it was found in 5 different blood cultures the following week. The resistance percentage of oxacillin of all \emph{S. aureus} isolates would be overestimated, because you included this MRSA more than once. It would be \href{https://en.wikipedia.org/wiki/Selection_bias}{selection bias}. #' @section Key antibiotics: -#' There are two ways to determine whether isolates can be included as first \emph{weighted} isolates: \cr +#' There are two ways to determine whether isolates can be included as first \emph{weighted} isolates which will give generally the same results: \cr #' #' \strong{1. Using} \code{type = "keyantibiotics"} \strong{and parameter} \code{ignore_I} \cr #' Any difference from S to R (or vice versa) will (re)select an isolate as a first weighted isolate. With \code{ignore_I = FALSE}, also differences from I to S|R (or vice versa) will lead to this. This is a reliable method and 30-35 times faster than method 2. \cr @@ -65,6 +65,24 @@ #' col_patient_id = "patient_id", #' col_bactid = "bactid") #' +#' # Now let's see if first isolates matter: +#' A <- my_patients %>% +#' group_by(hospital_id) %>% +#' summarise(count = n_rsi(gent), # gentamicin +#' resistance = resistance(gent)) +#' +#' B <- my_patients %>% +#' filter(first_isolate == TRUE) %>% +#' group_by(hospital_id) %>% +#' summarise(count = n_rsi(gent), # gentamicin +#' resistance = resistance(gent)) +#' +#' # Have a look at A and B. B is more reliable because every isolate is +#' # counted once. Gentamicin resitance in hospital D seems to be 5% +#' # higher than originally thought. +#' +#' ## OTHER EXAMPLES: +#' #' \dontrun{ #' #' # set key antibiotics to a new variable @@ -153,7 +171,7 @@ first_isolate <- function(tbl, if (!is.na(col_bactid)) { if (!tbl %>% pull(col_bactid) %>% is.bactid()) { - tbl[, col_bactid] <- tbl %>% pull(col_bactid) %>% as.bactid() + warning("Improve integrity of the `", col_bactid, "` column by transforming it with 'as.bactid'.") } tbl <- tbl %>% left_join_microorganisms(by = col_bactid) col_genus <- "genus" @@ -179,7 +197,6 @@ first_isolate <- function(tbl, filter_specimen <- '' } - weighted.notice <- '' # filter on specimen group and keyantibiotics when they are filled in if (!is.na(filter_specimen) & filter_specimen != '') { check_columns_existance(col_specimen, tbl) @@ -317,7 +334,9 @@ first_isolate <- function(tbl, (date_lab - lag(date_lab)) + lag(days_diff), 0)) + weighted.notice <- '' if (col_keyantibiotics != '') { + weighted.notice <- 'weighted ' if (info == TRUE) { if (type == 'keyantibiotics') { cat('[Criteria] Inclusion based on key antibiotics, ') diff --git a/R/freq.R b/R/freq.R index 17cfab5a..6c37a6fe 100755 --- a/R/freq.R +++ b/R/freq.R @@ -415,7 +415,6 @@ frequency_tbl <- function(x, class(df) <- c('frequency_tbl', class(df)) attr(df, 'package') <- 'AMR' - attr(df, 'package.version') <- packageDescription('AMR')$Version if (markdown == TRUE) { tbl_format <- 'markdown' @@ -567,7 +566,6 @@ print.frequency_tbl <- function(x, nmax = getOption("max.print.freq", default = #' @export as.data.frame.frequency_tbl <- function(x, ...) { attr(x, 'package') <- NULL - attr(x, 'package.version') <- NULL attr(x, 'opt') <- NULL as.data.frame.data.frame(x, ...) } @@ -578,7 +576,6 @@ as.data.frame.frequency_tbl <- function(x, ...) { #' @importFrom dplyr as_tibble as_tibble.frequency_tbl <- function(x, validate = TRUE, ..., rownames = NA) { attr(x, 'package') <- NULL - attr(x, 'package.version') <- NULL attr(x, 'opt') <- NULL as_tibble(x = as.data.frame(x), validate = validate, ..., rownames = rownames) } diff --git a/R/join_microorganisms.R b/R/join_microorganisms.R index 3cdaa276..dd19c16b 100755 --- a/R/join_microorganisms.R +++ b/R/join_microorganisms.R @@ -26,8 +26,8 @@ #' df2 <- left_join_microorganisms(df, "bacteria_id") #' colnames(df2) inner_join_microorganisms <- function(x, by = 'bactid', suffix = c("2", ""), ...) { - if (!any(class(x) %in% c("bactid", "data.frame", "matrix"))) { - x <- data.frame(bactid = as.bactid(x), stringsAsFactors = FALSE) + if (!any(class(x) %in% c("data.frame", "matrix"))) { + x <- data.frame(bactid = as.character(x), stringsAsFactors = FALSE) } # no name set to `by` parameter if (is.null(names(by))) { @@ -48,8 +48,8 @@ inner_join_microorganisms <- function(x, by = 'bactid', suffix = c("2", ""), ... #' @rdname join #' @export left_join_microorganisms <- function(x, by = 'bactid', suffix = c("2", ""), ...) { - if (!any(class(x) %in% c("bactid", "data.frame", "matrix"))) { - x <- data.frame(bactid = as.bactid(x), stringsAsFactors = FALSE) + if (!any(class(x) %in% c("data.frame", "matrix"))) { + x <- data.frame(bactid = as.character(x), stringsAsFactors = FALSE) } # no name set to `by` parameter if (is.null(names(by))) { @@ -70,8 +70,8 @@ left_join_microorganisms <- function(x, by = 'bactid', suffix = c("2", ""), ...) #' @rdname join #' @export right_join_microorganisms <- function(x, by = 'bactid', suffix = c("2", ""), ...) { - if (!any(class(x) %in% c("bactid", "data.frame", "matrix"))) { - x <- data.frame(bactid = as.bactid(x), stringsAsFactors = FALSE) + if (!any(class(x) %in% c("data.frame", "matrix"))) { + x <- data.frame(bactid = as.character(x), stringsAsFactors = FALSE) } # no name set to `by` parameter if (is.null(names(by))) { @@ -92,8 +92,8 @@ right_join_microorganisms <- function(x, by = 'bactid', suffix = c("2", ""), ... #' @rdname join #' @export full_join_microorganisms <- function(x, by = 'bactid', suffix = c("2", ""), ...) { - if (!any(class(x) %in% c("bactid", "data.frame", "matrix"))) { - x <- data.frame(bactid = as.bactid(x), stringsAsFactors = FALSE) + if (!any(class(x) %in% c("data.frame", "matrix"))) { + x <- data.frame(bactid = as.character(x), stringsAsFactors = FALSE) } # no name set to `by` parameter if (is.null(names(by))) { @@ -114,8 +114,8 @@ full_join_microorganisms <- function(x, by = 'bactid', suffix = c("2", ""), ...) #' @rdname join #' @export semi_join_microorganisms <- function(x, by = 'bactid', ...) { - if (!any(class(x) %in% c("bactid", "data.frame", "matrix"))) { - x <- data.frame(bactid = as.bactid(x), stringsAsFactors = FALSE) + if (!any(class(x) %in% c("data.frame", "matrix"))) { + x <- data.frame(bactid = as.character(x), stringsAsFactors = FALSE) } # no name set to `by` parameter if (is.null(names(by))) { @@ -132,8 +132,8 @@ semi_join_microorganisms <- function(x, by = 'bactid', ...) { #' @rdname join #' @export anti_join_microorganisms <- function(x, by = 'bactid', ...) { - if (!any(class(x) %in% c("bactid", "data.frame", "matrix"))) { - x <- data.frame(bactid = as.bactid(x), stringsAsFactors = FALSE) + if (!any(class(x) %in% c("data.frame", "matrix"))) { + x <- data.frame(bactid = as.character(x), stringsAsFactors = FALSE) } # no name set to `by` parameter if (is.null(names(by))) { diff --git a/R/key_antibiotics.R b/R/key_antibiotics.R index 3b391fb1..6e04a260 100644 --- a/R/key_antibiotics.R +++ b/R/key_antibiotics.R @@ -42,19 +42,26 @@ #' @importFrom dplyr %>% mutate if_else #' @seealso \code{\link{first_isolate}} #' @examples -#' \dontrun{ +#' # septic_patients is a dataset available in the AMR package +#' ?septic_patients +#' my_patients <- septic_patients +#' +#' library(dplyr) #' # set key antibiotics to a new variable -#' tbl$keyab <- key_antibiotics(tbl) +#' my_patients <- my_patients %>% +#' mutate(keyab = key_antibiotics(.)) %>% +#' mutate( +#' # now calculate first isolates +#' first_regular = first_isolate(., "date", "patient_id", "bactid"), +#' # and first WEIGHTED isolates +#' first_weighted = first_isolate(., "date", "patient_id", "bactid", +#' col_keyantibiotics = "keyab") +#' ) #' -#' # add regular first isolates -#' tbl$first_isolate <- -#' first_isolate(tbl) +#' # Check the difference, in this data set it results in 7% more isolates: +#' sum(my_patients$first_regular, na.rm = TRUE) +#' sum(my_patients$first_weighted, na.rm = TRUE) #' -#' # add first WEIGHTED isolates using key antibiotics -#' tbl$first_isolate_weighed <- -#' first_isolate(tbl, -#' col_keyantibiotics = 'keyab') -#' } #' #' # output of the `key_antibiotics` function could be like this: #' strainA <- "SSSRR.S.R..S" @@ -169,87 +176,80 @@ key_antibiotics_equal <- function(x, points_threshold = 2, info = FALSE) { # x is active row, y is lag + type <- type[1] if (length(x) != length(y)) { stop('Length of `x` and `y` must be equal.') } + # only show progress bar on points or when at least 5000 isolates + info_needed <- info == TRUE & (type == "points" | length(x) > 5000) + result <- logical(length(x)) - if (type == "keyantibiotics") { - if (ignore_I == TRUE) { - # evaluation using regular expression will treat '.' as any character - # so I is actually ignored then - x <- gsub('I', '.', x, ignore.case = TRUE) - y <- gsub('I', '.', y, ignore.case = TRUE) + if (info_needed == TRUE) { + p <- dplyr::progress_estimated(length(x)) + } + + for (i in 1:length(x)) { + + if (info_needed == TRUE) { + p$tick()$print() } - for (i in 1:length(x)) { + if (is.na(x[i])) { + x[i] <- '' + } + if (is.na(y[i])) { + y[i] <- '' + } + + if (x[i] == y[i]) { + + result[i] <- TRUE + + } else if (nchar(x[i]) != nchar(y[i])) { + + result[i] <- FALSE + + } else { + x_split <- strsplit(x[i], "")[[1]] y_split <- strsplit(y[i], "")[[1]] - y_split[x_split == "."] <- "." - x_split[y_split == "."] <- "." - x_checkfor <- paste(x_split, collapse = "") - y_checkfor <- paste(y_split, collapse = "") - result[i] <- nchar(x[i]) == nchar(y[i]) & - (x_checkfor %like% y_checkfor | - y_checkfor %like% x_checkfor) - } - return(result) - } else { + if (type == 'keyantibiotics') { - if (type != 'points') { - stop('`', type, '` is not a valid value for type, must be "points" or "keyantibiotics". See ?first_isolate.') - } + if (ignore_I == TRUE) { + x_split[x_split == "I"] <- "." + y_split[y_split == "I"] <- "." + } - if (info == TRUE) { - p <- dplyr::progress_estimated(length(x)) - } + y_split[x_split == "."] <- "." + x_split[y_split == "."] <- "." - for (i in 1:length(x)) { - - if (info == TRUE) { - p$tick()$print() - } - - if (is.na(x[i])) { - x[i] <- '' - } - if (is.na(y[i])) { - y[i] <- '' - } - - if (nchar(x[i]) != nchar(y[i])) { - - result[i] <- FALSE - - } else if (x[i] == '' & y[i] == '') { - - result[i] <- TRUE - - } else { - - x2 <- strsplit(x[i], "")[[1]] - y2 <- strsplit(y[i], "")[[1]] + result[i] <- all(x_split == y_split) + } else if (type == 'points') { # count points for every single character: # - no change is 0 points # - I <-> S|R is 0.5 point # - S|R <-> R|S is 1 point # use the levels of as.rsi (S = 1, I = 2, R = 3) - suppressWarnings(x2 <- x2 %>% as.rsi() %>% as.double()) - suppressWarnings(y2 <- y2 %>% as.rsi() %>% as.double()) + suppressWarnings(x_split <- x_split %>% as.rsi() %>% as.double()) + suppressWarnings(y_split <- y_split %>% as.rsi() %>% as.double()) - points <- (x2 - y2) %>% abs() %>% sum(na.rm = TRUE) - result[i] <- ((points / 2) >= points_threshold) + points <- (x_split - y_split) %>% abs() %>% sum(na.rm = TRUE) / 2 + result[i] <- points >= points_threshold + + } else { + stop('`', type, '` is not a valid value for type, must be "points" or "keyantibiotics". See ?first_isolate.') } } - if (info == TRUE) { - cat('\n') - } - result } + if (info_needed == TRUE) { + cat('\n') + } + result } diff --git a/README.md b/README.md index 1e9c5920..ec3d16bf 100755 --- a/README.md +++ b/README.md @@ -26,9 +26,13 @@ This R package contains functions to make **microbiological, epidemiological dat With `AMR` you can: * Calculate the resistance (and even co-resistance) of microbial isolates with the `resistance` and `susceptibility` functions, that can also be used with the `dplyr` package (e.g. in conjunction with `summarise`) -* Predict antimicrobial resistance for the nextcoming years with the `rsi_predict` function +* Predict antimicrobial resistance for the nextcoming years with the `resistance_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 + * You can also identify first *weighted* isolates of every patient, an adjusted version of the CLSI guideline. This takes into account key antibiotics of every strain and compares them. The following 12 antibiotics will be used as key antibiotics at default: + * Universal: amoxicillin, amoxicillin/clavlanic acid, cefuroxime, piperacillin/tazobactam, ciprofloxacin, trimethoprim/sulfamethoxazole + * Specific for Gram-positives: vancomycin, teicoplanin, tetracycline, erythromycin, oxacillin, rifampicin + * Specific for Gram-negatives: gentamicin, tobramycin, colistin, cefotaxime, ceftazidime, meropenem * Get antimicrobial ATC properties from the WHO Collaborating Centre for Drug Statistics Methodology ([WHOCC](https://www.whocc.no/atc_ddd_methodology/who_collaborating_centre/)), to be able to: * Translate antibiotic codes (like *AMOX*), official names (like *amoxicillin*) and even trade names (like *Amoxil* or *Trimox*) to an [ATC code](https://www.whocc.no/atc_ddd_index/?code=J01CA04&showdescription=no) (like *J01CA04*) and vice versa with the `abname` function * Get the latest antibiotic properties like hierarchic groups and [defined daily dose](https://en.wikipedia.org/wiki/Defined_daily_dose) (DDD) with units and administration form from the WHOCC website with the `atc_property` function @@ -219,35 +223,33 @@ mydata %>% freq(myvariable) Factors sort on item by default: ```r septic_patients %>% freq(hospital_id) -# Frequency table of `hospital_id` +# Frequency table of `hospital_id` # Class: factor # Length: 2000 (of which NA: 0 = 0.0%) -# Unique: 5 +# Unique: 4 # # Item Count Percent Cum. Count Cum. Percent (Factor Level) # --- ----- ------ -------- ----------- ------------- --------------- -# 1 A 233 11.7% 233 11.7% 1 -# 2 B 583 29.1% 816 40.8% 2 -# 3 C 221 11.1% 1037 51.8% 3 -# 4 D 650 32.5% 1687 84.4% 4 -# 5 E 313 15.7% 2000 100.0% 5 +# 1 A 319 16.0% 319 16.0% 1 +# 2 B 661 33.1% 980 49.0% 2 +# 3 C 256 12.8% 1236 61.8% 3 +# 4 D 764 38.2% 2000 100.0% 4 ``` This can be changed with the `sort.count` parameter: ```r septic_patients %>% freq(hospital_id, sort.count = TRUE) -# Frequency table of `hospital_id` +# Frequency table of `hospital_id` # Class: factor # Length: 2000 (of which NA: 0 = 0.0%) -# Unique: 5 +# Unique: 4 # # Item Count Percent Cum. Count Cum. Percent (Factor Level) # --- ----- ------ -------- ----------- ------------- --------------- -# 1 D 650 32.5% 650 32.5% 4 -# 2 B 583 29.1% 1233 61.7% 2 -# 3 E 313 15.7% 1546 77.3% 5 -# 4 A 233 11.7% 1779 88.9% 1 -# 5 C 221 11.1% 2000 100.0% 3 +# 1 D 764 38.2% 764 38.2% 4 +# 2 B 661 33.1% 1425 71.2% 2 +# 3 A 319 16.0% 1744 87.2% 1 +# 4 C 256 12.8% 2000 100.0% 3 ``` All other types, like numbers, characters and dates, sort on count by default: @@ -256,56 +258,56 @@ septic_patients %>% freq(date) # Frequency table of `date` # Class: Date # Length: 2000 (of which NA: 0 = 0.0%) -# Unique: 1662 +# Unique: 1151 # -# Oldest: 2 January 2001 -# Newest: 18 October 2017 (+6133) -# Median: 6 December 2009 (~53%) +# Oldest: 2 January 2002 +# Newest: 28 December 2017 (+5839) +# Median: 7 Augustus 2009 (~48%) # # Item Count Percent Cum. Count Cum. Percent # --- ----------- ------ -------- ----------- ------------- -# 1 2008-12-24 5 0.2% 5 0.2% -# 2 2010-12-10 4 0.2% 9 0.4% -# 3 2011-03-03 4 0.2% 13 0.6% -# 4 2013-06-24 4 0.2% 17 0.8% -# 5 2017-09-01 4 0.2% 21 1.1% -# 6 2002-09-02 3 0.2% 24 1.2% -# 7 2003-10-14 3 0.2% 27 1.4% -# 8 2004-06-25 3 0.2% 30 1.5% -# 9 2004-06-27 3 0.2% 33 1.7% -# 10 2004-10-29 3 0.2% 36 1.8% -# 11 2005-09-27 3 0.2% 39 2.0% -# 12 2006-08-01 3 0.2% 42 2.1% -# 13 2006-10-10 3 0.2% 45 2.2% -# 14 2007-11-16 3 0.2% 48 2.4% -# 15 2008-03-09 3 0.2% 51 2.5% -# [ reached getOption("max.print.freq") -- omitted 1647 entries, n = 1949 (97.5%) ] +# 1 2016-05-21 10 0.5% 10 0.5% +# 2 2004-11-15 8 0.4% 18 0.9% +# 3 2013-07-29 8 0.4% 26 1.3% +# 4 2017-06-12 8 0.4% 34 1.7% +# 5 2015-11-19 7 0.4% 41 2.1% +# 6 2005-12-22 6 0.3% 47 2.4% +# 7 2015-10-12 6 0.3% 53 2.6% +# 8 2002-05-16 5 0.2% 58 2.9% +# 9 2004-02-02 5 0.2% 63 3.1% +# 10 2004-02-18 5 0.2% 68 3.4% +# 11 2005-08-16 5 0.2% 73 3.6% +# 12 2005-09-01 5 0.2% 78 3.9% +# 13 2006-06-29 5 0.2% 83 4.2% +# 14 2007-08-10 5 0.2% 88 4.4% +# 15 2008-08-29 5 0.2% 93 4.7% +# [ reached getOption("max.print.freq") -- omitted 1136 entries, n = 1907 (95.3%) ] ``` For numeric values, some extra descriptive statistics will be calculated: ```r freq(runif(n = 10, min = 1, max = 5)) -# Frequency table +# Frequency table # Class: numeric # Length: 10 (of which NA: 0 = 0.0%) # Unique: 10 -# -# Mean: 2.9 -# Std. dev.: 1.3 (CV: 0.43, MAD: 1.5) -# Five-Num: 1.5 | 1.7 | 2.6 | 4.0 | 4.7 (IQR: 2.3, CQV: 0.4) +# +# Mean: 3.4 +# Std. dev.: 1.3 (CV: 0.38, MAD: 1.3) +# Five-Num: 1.6 | 2.0 | 3.9 | 4.7 | 4.8 (IQR: 2.7, CQV: 0.4) # Outliers: 0 # -# Item Count Percent Cum. Count Cum. Percent -# --------- ------ -------- ----------- ------------- -# 1.132033 1 10.0% 1 10.0% -# 2.226903 1 10.0% 2 20.0% -# 2.280779 1 10.0% 3 30.0% -# 2.640898 1 10.0% 4 40.0% -# 2.913462 1 10.0% 5 50.0% -# 3.364201 1 10.0% 6 60.0% -# 3.771975 1 10.0% 7 70.0% -# 3.802861 1 10.0% 8 80.0% -# 3.803547 1 10.0% 9 90.0% -# 3.985691 1 10.0% 10 100.0% +# Item Count Percent Cum. Count Cum. Percent +# --- --------- ------ -------- ----------- ------------- +# 1 1.568997 1 10.0% 1 10.0% +# 2 1.993575 1 10.0% 2 20.0% +# 3 2.022348 1 10.0% 3 30.0% +# 4 2.236038 1 10.0% 4 40.0% +# 5 3.579828 1 10.0% 5 50.0% +# 6 4.178081 1 10.0% 6 60.0% +# 7 4.394818 1 10.0% 7 70.0% +# 8 4.689871 1 10.0% 8 80.0% +# 9 4.698626 1 10.0% 9 90.0% +# 10 4.751488 1 10.0% 10 100.0% # # Warning message: # All observations are unique. @@ -320,7 +322,7 @@ 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 -septic_patients # A tibble: 2,000 x 47 +septic_patients # A tibble: 2,000 x 49 # Dataset with ATC antibiotics codes, official names, trade names # and DDD's (oral and parenteral) diff --git a/data/septic_patients.rda b/data/septic_patients.rda index fc482274e129df10d3ca15e145144ef9b218fc8e..aa113de2b8d047757bc3aadb4af65004d66f3bfd 100755 GIT binary patch literal 30732 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 literal 35508 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 LP81{;RGHO4Lu;J# diff --git a/man/as.mic.Rd b/man/as.mic.Rd index 4cf77e34..371ccccf 100755 --- a/man/as.mic.Rd +++ b/man/as.mic.Rd @@ -15,19 +15,22 @@ is.mic(x) \item{na.rm}{a logical indicating whether missing values should be removed} } \value{ -Ordered factor with new class \code{mic} and new attributes \code{package} and \code{package.version} +Ordered factor with new class \code{mic} and new attribute \code{package} } \description{ -This transforms a vector to a new class\code{mic}, which is an ordered factor with valid MIC values as levels. Invalid MIC values will be translated as \code{NA} with a warning. +This transforms a vector to a new class \code{mic}, which is an ordered factor with valid MIC values as levels. Invalid MIC values will be translated as \code{NA} with a warning. } \examples{ mic_data <- as.mic(c(">=32", "1.0", "1", "1.00", 8, "<=0.128", "8", "16", "16")) is.mic(mic_data) # this can also coerce combined MIC/RSI values: -as.mic("<=0.002; R") # will return <=0.002 +as.mic("<=0.002; S") # will return <=0.002 plot(mic_data) barplot(mic_data) } +\seealso{ +\code{\link{as.rsi}} +} \keyword{mic} diff --git a/man/as.rsi.Rd b/man/as.rsi.Rd index 61aab991..24352463 100755 --- a/man/as.rsi.Rd +++ b/man/as.rsi.Rd @@ -13,7 +13,7 @@ is.rsi(x) \item{x}{vector} } \value{ -Ordered factor with new class \code{rsi} and new attributes \code{package} and \code{package.version} +Ordered factor with new class \code{rsi} and new attribute \code{package} } \description{ This transforms a vector to a new class \code{rsi}, which is an ordered factor with levels \code{S < I < R}. Invalid antimicrobial interpretations will be translated as \code{NA} with a warning. @@ -24,9 +24,12 @@ rsi_data <- as.rsi(c(rep("S", 474), rep("I", 36), rep("R", 370), "A", "B", "C")) is.rsi(rsi_data) # this can also coerce combined MIC/RSI values: -as.rsi("<= 0.002; R") # will return R +as.rsi("<= 0.002; S") # will return S plot(rsi_data) # for percentages barplot(rsi_data) # for frequencies } +\seealso{ +\code{\link{as.mic}} +} \keyword{rsi} diff --git a/man/first_isolate.Rd b/man/first_isolate.Rd index 86b582cb..2929f161 100755 --- a/man/first_isolate.Rd +++ b/man/first_isolate.Rd @@ -65,7 +65,7 @@ Determine first (weighted) isolates of all microorganisms of every patient per e } \section{Key antibiotics}{ - There are two ways to determine whether isolates can be included as first \emph{weighted} isolates: \cr + There are two ways to determine whether isolates can be included as first \emph{weighted} isolates which will give generally the same results: \cr \strong{1. Using} \code{type = "keyantibiotics"} \strong{and parameter} \code{ignore_I} \cr Any difference from S to R (or vice versa) will (re)select an isolate as a first weighted isolate. With \code{ignore_I = FALSE}, also differences from I to S|R (or vice versa) will lead to this. This is a reliable method and 30-35 times faster than method 2. \cr @@ -85,6 +85,24 @@ my_patients$first_isolate <- my_patients \%>\% col_patient_id = "patient_id", col_bactid = "bactid") +# Now let's see if first isolates matter: +A <- my_patients \%>\% + group_by(hospital_id) \%>\% + summarise(count = n_rsi(gent), # gentamicin + resistance = resistance(gent)) + +B <- my_patients \%>\% + filter(first_isolate == TRUE) \%>\% + group_by(hospital_id) \%>\% + summarise(count = n_rsi(gent), # gentamicin + resistance = resistance(gent)) + +# Have a look at A and B. B is more reliable because every isolate is +# counted once. Gentamicin resitance in hospital D seems to be 5\% +# higher than originally thought. + +## OTHER EXAMPLES: + \dontrun{ # set key antibiotics to a new variable diff --git a/man/key_antibiotics.Rd b/man/key_antibiotics.Rd index 8d97b7e7..41bf8371 100755 --- a/man/key_antibiotics.Rd +++ b/man/key_antibiotics.Rd @@ -56,7 +56,7 @@ The function \code{key_antibiotics} returns a character vector with 12 antibioti } \section{Key antibiotics}{ - There are two ways to determine whether isolates can be included as first \emph{weighted} isolates: \cr + There are two ways to determine whether isolates can be included as first \emph{weighted} isolates which will give generally the same results: \cr \strong{1. Using} \code{type = "keyantibiotics"} \strong{and parameter} \code{ignore_I} \cr Any difference from S to R (or vice versa) will (re)select an isolate as a first weighted isolate. With \code{ignore_I = FALSE}, also differences from I to S|R (or vice versa) will lead to this. This is a reliable method and 30-35 times faster than method 2. \cr @@ -66,19 +66,26 @@ The function \code{key_antibiotics} returns a character vector with 12 antibioti } \examples{ -\dontrun{ +# septic_patients is a dataset available in the AMR package +?septic_patients +my_patients <- septic_patients + +library(dplyr) # set key antibiotics to a new variable -tbl$keyab <- key_antibiotics(tbl) +my_patients <- my_patients \%>\% + mutate(keyab = key_antibiotics(.)) \%>\% + mutate( + # now calculate first isolates + first_regular = first_isolate(., "date", "patient_id", "bactid"), + # and first WEIGHTED isolates + first_weighted = first_isolate(., "date", "patient_id", "bactid", + col_keyantibiotics = "keyab") + ) -# add regular first isolates -tbl$first_isolate <- - first_isolate(tbl) +# Check the difference, in this data set it results in 7\% more isolates: +sum(my_patients$first_regular, na.rm = TRUE) +sum(my_patients$first_weighted, na.rm = TRUE) -# add first WEIGHTED isolates using key antibiotics -tbl$first_isolate_weighed <- - first_isolate(tbl, - col_keyantibiotics = 'keyab') -} # output of the `key_antibiotics` function could be like this: strainA <- "SSSRR.S.R..S" diff --git a/man/microorganisms.Rd b/man/microorganisms.Rd index 248e68db..2dd3a2d6 100755 --- a/man/microorganisms.Rd +++ b/man/microorganisms.Rd @@ -19,9 +19,6 @@ \item{\code{type_nl}}{Type of microorganism in Dutch, like \code{"Bacterie"} and \code{"Schimmel/gist"}} \item{\code{gramstain_nl}}{Gram of microorganism in Dutch, like \code{"Negatieve staven"}} }} -\source{ -MOLIS (LIS of Certe) - \url{https://www.certe.nl} -} \usage{ microorganisms } diff --git a/man/microorganisms.umcg.Rd b/man/microorganisms.umcg.Rd index 18c98600..51645a14 100755 --- a/man/microorganisms.umcg.Rd +++ b/man/microorganisms.umcg.Rd @@ -9,9 +9,6 @@ \item{\code{mocode}}{Code of microorganism according to UMCG MMB} \item{\code{bactid}}{Code of microorganism in \code{\link{microorganisms}}} }} -\source{ -MOLIS (LIS of Certe) - \url{https://www.certe.nl} \cr \cr GLIMS (LIS of UMCG) - \url{https://www.umcg.nl} -} \usage{ microorganisms.umcg } diff --git a/man/septic_patients.Rd b/man/septic_patients.Rd index 14956c3b..a8be9cdd 100755 --- a/man/septic_patients.Rd +++ b/man/septic_patients.Rd @@ -4,7 +4,7 @@ \name{septic_patients} \alias{septic_patients} \title{Dataset with 2000 blood culture isolates of septic patients} -\format{A data.frame with 2000 observations and 47 variables: +\format{A data.frame with 2000 observations and 49 variables: \describe{ \item{\code{date}}{date of receipt at the laboratory} \item{\code{hospital_id}}{ID of the hospital} @@ -15,11 +15,8 @@ \item{\code{sex}}{sex of the patient} \item{\code{patient_id}}{ID of the patient, first 10 characters of an SHA hash containing irretrievable information} \item{\code{bactid}}{ID of microorganism, see \code{\link{microorganisms}}} - \item{\code{peni:mupi}}{38 different antibiotics with class \code{rsi} (see \code{\link{as.rsi}}); these column names occur in \code{\link{antibiotics}} and can be translated with \code{\link{abname}}} + \item{\code{peni:rifa}}{40 different antibiotics with class \code{rsi} (see \code{\link{as.rsi}}); these column names occur in \code{\link{antibiotics}} data set and can be translated with \code{\link{abname}}} }} -\source{ -MOLIS (LIS of Certe) - \url{https://www.certe.nl} -} \usage{ septic_patients } @@ -45,15 +42,15 @@ my_data <- my_data \%>\% # ANALYSIS # # -------- # -# 1. Get the amoxicillin resistance percentages -# of E. coli, divided by hospital: +# 1. Get the amoxicillin resistance percentages (p) +# and numbers (n) of E. coli, divided by hospital: my_data \%>\% - filter(bactid == "ESCCOL", + filter(bactid == guess_bactid("E. coli"), first_isolates == TRUE) \%>\% group_by(hospital_id) \%>\% - summarise(n = n(), - amoxicillin_resistance = rsi(amox)) + summarise(n = n_rsi(amox), + p = resistance(amox)) # 2. Get the amoxicillin/clavulanic acid resistance @@ -63,7 +60,7 @@ my_data \%>\% filter(bactid == guess_bactid("E. coli"), first_isolates == TRUE) \%>\% group_by(year = format(date, "\%Y")) \%>\% - summarise(n = n(), - amoxclav_resistance = rsi(amcl, minimum = 20)) + summarise(n = n_rsi(amcl), + p = resistance(amcl, minimum = 20)) } \keyword{datasets} diff --git a/tests/testthat/test-bactid.R b/tests/testthat/test-bactid.R index 1fc8253f..17bd3c38 100644 --- a/tests/testthat/test-bactid.R +++ b/tests/testthat/test-bactid.R @@ -37,8 +37,8 @@ test_that("as.bactid works", { select(genus) %>% as.bactid() %>% as.character(), - c("STC", "STC", "NEI", "STA", "STA", - "NEI", "ENT", "ENT", "ESC", "KLE")) + c("ESC", "ESC", "STA", "STA", "STA", + "STA", "STA", "STA", "STA", "STA")) # select with two columns expect_identical( diff --git a/tests/testthat/test-first_isolate.R b/tests/testthat/test-first_isolate.R index c809bbfc..8f37f4f7 100755 --- a/tests/testthat/test-first_isolate.R +++ b/tests/testthat/test-first_isolate.R @@ -8,9 +8,9 @@ test_that("first isolates work", { col_date = "date", col_patient_id = "patient_id", col_bactid = "bactid", - info = FALSE), + info = TRUE), na.rm = TRUE), - 1959) + 1326) # septic_patients contains 1962 out of 2000 first *weighted* isolates expect_equal( @@ -24,8 +24,8 @@ test_that("first isolates work", { type = "keyantibiotics", info = TRUE), na.rm = TRUE)), - 1962) - # and 1997 when using points + 1421) + # and 1961 when using points expect_equal( suppressWarnings( sum( @@ -37,7 +37,7 @@ test_that("first isolates work", { type = "points", info = TRUE), na.rm = TRUE)), - 1997) + 1425) # septic_patients contains 1732 out of 2000 first non-ICU isolates expect_equal( @@ -50,7 +50,7 @@ test_that("first isolates work", { info = TRUE, icu_exclude = TRUE), na.rm = TRUE), - 1732) + 1171) # set 1500 random observations to be of specimen type 'Urine' random_rows <- sample(x = 1:2000, size = 1500, replace = FALSE) @@ -59,7 +59,7 @@ test_that("first isolates work", { first_isolate(tbl = mutate(septic_patients, specimen = if_else(row_number() %in% random_rows, "Urine", - "Unknown")), + "Other")), col_date = "date", col_patient_id = "patient_id", col_bactid = "bactid", @@ -74,7 +74,7 @@ test_that("first isolates work", { first_isolate(tbl = mutate(septic_patients, specimen = if_else(row_number() %in% random_rows, "Urine", - "Unknown")), + "Other")), col_date = "date", col_patient_id = "patient_id", col_bactid = "bactid", diff --git a/tests/testthat/test-freq.R b/tests/testthat/test-freq.R index be3de4c3..c81fcb14 100755 --- a/tests/testthat/test-freq.R +++ b/tests/testthat/test-freq.R @@ -4,8 +4,8 @@ test_that("frequency table works", { expect_equal(nrow(freq(c(1, 1, 2, 2, 3, 3, 4, 4, 5, 5))), 5) expect_equal(nrow(frequency_tbl(c(1, 1, 2, 2, 3, 3, 4, 4, 5, 5))), 5) - # date column of septic_patients should contain 1662 unique dates - expect_equal(nrow(freq(septic_patients$date)), 1662) + # date column of septic_patients should contain 1151 unique dates + expect_equal(nrow(freq(septic_patients$date)), 1151) expect_equal(nrow(freq(septic_patients$date)), length(unique(septic_patients$date))) diff --git a/tests/testthat/test-kurtosis.R b/tests/testthat/test-kurtosis.R index a970e55a..8d5b8f77 100644 --- a/tests/testthat/test-kurtosis.R +++ b/tests/testthat/test-kurtosis.R @@ -2,12 +2,12 @@ context("kurtosis.R") test_that("kurtosis works", { expect_equal(kurtosis(septic_patients$age), - 6.423118, + 3.57781, tolerance = 0.00001) expect_equal(unname(kurtosis(data.frame(septic_patients$age))), - 6.423118, + 3.57781, tolerance = 0.00001) expect_equal(kurtosis(matrix(septic_patients$age)), - 6.423118, + 3.57781, tolerance = 0.00001) }) diff --git a/tests/testthat/test-mdro.R b/tests/testthat/test-mdro.R index 9433be36..f0982e3b 100755 --- a/tests/testthat/test-mdro.R +++ b/tests/testthat/test-mdro.R @@ -13,7 +13,8 @@ test_that("MDRO works", { expect_equal(outcome %>% class(), c('ordered', 'factor')) # septic_patients should have these finding using Dutch guidelines - expect_equal(outcome %>% freq() %>% pull(count), c(3, 21)) + expect_equal(outcome %>% freq() %>% pull(count), + c(2, 14)) # 2 unconfirmed, 14 positive expect_equal(BRMO(septic_patients, info = FALSE), MDRO(septic_patients, "nl", info = FALSE)) diff --git a/tests/testthat/test-resistance.R b/tests/testthat/test-resistance.R index e93a7208..59a30dd9 100755 --- a/tests/testthat/test-resistance.R +++ b/tests/testthat/test-resistance.R @@ -1,19 +1,19 @@ context("resistance.R") test_that("resistance works", { - # amox resistance in `septic_patients` should be around 57.56% - expect_equal(resistance(septic_patients$amox, include_I = TRUE), 0.5756, tolerance = 0.0001) - expect_equal(susceptibility(septic_patients$amox, include_I = FALSE), 1 - 0.5756, tolerance = 0.0001) + # amox resistance in `septic_patients` should be around 66.33% + expect_equal(resistance(septic_patients$amox, include_I = TRUE), 0.6633, tolerance = 0.0001) + expect_equal(susceptibility(septic_patients$amox, include_I = FALSE), 1 - 0.6633, tolerance = 0.0001) # pita+genta susceptibility around 98.09% expect_equal(susceptibility(septic_patients$pita, septic_patients$gent), - 0.9809, + 0.9535, tolerance = 0.0001) expect_equal(suppressWarnings(rsi(septic_patients$pita, septic_patients$gent, interpretation = "S")), - 0.9809, + 0.9535, tolerance = 0.0001) # count of cases @@ -26,7 +26,7 @@ test_that("resistance works", { combination_p = susceptibility(cipr, gent, as_percent = TRUE), combination_n = n_rsi(cipr, gent)) %>% pull(combination_n), - c(138, 474, 170, 464, 183)) + c(202, 482, 201, 499)) expect_warning(resistance(as.character(septic_patients$amcl))) expect_warning(susceptibility(as.character(septic_patients$amcl))) @@ -36,26 +36,26 @@ test_that("resistance works", { }) test_that("old rsi works", { - # amox resistance in `septic_patients` should be around 53.86% - expect_equal(rsi(septic_patients$amox), 0.5756, tolerance = 0.0001) - expect_equal(rsi(septic_patients$amox), 0.5756, tolerance = 0.0001) + # amox resistance in `septic_patients` should be around 66.33% + expect_equal(rsi(septic_patients$amox), 0.6633, tolerance = 0.0001) + expect_equal(rsi(septic_patients$amox, interpretation = "S"), 1 - 0.6633, tolerance = 0.0001) expect_equal(rsi_df(septic_patients, ab = "amox", info = TRUE), - 0.5756, + 0.6633, tolerance = 0.0001) # pita+genta susceptibility around 98.09% expect_equal(rsi(septic_patients$pita, septic_patients$gent, interpretation = "S", info = TRUE), - 0.9809, + 0.9535, tolerance = 0.0001) expect_equal(rsi_df(septic_patients, ab = c("pita", "gent"), interpretation = "S", info = TRUE), - 0.9809, + 0.9535, tolerance = 0.0001) # more than 2 not allowed expect_error(rsi_df(septic_patients, @@ -76,7 +76,7 @@ test_that("old rsi works", { as_percent = TRUE, warning = FALSE), combination_n = n_rsi(cipr, gent)) %>% pull(combination_n), - c(138, 474, 170, 464, 183)) + c(202, 482, 201, 499)) }) test_that("prediction of rsi works", { @@ -86,8 +86,8 @@ test_that("prediction of rsi works", { col_date = "date", info = TRUE) %>% pull("probR") - # amox resistance will decrease using dataset `septic_patients` - expect_true(amox_R[2] > amox_R[20]) + # amox resistance will increase according to data set `septic_patients` + expect_true(amox_R[3] < amox_R[20]) expect_output(rsi_predict(tbl = filter(septic_patients, bactid == "ESCCOL"), model = "binomial", diff --git a/tests/testthat/test-skewness.R b/tests/testthat/test-skewness.R index cd7beff8..96b0ef6e 100644 --- a/tests/testthat/test-skewness.R +++ b/tests/testthat/test-skewness.R @@ -2,12 +2,12 @@ context("skewness.R") test_that("skewness works", { expect_equal(skewness(septic_patients$age), - -1.637164, + -0.90624, tolerance = 0.00001) expect_equal(unname(skewness(data.frame(septic_patients$age))), - -1.637164, + -0.90624, tolerance = 0.00001) expect_equal(skewness(matrix(septic_patients$age)), - -1.637164, + -0.90624, tolerance = 0.00001) })