From 34e70a65ed521c2fdc4ac72b717cf07d2da53831 Mon Sep 17 00:00:00 2001 From: "Matthijs S. Berends" Date: Tue, 27 Feb 2018 20:01:02 +0100 Subject: [PATCH] added septic_patients --- R/data.R | 19 ++++++++++ R/first_isolates.R | 74 ++++++++++++++++----------------------- R/join.R | 12 +++---- R/misc.R | 18 ++++++++++ R/rsi_analysis.R | 74 +++++++++++++++++++++++++++++---------- data/septic_patients.rda | Bin 0 -> 35366 bytes man/first_isolate.Rd | 13 +++---- man/join.Rd | 12 +++---- man/rsi_predict.Rd | 45 ++++++++++++++++-------- man/septic_patients.Rd | 29 +++++++++++++++ 10 files changed, 202 insertions(+), 94 deletions(-) create mode 100644 data/septic_patients.rda create mode 100644 man/septic_patients.Rd diff --git a/R/data.R b/R/data.R index b2af683f..08af4099 100644 --- a/R/data.R +++ b/R/data.R @@ -75,3 +75,22 @@ #' @source MOLIS (LIS of Certe) - \url{https://www.certe.nl} \cr \cr GLIMS (LIS of UMCG) - \url{https://www.umcg.nl} #' @seealso \code{\link{bactlist}} "bactlist.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 e.g. with \code{\link{rsi}} or \code{\link{rsi_predict}}, or it can be used to practice other statistics. +#' @format A data.frame with 2000 observations and 47 variables: +#' \describe{ +#' \item{\code{date}}{date of receipt at the laboratory} +#' \item{\code{hospital_id}}{ID of the hospital} +#' \item{\code{ward_icu}}{logical to determine if ward is an intensive care unit} +#' \item{\code{ward_clinical}}{logical to determine if ward is a regular clinical ward} +#' \item{\code{ward_outpatient}}{logical to determine if ward is an outpatient clinic} +#' \item{\code{age}}{age of the patient} +#' \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{bactlist}}} +#' \item{\code{peni:mupi}}{38 different antibiotics with class \code{rsi} (see \code{\link{as.rsi}}), these column names occur in \code{\link{ablist}} and can be translated with \code{\link{abname}}} +#' } +#' @source MOLIS (LIS of Certe) - \url{https://www.certe.nl} +"septic_patients" \ No newline at end of file diff --git a/R/first_isolates.R b/R/first_isolates.R index cc8c999e..93eedd53 100644 --- a/R/first_isolates.R +++ b/R/first_isolates.R @@ -24,7 +24,7 @@ #' @param col_patient_id column name of the unique IDs of the patients #' @param col_genus column name of the genus of the microorganisms #' @param col_species column name of the species of the microorganisms -#' @param col_testcode column name of the test codes, see Details +#' @param col_testcode column name of the test codes. Use \code{col_testcode = NA} to \strong{not} exclude certain test codes (like test codes for screening). In that case \code{testcodes_exclude} will be ignored. #' @param col_specimen column name of the specimen type or group #' @param col_icu column name of the logicals (\code{TRUE}/\code{FALSE}) whether a ward or department is an Intensive Care Unit (ICU) #' @param col_keyantibiotics column name of the key antibiotics to determine first \emph{weighted} isolates, see \code{\link{key_antibiotics}}. @@ -33,11 +33,13 @@ #' @param icu_exclude logical whether ICU isolates should be excluded #' @param filter_specimen specimen group or type that should be excluded #' @param output_logical return output as \code{logical} (will else the values \code{0} or \code{1}) -#' @param ignore_I ignore \code{"I"} as antimicrobial interpretation of key antibiotics (with \code{FALSE}, changes in antibiograms from S to I and I to R will be interpreted as difference) +#' @param points_threshold points until the comparison of key antibiotics will lead to inclusion of an isolate, see Details #' @param info print progress -#' @details To conduct an analysis of antimicrobial resistance, you should only include the first isolate of every patient per episode. 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 is 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 selection bias. -#' -#' Use \code{col_testcode = NA} to \strong{not} exclude certain test codes (like test codes for screening). In that case \code{testcodes_exclude} will be ignored. +#' @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}. + +#' \strong{\code{points_threshold}} \cr +#' To compare key antibiotics, the difference between antimicrobial interpretations will be measured. A difference from I to S|R (or vice versa) means 0.5 points. A difference from S to R (or vice versa) means 1 point. When the sum of points exceeds \code{points_threshold}, an isolate will be (re)selected as a first weighted isolate. #' @keywords isolate isolates first #' @export #' @importFrom dplyr arrange_at lag between row_number filter mutate arrange @@ -96,7 +98,7 @@ first_isolate <- function(tbl, icu_exclude = FALSE, filter_specimen = NA, output_logical = TRUE, - ignore_I = TRUE, + points_threshold = 2, info = TRUE) { # controleren of kolommen wel bestaan @@ -274,20 +276,16 @@ first_isolate <- function(tbl, 0)) if (col_keyantibiotics != '') { - # dit duurt 2 min bij 120.000 isolaten if (info == TRUE) { - cat('Comparing key antibiotics for first weighted isolates') - if (ignore_I == TRUE) { - cat(' (ignoring I)') - } - cat('...\n') + cat(paste0('Comparing key antibiotics for first weighted isolates (using points threshold of ' + , points_threshold, ')...\n')) } all_first <- all_first %>% mutate(key_ab_lag = lag(key_ab)) %>% - mutate(key_ab_other = !key_antibiotics_equal(key_ab, - key_ab_lag, - ignore_I = ignore_I, - info = info)) %>% + mutate(key_ab_other = !key_antibiotics_equal(x = key_ab, + y = key_ab_lag, + points_threshold = points_threshold, + info = info)) %>% mutate( real_first_isolate = if_else( @@ -448,18 +446,11 @@ key_antibiotics <- function(tbl, } -# Compare key antibiotics -# -# Check whether two text values with key antibiotics match. Supports vectors. -# @param x,y tekst (or multiple text vectors) with antimicrobial interpretations -# @param ignore_I ignore \code{"I"} as antimicrobial interpretation of key antibiotics (with \code{FALSE}, changes in antibiograms from S to I and I to R will be interpreted as difference) -# @param info print progress -# @return logical -# @export -# @seealso \code{\link{key_antibiotics}} +#' @importFrom dplyr progress_estimated %>% +#' @noRd +key_antibiotics_equal <- function(x, y, points_threshold = 2, info = FALSE) { + # x is active row, y is lag -# only internal use -key_antibiotics_equal <- function(x, y, ignore_I = TRUE, info = FALSE) { if (length(x) != length(y)) { stop('Length of `x` and `y` must be equal.') } @@ -467,13 +458,13 @@ key_antibiotics_equal <- function(x, y, ignore_I = TRUE, info = FALSE) { result <- logical(length(x)) if (info == TRUE) { - voortgang <- dplyr::progress_estimated(length(x)) + p <- dplyr::progress_estimated(length(x)) } for (i in 1:length(x)) { if (info == TRUE) { - voortgang$tick()$print() + p$tick()$print() } if (is.na(x[i])) { @@ -493,22 +484,17 @@ key_antibiotics_equal <- function(x, y, ignore_I = TRUE, info = FALSE) { } else { - x2 <- strsplit(x[i], "")[[1]] - y2 <- strsplit(y[i], "")[[1]] + # 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) + + x2 <- strsplit(x[i], "")[[1]] %>% as.rsi() %>% as.double() + y2 <- strsplit(y[i], "")[[1]] %>% as.rsi() %>% as.double() - if (ignore_I == TRUE) { - valid_chars <- c('S', 's', 'R', 'r') - } else { - valid_chars <- c('S', 's', 'I', 'i', 'R', 'r') - } - - # Ongeldige waarden (zoals "-", NA) op beide locaties verwijderen - x2[which(!x2 %in% valid_chars)] <- '?' - x2[which(!y2 %in% valid_chars)] <- '?' - y2[which(!x2 %in% valid_chars)] <- '?' - y2[which(!y2 %in% valid_chars)] <- '?' - - result[i] <- all(x2 == y2) + points <- (x2 - y2) %>% abs() %>% sum(na.rm = TRUE) + result[i] <- ((points / 2) >= points_threshold) } } if (info == TRUE) { diff --git a/R/join.R b/R/join.R index 08838e79..294b875d 100644 --- a/R/join.R +++ b/R/join.R @@ -6,7 +6,7 @@ #' @aliases join inner_join #' @param x existing table to join #' @param by a variable to join by - could be a column name of \code{x} with values that exist in \code{bactlist$bactid} (like \code{by = "bacteria_id"}), or another column in \code{\link{bactlist}} (but then it should be named, like \code{by = c("my_genus_species" = "fullname")}) -#' @param ... other parameters to pass trhough to \code{dplyr::\link[dplyr]{join}}. +#' @param ... other parameters to pass on to \code{dplyr::\link[dplyr]{join}}. #' @details As opposed to the \code{\link[dplyr]{join}} functions of \code{dplyr}, at default existing columns will get a suffix \code{"2"} and the newly joined columns will not get a suffix. See \code{\link[dplyr]{join}} for more information. #' @export #' @examples @@ -37,7 +37,7 @@ inner_join_bactlist <- function(x, by = 'bactid', ...) { #' @rdname join #' @export -left_join_bactlist <- function(x, by = 'bacteriecode', ...) { +left_join_bactlist <- function(x, by = 'bactid', ...) { # no name set to `by` parameter if (is.null(names(by))) { joinby <- colnames(AMR::bactlist)[1] @@ -54,7 +54,7 @@ left_join_bactlist <- function(x, by = 'bacteriecode', ...) { #' @rdname join #' @export -right_join_bactlist <- function(x, by = 'bacteriecode', ...) { +right_join_bactlist <- function(x, by = 'bactid', ...) { # no name set to `by` parameter if (is.null(names(by))) { joinby <- colnames(AMR::bactlist)[1] @@ -71,7 +71,7 @@ right_join_bactlist <- function(x, by = 'bacteriecode', ...) { #' @rdname join #' @export -full_join_bactlist <- function(x, by = 'bacteriecode', ...) { +full_join_bactlist <- function(x, by = 'bactid', ...) { # no name set to `by` parameter if (is.null(names(by))) { joinby <- colnames(AMR::bactlist)[1] @@ -84,7 +84,7 @@ full_join_bactlist <- function(x, by = 'bacteriecode', ...) { #' @rdname join #' @export -semi_join_bactlist <- function(x, by = 'bacteriecode', ...) { +semi_join_bactlist <- function(x, by = 'bactid', ...) { # no name set to `by` parameter if (is.null(names(by))) { joinby <- colnames(AMR::bactlist)[1] @@ -97,7 +97,7 @@ semi_join_bactlist <- function(x, by = 'bacteriecode', ...) { #' @rdname join #' @export -anti_join_bactlist <- function(x, by = 'bacteriecode', ...) { +anti_join_bactlist <- function(x, by = 'bactid', ...) { # no name set to `by` parameter if (is.null(names(by))) { joinby <- colnames(AMR::bactlist)[1] diff --git a/R/misc.R b/R/misc.R index e90118d3..ff4b3afa 100644 --- a/R/misc.R +++ b/R/misc.R @@ -29,3 +29,21 @@ percent <- function(x, round = 1, ...) { base::paste0(base::round(x * 100, digits = round), "%") } + +quasiquotate <- function(deparsed, parsed) { + # when text: remove first and last " + if (any(deparsed %like% '^".+"$' | deparsed %like% "^'.+'$")) { + deparsed <- deparsed %>% substr(2, nchar(.) - 1) + } + # apply if needed + if (any(!deparsed %like% '[[$:()]' + & !deparsed %in% c('""', "''", "", # empty text + ".", ".data", # dplyr references + "TRUE", "FALSE", # logicals + "NA", "NaN", "NULL", # empty values + ls(.GlobalEnv)))) { + deparsed + } else { + parsed + } +} \ No newline at end of file diff --git a/R/rsi_analysis.R b/R/rsi_analysis.R index dc268de8..e9a2edf5 100644 --- a/R/rsi_analysis.R +++ b/R/rsi_analysis.R @@ -192,15 +192,15 @@ rsi_df <- function(tbl, #' rsi(as.rsi(isolates$amcl), interpretation = "S") #' } rsi <- function(ab1, ab2 = NA, interpretation = 'IR', minimum = 30, percent = FALSE, info = FALSE, warning = FALSE) { - functietekst <- as.character(match.call()) + function_text <- as.character(match.call()) # param 1 = functienaam # param 2 = ab1 # param 3 = ab2 - ab1.naam <- functietekst[2] + ab1.naam <- function_text[2] if (!grepl('^[a-z]{3,4}$', ab1.naam)) { ab1.naam <- 'rsi1' } - ab2.naam <- functietekst[3] + ab2.naam <- function_text[3] if (!grepl('^[a-z]{3,4}$', ab2.naam)) { ab2.naam <- 'rsi2' } @@ -236,10 +236,10 @@ rsi <- function(ab1, ab2 = NA, interpretation = 'IR', minimum = 30, percent = FA #' Predict antimicrobial resistance #' -#' Create a prediction model to predict antimicrobial resistance for the next years on statistical solid ground. Standard errors (SE) will be returned as columns \code{se_min} and \code{se_max}. +#' Create a prediction model to predict antimicrobial resistance for the next years on statistical solid ground. Standard errors (SE) will be returned as columns \code{se_min} and \code{se_max}. See Examples for a real live example. #' @param tbl table that contains columns \code{col_ab} and \code{col_date} -#' @param col_ab column name of \code{tbl} with antimicrobial interpretations (\code{R}, \code{I} and \code{S}) -#' @param col_date column name of the date, will be used to calculate years +#' @param col_ab column name of \code{tbl} with antimicrobial interpretations (\code{R}, \code{I} and \code{S}), supports tidyverse-like quotation +#' @param col_date column name of the date, will be used to calculate years if this column doesn't consist of years already, supports tidyverse-like quotation #' @param year_max highest year to use in the prediction model, deafults to 15 years after today #' @param year_every unit of sequence between lowest year found in the data and \code{year_max} #' @param model the statistical model of choice. Valid values are \code{"binomial"} (or \code{"binom"} or \code{"logit"}) or \code{"loglin"} or \code{"linear"} (or \code{"lin"}). @@ -255,24 +255,41 @@ rsi <- function(ab1, ab2 = NA, interpretation = 'IR', minimum = 30, percent = FA #' \dontrun{ #' # use it directly: #' rsi_predict(tbl = tbl[which(first_isolate == TRUE & genus == "Haemophilus"),], -#' col_ab = "amcl", coldate = "date") +#' col_ab = "amcl", col_date = "date") #' #' # or with dplyr so you can actually read it: #' library(dplyr) #' tbl %>% #' filter(first_isolate == TRUE, #' genus == "Haemophilus") %>% -#' rsi_predict(col_ab = "amcl", coldate = "date") -#' -#' tbl %>% -#' filter(first_isolate_weighted == TRUE, -#' genus == "Haemophilus") %>% -#' rsi_predict(col_ab = "amcl", -#' coldate = "date", -#' year_max = 2050, -#' year_every = 5) -#' +#' rsi_predict(amcl, date) #' } +#' +#' +#' # real live example: +#' library(dplyr) +#' septic_patients %>% +#' # get bacteria properties like genus and species +#' left_join_bactlist("bactid") %>% +#' # calculate first isolates +#' mutate(first_isolate = +#' first_isolate(., +#' "date", +#' "patient_id", +#' "genus", +#' "species", +#' col_specimen = NA, +#' col_icu = NA)) %>% +#' # filter on first E. coli isolates +#' filter(genus == "Escherichia", +#' species == "coli", +#' first_isolate == TRUE) %>% +#' # predict resistance of cefotaxime for next years +#' rsi_predict(col_ab = cfot, +#' col_date = date, +#' year_max = 2025, +#' preserve_measurements = FALSE) +#' rsi_predict <- function(tbl, col_ab, col_date, @@ -283,12 +300,33 @@ rsi_predict <- function(tbl, preserve_measurements = TRUE, info = TRUE) { + col_ab <- quasiquotate(deparse(substitute(col_ab)), col_ab) + if (!col_ab %in% colnames(tbl)) { + stop('Column ', col_ab, ' not found.') + } + col_date <- quasiquotate(deparse(substitute(col_date)), col_date) + if (!col_date %in% colnames(tbl)) { + stop('Column ', col_date, ' not found.') + } + if ('grouped_df' %in% class(tbl)) { + # no grouped tibbles please, mutate will throw errors + tbl <- base::as.data.frame(tbl, stringsAsFactors = FALSE) + } + if (I_as_R == TRUE) { tbl[, col_ab] <- gsub('I', 'R', tbl %>% pull(col_ab)) } + + if (!all(tbl %>% pull(col_ab) %>% as.rsi() %in% c(NA, 'S', 'I', 'R'))) { + stop('Column ', col_ab, ' must contain antimicrobial interpretations (S, I, R).') + } year <- function(x) { - as.integer(format(as.Date(x), '%Y')) + if (all(grepl('^[0-9]{4}$', x))) { + x + } else { + as.integer(format(as.Date(x), '%Y')) + } } years_predict <- seq(from = min(year(tbl %>% pull(col_date))), to = year_max, by = year_every) diff --git a/data/septic_patients.rda b/data/septic_patients.rda new file mode 100644 index 0000000000000000000000000000000000000000..272d28f9b8a13e141ae7d01583c4d769157df18f GIT binary patch literal 35366 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 Efcfz`u>b%7 literal 0 HcmV?d00001 diff --git a/man/first_isolate.Rd b/man/first_isolate.Rd index ca9e344d..4704cb35 100644 --- a/man/first_isolate.Rd +++ b/man/first_isolate.Rd @@ -7,7 +7,7 @@ first_isolate(tbl, col_date, col_patient_id, col_genus, col_species, col_testcode = NA, col_specimen, col_icu, col_keyantibiotics = NA, episode_days = 365, testcodes_exclude = "", icu_exclude = FALSE, - filter_specimen = NA, output_logical = TRUE, ignore_I = TRUE, + filter_specimen = NA, output_logical = TRUE, points_threshold = 2, info = TRUE) } \arguments{ @@ -21,7 +21,7 @@ first_isolate(tbl, col_date, col_patient_id, col_genus, col_species, \item{col_species}{column name of the species of the microorganisms} -\item{col_testcode}{column name of the test codes, see Details} +\item{col_testcode}{column name of the test codes. Use \code{col_testcode = NA} to \strong{not} exclude certain test codes (like test codes for screening). In that case \code{testcodes_exclude} will be ignored.} \item{col_specimen}{column name of the specimen type or group} @@ -39,7 +39,7 @@ first_isolate(tbl, col_date, col_patient_id, col_genus, col_species, \item{output_logical}{return output as \code{logical} (will else the values \code{0} or \code{1})} -\item{ignore_I}{ignore \code{"I"} as antimicrobial interpretation of key antibiotics (with \code{FALSE}, changes in antibiograms from S to I and I to R will be interpreted as difference)} +\item{points_threshold}{points until the comparison of key antibiotics will lead to inclusion of an isolate, see Details} \item{info}{print progress} } @@ -50,9 +50,10 @@ A vector to add to table, see Examples. Determine first (weighted) isolates of all microorganisms of every patient per episode and (if needed) per specimen type. } \details{ -To conduct an analysis of antimicrobial resistance, you should only include the first isolate of every patient per episode. 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 is 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 selection bias. - - Use \code{col_testcode = NA} to \strong{not} exclude certain test codes (like test codes for screening). In that case \code{testcodes_exclude} will be ignored. +\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}. + \strong{\code{points_threshold}} \cr + To compare key antibiotics, the difference between antimicrobial interpretations will be measured. A difference from I to S|R (or vice versa) means 0.5 points. A difference from S to R (or vice versa) means 1 point. When the sum of points exceeds \code{points_threshold}, an isolate will be (re)selected as a first weighted isolate. } \examples{ \dontrun{ diff --git a/man/join.Rd b/man/join.Rd index 1d274b3a..9be18359 100644 --- a/man/join.Rd +++ b/man/join.Rd @@ -13,22 +13,22 @@ \usage{ inner_join_bactlist(x, by = "bactid", ...) -left_join_bactlist(x, by = "bacteriecode", ...) +left_join_bactlist(x, by = "bactid", ...) -right_join_bactlist(x, by = "bacteriecode", ...) +right_join_bactlist(x, by = "bactid", ...) -full_join_bactlist(x, by = "bacteriecode", ...) +full_join_bactlist(x, by = "bactid", ...) -semi_join_bactlist(x, by = "bacteriecode", ...) +semi_join_bactlist(x, by = "bactid", ...) -anti_join_bactlist(x, by = "bacteriecode", ...) +anti_join_bactlist(x, by = "bactid", ...) } \arguments{ \item{x}{existing table to join} \item{by}{a variable to join by - could be a column name of \code{x} with values that exist in \code{bactlist$bactid} (like \code{by = "bacteria_id"}), or another column in \code{\link{bactlist}} (but then it should be named, like \code{by = c("my_genus_species" = "fullname")})} -\item{...}{other parameters to pass trhough to \code{dplyr::\link[dplyr]{join}}.} +\item{...}{other parameters to pass on to \code{dplyr::\link[dplyr]{join}}.} } \description{ Join the list of microorganisms \code{\link{bactlist}} easily to an existing table. diff --git a/man/rsi_predict.Rd b/man/rsi_predict.Rd index 1b49a95c..42b0e670 100644 --- a/man/rsi_predict.Rd +++ b/man/rsi_predict.Rd @@ -12,9 +12,9 @@ rsi_predict(tbl, col_ab, col_date, \arguments{ \item{tbl}{table that contains columns \code{col_ab} and \code{col_date}} -\item{col_ab}{column name of \code{tbl} with antimicrobial interpretations (\code{R}, \code{I} and \code{S})} +\item{col_ab}{column name of \code{tbl} with antimicrobial interpretations (\code{R}, \code{I} and \code{S}), supports tidyverse-like quotation} -\item{col_date}{column name of the date, will be used to calculate years} +\item{col_date}{column name of the date, will be used to calculate years if this column doesn't consist of years already, supports tidyverse-like quotation} \item{year_max}{highest year to use in the prediction model, deafults to 15 years after today} @@ -32,30 +32,47 @@ rsi_predict(tbl, col_ab, col_date, \code{data.frame} with columns \code{year}, \code{probR}, \code{se_min} and \code{se_max}. } \description{ -Create a prediction model to predict antimicrobial resistance for the next years on statistical solid ground. Standard errors (SE) will be returned as columns \code{se_min} and \code{se_max}. +Create a prediction model to predict antimicrobial resistance for the next years on statistical solid ground. Standard errors (SE) will be returned as columns \code{se_min} and \code{se_max}. See Examples for a real live example. } \examples{ \dontrun{ # use it directly: rsi_predict(tbl = tbl[which(first_isolate == TRUE & genus == "Haemophilus"),], - col_ab = "amcl", coldate = "date") + col_ab = "amcl", col_date = "date") # or with dplyr so you can actually read it: library(dplyr) tbl \%>\% filter(first_isolate == TRUE, genus == "Haemophilus") \%>\% - rsi_predict(col_ab = "amcl", coldate = "date") - -tbl \%>\% - filter(first_isolate_weighted == TRUE, - genus == "Haemophilus") \%>\% - rsi_predict(col_ab = "amcl", - coldate = "date", - year_max = 2050, - year_every = 5) - + rsi_predict(amcl, date) } + + +# real live example: +library(dplyr) +septic_patients \%>\% + # get bacteria properties like genus and species + left_join_bactlist("bactid") \%>\% + # calculate first isolates + mutate(first_isolate = + first_isolate(., + "date", + "patient_id", + "genus", + "species", + col_specimen = NA, + col_icu = NA)) \%>\% + # filter on first E. coli isolates + filter(genus == "Escherichia", + species == "coli", + first_isolate == TRUE) \%>\% + # predict resistance of cefotaxime for next years + rsi_predict(col_ab = cfot, + col_date = date, + year_max = 2025, + preserve_measurements = FALSE) + } \seealso{ \code{\link{lm}} \cr \code{\link{glm}} diff --git a/man/septic_patients.Rd b/man/septic_patients.Rd new file mode 100644 index 00000000..a118d022 --- /dev/null +++ b/man/septic_patients.Rd @@ -0,0 +1,29 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/data.R +\docType{data} +\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: +\describe{ + \item{\code{date}}{date of receipt at the laboratory} + \item{\code{hospital_id}}{ID of the hospital} + \item{\code{ward_icu}}{logical to determine if ward is an intensive care unit} + \item{\code{ward_clinical}}{logical to determine if ward is a regular clinical ward} + \item{\code{ward_outpatient}}{logical to determine if ward is an outpatient clinic} + \item{\code{age}}{age of the patient} + \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{bactlist}}} + \item{\code{peni:mupi}}{38 different antibiotics with class \code{rsi} (see \code{\link{as.rsi}}), these column names occur in \code{\link{ablist}} and can be translated with \code{\link{abname}}} +}} +\source{ +MOLIS (LIS of Certe) - \url{https://www.certe.nl} +} +\usage{ +septic_patients +} +\description{ +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 e.g. with \code{\link{rsi}} or \code{\link{rsi_predict}}, or it can be used to practice other statistics. +} +\keyword{datasets}