diff --git a/DESCRIPTION b/DESCRIPTION
index a5e6c939..861b1342 100644
--- a/DESCRIPTION
+++ b/DESCRIPTION
@@ -1,6 +1,6 @@
Package: AMR
-Version: 1.6.0.9009
-Date: 2021-04-23
+Version: 1.6.0.9010
+Date: 2021-04-26
Title: Antimicrobial Resistance Data Analysis
Authors@R: c(
person(role = c("aut", "cre"),
diff --git a/NAMESPACE b/NAMESPACE
index c8a9ade3..abf29a54 100755
--- a/NAMESPACE
+++ b/NAMESPACE
@@ -161,8 +161,10 @@ export(ab_tradenames)
export(ab_url)
export(age)
export(age_groups)
+export(all_antimicrobials)
export(aminoglycosides)
export(anti_join_microorganisms)
+export(antimicrobials_equal)
export(as.ab)
export(as.disk)
export(as.mic)
@@ -237,6 +239,7 @@ export(is.rsi.eligible)
export(is_new_episode)
export(key_antibiotics)
export(key_antibiotics_equal)
+export(key_antimicrobials)
export(kurtosis)
export(labels_rsi_count)
export(left_join_microorganisms)
diff --git a/NEWS.md b/NEWS.md
index 70127e9f..ae862ea5 100755
--- a/NEWS.md
+++ b/NEWS.md
@@ -1,8 +1,16 @@
-# AMR 1.6.0.9009
-## Last updated: 23 April 2021
+# AMR 1.6.0.9010
+## Last updated: 26 April 2021
### New
* Function `custom_eucast_rules()` that brings support for custom AMR rules in `eucast_rules()`
+* Support for all four methods to determine first isolates as summarised by Hindler *et al* (doi: [10.1086/511864](https://doi.org/10.1086/511864)): isolate-based, patient-based, episode-based and phenotype-based. The last method is now the default.
+ * Since fungal isolates can also be selected, new functions `key_antimicrobials()` and `all_antimicrobials()` have replaced the now deprecated function `key_antibiotics()`
+ * Using `key_antimicrobials()` still only selects six preferred antibiotics for Gram-negatives, six for Gram-positives, and six universal antibiotics. It has a new `antifungal` argument to set antifungal agents (antimycotics).
+ * The `first_isolate()` function gained the argument `method` that has to be "phenotype-based", "episode-based", "patient-based", or "isolate-based". The old behaviour is equal to "episode-based", while the new default is "phenotype-based".
+ * Using `type == "points"` in the `first_isolate()` function for phenotype-based selection will now consider all antimicrobial drugs in the data set, using the new `all_antimicrobials()`
+ * The `first_isolate()` function can now take a vector of values for `col_keyantibiotics` and can have an episode length of `Inf`
+ * The `filter_first_isolate()` function has not changed, as it uses the episode-based method. The `filter_first_weighted_isolate()` may now include more isolates as uses the phenotype-based method.
+ * The documentation of the `first_isolate()` and `key_antimicrobials()` functions has been completely rewritten.
### Changed
* Custom MDRO guidelines (`mdro()`, `custom_mdro_guideline()`):
@@ -12,7 +20,6 @@
* The `example_isolates` data set now contains some (fictitious) zero-year old patients
* Fix for minor translation errors
* Printing of microbial codes in a `data.frame` or `tibble` now gives a warning if the data contains old microbial codes (from a previous AMR package version)
-* `first_isolate()` can now take a vector of values for `col_keyantibiotics` and can have an episode length of `Inf`
* Extended the `like()` functions:
* Now checks if `pattern` is a *valid* regular expression
* Added `%unlike%` and `%unlike_case%` (as negations of the existing `%like%` and `%like_case%`). This greatly improves readability:
@@ -25,9 +32,6 @@
* Fixed an installation error on R-3.0
* Added `info` argument to `as.mo()` to turn on/off the progress bar
* Fixed a bug that `col_mo` for some functions (esp. `eucast_rules()` and `mdro()`) could not be column names of the `microorganisms` data set as it would throw an error
-* Using `first_isolate()` with key antibiotics:
- * Fixed a bug in the algorithm when using `type == "points"`, that now leads to inclusion of slightly more isolates
- * Big speed improvement for `key_antibiotics_equal()` when using `type == "points"`
# AMR 1.6.0
diff --git a/R/aa_helper_functions.R b/R/aa_helper_functions.R
index b59b36fd..ee8fac86 100755
--- a/R/aa_helper_functions.R
+++ b/R/aa_helper_functions.R
@@ -190,8 +190,8 @@ search_type_in_df <- function(x, type, info = TRUE) {
}
# -- key antibiotics
if (type == "keyantibiotics") {
- if (any(colnames(x) %like% "^key.*(ab|antibiotics)")) {
- found <- sort(colnames(x)[colnames(x) %like% "^key.*(ab|antibiotics)"])[1]
+ if (any(colnames(x) %like% "^key.*(ab|antibiotics|antimicrobials)")) {
+ found <- sort(colnames(x)[colnames(x) %like% "^key.*(ab|antibiotics|antimicrobials)"])[1]
}
}
# -- date
@@ -318,7 +318,9 @@ word_wrap <- function(...,
msg <- paste0(c(...), collapse = "")
if (isTRUE(as_note)) {
- msg <- paste0("NOTE: ", gsub("^note:? ?", "", msg, ignore.case = TRUE))
+ # \u2139 is a symbol officially named 'information source'
+ # \ufe0f can add the blue square around it: \u2139\ufe0f
+ msg <- paste0("\u2139 ", gsub("^note:? ?", "", msg, ignore.case = TRUE))
}
if (msg %like% "\n") {
@@ -352,8 +354,8 @@ word_wrap <- function(...,
msg <- paste0(msg, collapse = " ")
msg <- gsub("\n ", "\n", msg, fixed = TRUE)
- if (msg_stripped %like% "^NOTE: ") {
- indentation <- 6 + extra_indent
+ if (msg_stripped %like% "\u2139 ") {
+ indentation <- 2 + extra_indent
} else if (msg_stripped %like% "^=> ") {
indentation <- 3 + extra_indent
} else {
diff --git a/R/deprecated.R b/R/deprecated.R
index b4b1cbeb..0ac98c67 100755
--- a/R/deprecated.R
+++ b/R/deprecated.R
@@ -45,3 +45,71 @@ p_symbol <- function(p, emptychar = " ") {
s
}
+
+#' @name AMR-deprecated
+#' @export
+key_antibiotics <- function(x = NULL,
+ col_mo = NULL,
+ universal_1 = guess_ab_col(x, "amoxicillin"),
+ universal_2 = guess_ab_col(x, "amoxicillin/clavulanic acid"),
+ universal_3 = guess_ab_col(x, "cefuroxime"),
+ universal_4 = guess_ab_col(x, "piperacillin/tazobactam"),
+ universal_5 = guess_ab_col(x, "ciprofloxacin"),
+ universal_6 = guess_ab_col(x, "trimethoprim/sulfamethoxazole"),
+ GramPos_1 = guess_ab_col(x, "vancomycin"),
+ GramPos_2 = guess_ab_col(x, "teicoplanin"),
+ GramPos_3 = guess_ab_col(x, "tetracycline"),
+ GramPos_4 = guess_ab_col(x, "erythromycin"),
+ GramPos_5 = guess_ab_col(x, "oxacillin"),
+ GramPos_6 = guess_ab_col(x, "rifampin"),
+ GramNeg_1 = guess_ab_col(x, "gentamicin"),
+ GramNeg_2 = guess_ab_col(x, "tobramycin"),
+ GramNeg_3 = guess_ab_col(x, "colistin"),
+ GramNeg_4 = guess_ab_col(x, "cefotaxime"),
+ GramNeg_5 = guess_ab_col(x, "ceftazidime"),
+ GramNeg_6 = guess_ab_col(x, "meropenem"),
+ warnings = TRUE,
+ ...) {
+
+ .Deprecated(old = "key_antibiotics()",
+ new = "key_antimicrobials()",
+ package = "AMR")
+
+ if (is_null_or_grouped_tbl(x)) {
+ # when `x` is left blank, auto determine it (get_current_data() also contains dplyr::cur_data_all())
+ # is also fix for using a grouped df as input (a dot as first argument)
+ x <- tryCatch(get_current_data(arg_name = "x", call = -2), error = function(e) x)
+ }
+
+ key_antimicrobials(x = x,
+ col_mo = col_mo,
+ universal = c(universal_1, universal_2, universal_3, universal_4, universal_5, universal_6),
+ gram_negative = c(GramNeg_1, GramNeg_2, GramNeg_3, GramNeg_4, GramNeg_5, GramNeg_6),
+ gram_positive = c(GramPos_1, GramPos_2, GramPos_3, GramPos_4, GramPos_5, GramPos_6),
+ antifungal = NULL,
+ only_rsi_columns = FALSE,
+ ...)
+}
+
+#' @name AMR-deprecated
+#' @export
+key_antibiotics_equal <- function(y,
+ z,
+ type = "keyantimicrobials",
+ ignore_I = TRUE,
+ points_threshold = 2,
+ info = FALSE,
+ na.rm = TRUE,
+ ...) {
+
+ .Deprecated(old = "key_antibiotics_equal()",
+ new = "antimicrobials_equal()",
+ package = "AMR")
+
+ antimicrobials_equal(y = y,
+ z = z,
+ type = type,
+ ignore_I = ignore_I,
+ points_threshold = points_threshold,
+ info = info)
+}
diff --git a/R/first_isolate.R b/R/first_isolate.R
index 3a2c8b5c..fe5c2648 100755
--- a/R/first_isolate.R
+++ b/R/first_isolate.R
@@ -34,62 +34,91 @@
#' @param col_testcode column name of the test codes. Use `col_testcode = NULL` to **not** exclude certain test codes (such as test codes for screening). In that case `testcodes_exclude` will be ignored.
#' @param col_specimen column name of the specimen type or group
#' @param col_icu column name of the logicals (`TRUE`/`FALSE`) whether a ward or department is an Intensive Care Unit (ICU)
-#' @param col_keyantibiotics column name of the key antibiotics to determine first (weighted) isolates, see [key_antibiotics()]. Defaults to the first column that starts with 'key' followed by 'ab' or 'antibiotics' (case insensitive). Use `col_keyantibiotics = FALSE` to prevent this. Can also be the output of [key_antibiotics()].
+#' @param col_keyantimicrobials (only useful when `method = "phenotype-based"`) column name of the key antimicrobials to determine first (weighted) isolates, see [key_antimicrobials()]. Defaults to the first column that starts with 'key' followed by 'ab' or 'antibiotics' or 'antimicrobials' (case insensitive). Use `col_keyantimicrobials = FALSE` to prevent this. Can also be the output of [key_antimicrobials()].
#' @param episode_days episode in days after which a genus/species combination will be determined as 'first isolate' again. The default of 365 days is based on the guideline by CLSI, see *Source*.
#' @param testcodes_exclude character vector with test codes that should be excluded (case-insensitive)
#' @param icu_exclude logical to indicate whether ICU isolates should be excluded (rows with value `TRUE` in the column set with `col_icu`)
#' @param specimen_group value in the column set with `col_specimen` to filter on
-#' @param type type to determine weighed isolates; can be `"keyantibiotics"` or `"points"`, see *Details*
-#' @param ignore_I logical to indicate whether antibiotic interpretations with `"I"` will be ignored when `type = "keyantibiotics"`, see *Details*
-#' @param points_threshold points until the comparison of key antibiotics will lead to inclusion of an isolate when `type = "points"`, see *Details*
+#' @param type type to determine weighed isolates; can be `"keyantimicrobials"` or `"points"`, see *Details*
+#' @param method the algorithm to apply, either `"phenotype-based"`, `"episode-based"`, `"patient-based"` or `"isolate-based"` (can be abbreviated), see *Details*
+#' @param ignore_I logical to indicate whether antibiotic interpretations with `"I"` will be ignored when `type = "keyantimicrobials"`, see *Details*
+#' @param points_threshold minimum number of points to require before differences in the antibiogram will lead to inclusion of an isolate when `type = "points"`, see *Details*
#' @param info a [logical] to indicate info should be printed, defaults to `TRUE` only in interactive mode
#' @param include_unknown logical to indicate whether 'unknown' microorganisms should be included too, i.e. microbial code `"UNKNOWN"`, which defaults to `FALSE`. For WHONET users, this means that all records with organism code `"con"` (*contamination*) will be excluded at default. Isolates with a microbial ID of `NA` will always be excluded as first isolate.
#' @param include_untested_rsi logical to indicate whether also rows without antibiotic results are still eligible for becoming a first isolate. Use `include_untested_rsi = FALSE` to always return `FALSE` for such rows. This checks the data set for columns of class ` Now checks if These functions are so-called 'Deprecated'. They will be removed in a future release. Using the functions will give a warning with the name of the function it has been replaced by (if there is one). column name of the logicals ( column name of the key antibiotics to determine first (weighted) isolates, see (only useful when type to determine weighed isolates; can be type to determine weighed isolates; can be the algorithm to apply, either logical to indicate whether antibiotic interpretations with logical to indicate whether antibiotic interpretations with points until the comparison of key antibiotics will lead to inclusion of an isolate when minimum number of points to require before differences in the antibiogram will lead to inclusion of an isolate when arguments passed on to arguments passed on to A These functions are context-aware. This means that then the To conduct epidemiological analyses on antimicrobial resistance data, only so-called first isolates should be included to prevent overestimation and underestimation of antimicrobial resistance. Different algorithms can be used to do so, see below. These functions are context-aware. This means that then the The All isolates with a microbial ID of All isolates with a microbial ID of To conduct an analysis of antimicrobial resistance, you should only include the first isolate of every patient per episode (Hindler et al. 2007). 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 S. aureus isolates would be overestimated, because you included this MRSA more than once. It would be selection bias. According to Hindler et al. (2007, doi: 10.1086/511864
+), there are different algorithms to select first isolates with increasing reliability: isolate-based, patient-based, episode-based and phenotype-based. All algorithms select on a combination of the taxonomic genus and species (not subspecies). All mentioned algorithms are covered in the The functions The function The function This algorithm does not require any selection, as all isolates should be included. It does, however, respect all arguments set in the There are two ways to determine whether isolates can be included as first weighted isolates which will give generally the same results: Using Any difference from S to R (or vice versa) will (re)select an isolate as a first weighted isolate. With To include every genus-species combination per patient once, set the To include every genus-species combination per patient episode once, set the This is the most common algorithm to correct for duplicate isolates. Patients are categorised into episodes based on their ID and dates (e.g., the date of specimen receipt or laboratory result). While this is a common algorithm, it does not take into account antimicrobial test results. This means that e.g. a methicillin-resistant Staphylococcus aureus (MRSA) isolate cannot be differentiated from a wildtype Staphylococcus aureus isolate. This is a more reliable algorithm, since it also weighs the antibiogram (antimicrobial test results) yielding so-called 'first weighted isolates'. There are two different methods to weigh the antibiogram: Using 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 This method weighs all antimicrobial agents available in the data set. Any difference from I to S or R (or vice versa) counts as 0.5 points, a difference from S to R (or vice versa) counts as 1 point. When the sum of points exceeds All antimicrobials are internally selected using the Using This method only weighs specific antimicrobial agents, called key antimicrobials. Any difference from S to R (or vice versa) in these key antimicrobials will select an isolate as a first weighted isolate. With Key antimicrobials are internally selected using the The default algorithm is phenotype-based (using NEWS.md
-
-AMR 1.6.0.9009 Unreleased
+
+AMR 1.6.0.9010 Unreleased
-
-Last updated: 23 April 2021
+Last updated: 26 April 2021
@@ -250,6 +250,20 @@
custom_eucast_rules()
that brings support for custom AMR rules in eucast_rules()
+
+key_antimicrobials()
and all_antimicrobials()
have replaced the now deprecated function key_antibiotics()
+key_antimicrobials()
still only selects six preferred antibiotics for Gram-negatives, six for Gram-positives, and six universal antibiotics. It has a new antifungal
argument to set antifungal agents (antimycotics).first_isolate()
function gained the argument method
that has to be “phenotype-based”, “episode-based”, “patient-based”, or “isolate-based”. The old behaviour is equal to “episode-based”, while the new default is “phenotype-based”.type == "points"
in the first_isolate()
function for phenotype-based selection will now consider all antimicrobial drugs in the data set, using the new all_antimicrobials()
+first_isolate()
function can now take a vector of values for col_keyantibiotics
and can have an episode length of Inf
+filter_first_isolate()
function has not changed, as it uses the episode-based method. The filter_first_weighted_isolate()
may now include more isolates as uses the phenotype-based method.first_isolate()
and key_antimicrobials()
functions has been completely rewritten.example_isolates
data set now contains some (fictitious) zero-year old patientsdata.frame
or tibble
now gives a warning if the data contains old microbial codes (from a previous AMR package version)first_isolate()
can now take a vector of values for col_keyantibiotics
and can have an episode length of Inf
-like()
functions:
pattern
is a valid regular expressioninfo
argument to as.mo()
to turn on/off the progress barcol_mo
for some functions (esp. eucast_rules()
and mdro()
) could not be column names of the microorganisms
data set as it would throw an errorfirst_isolate()
with key antibiotics:
-
-
-type == "points"
, that now leads to inclusion of slightly more isolateskey_antibiotics_equal()
when using type == "points"
-first_isolate()
,key_antibiotics()
,key_antibiotics()
,
mdro()
,p.symbol()
to p_symbol()
(the former is now deprecated and will be removed in a future version)x
in age_groups()
will now introduce NA
s and not return an error anymorekey_antibiotics()
on foreign systemskey_antibiotics()
on foreign systemsmdr_tb()
scale_y_percent()
now contains the limits
argumentmdro()
, key_antibiotics()
and eucast_rules()
+mdro()
, key_antibiotics()
and eucast_rules()
resistance_predict()
function)as.mic()
to support more values ending in (several) zeroesp_symbol(p, emptychar = " ")
+ p_symbol(p, emptychar = " ")
+
+key_antibiotics(
+ x = NULL,
+ col_mo = NULL,
+ universal_1 = guess_ab_col(x, "amoxicillin"),
+ universal_2 = guess_ab_col(x, "amoxicillin/clavulanic acid"),
+ universal_3 = guess_ab_col(x, "cefuroxime"),
+ universal_4 = guess_ab_col(x, "piperacillin/tazobactam"),
+ universal_5 = guess_ab_col(x, "ciprofloxacin"),
+ universal_6 = guess_ab_col(x, "trimethoprim/sulfamethoxazole"),
+ GramPos_1 = guess_ab_col(x, "vancomycin"),
+ GramPos_2 = guess_ab_col(x, "teicoplanin"),
+ GramPos_3 = guess_ab_col(x, "tetracycline"),
+ GramPos_4 = guess_ab_col(x, "erythromycin"),
+ GramPos_5 = guess_ab_col(x, "oxacillin"),
+ GramPos_6 = guess_ab_col(x, "rifampin"),
+ GramNeg_1 = guess_ab_col(x, "gentamicin"),
+ GramNeg_2 = guess_ab_col(x, "tobramycin"),
+ GramNeg_3 = guess_ab_col(x, "colistin"),
+ GramNeg_4 = guess_ab_col(x, "cefotaxime"),
+ GramNeg_5 = guess_ab_col(x, "ceftazidime"),
+ GramNeg_6 = guess_ab_col(x, "meropenem"),
+ warnings = TRUE,
+ ...
+)
+
+key_antibiotics_equal(
+ y,
+ z,
+ type = "keyantimicrobials",
+ ignore_I = TRUE,
+ points_threshold = 2,
+ info = FALSE,
+ na.rm = TRUE,
+ ...
+)
Retired Lifecycle
diff --git a/docs/reference/ab_from_text.html b/docs/reference/ab_from_text.html
index 16981d6d..94b3f743 100644
--- a/docs/reference/ab_from_text.html
+++ b/docs/reference/ab_from_text.html
@@ -82,7 +82,7 @@
TRUE
/FALSE
) whether a ward or department is an Intensive Care Unit (ICU)
-
col_keyantibiotics
-
+ key_antibiotics()
. Defaults to the first column that starts with 'key' followed by 'ab' or 'antibiotics' (case insensitive). Use col_keyantibiotics = FALSE
to prevent this. Can also be the output of key_antibiotics()
.col_keyantimicrobials
+ method = "phenotype-based"
) column name of the key antimicrobials to determine first (weighted) isolates, see key_antimicrobials()
. Defaults to the first column that starts with 'key' followed by 'ab' or 'antibiotics' or 'antimicrobials' (case insensitive). Use col_keyantimicrobials = FALSE
to prevent this. Can also be the output of key_antimicrobials()
.
episode_days
@@ -334,15 +336,19 @@
+ type
-
+ "keyantibiotics"
or "points"
, see Details
+ "keyantimicrobials"
or "points"
, see Details
+
method
+ "phenotype-based"
, "episode-based"
, "patient-based"
or "isolate-based"
(can be abbreviated), see Details
ignore_I
-
+ "I"
will be ignored when type = "keyantibiotics"
, see Details"I"
will be ignored when type = "keyantimicrobials"
, see Details
points_threshold
-
+ type = "points"
, see Detailstype = "points"
, see Details
info
@@ -358,7 +364,7 @@
@@ -371,42 +377,69 @@
...
-
+ first_isolate()
when using filter_first_isolate()
, or arguments passed on to key_antibiotics()
when using filter_first_weighted_isolate()
first_isolate()
when using filter_first_isolate()
, or arguments passed on to key_antimicrobials()
otherwise (such as universal
, gram_negative
, gram_positive
)logical
vectorDetails
- x
argument can be left blank, see Examples.x
argument can be left blank, see Examples.first_isolate()
function is a wrapper around the is_new_episode()
function, but more efficient for data sets containing microorganism codes or names.NA
will be excluded as first isolate.Why this is so Important
+NA
will be excluded as first isolate.Different algorithms
-
+filter_*()
Shortcutsfirst_isolate()
function:
+
-
+Algorithm Function to apply
+Isolate-based first_isolate(x, method = "isolate-based")
+(= all isolates)
+
+
+Patient-based first_isolate(x, method = "patient-based")
+(= first isolate per patient)
+
+
+Episode-based first_isolate(x, method = "episode-based")
, or:
+(= first isolate per episode)
+- 7-Day interval from initial isolate - first_isolate(x, method = "e", episode_days = 7)
+- 30-Day interval from initial isolate - first_isolate(x, method = "e", episode_days = 30)
+
+
+Phenotype-based first_isolate(x, method = "phenotype-based")
, or:
+(= first isolate per phenotype)
+- Major difference in any antimicrobial result - first_isolate(x, type = "points")
+- Any difference in key antimicrobial results - first_isolate(x, type = "keyantimicrobials")
filter_first_isolate()
and filter_first_weighted_isolate()
are helper functions to quickly filter on first isolates.filter_first_isolate()
is essentially equal to either: x[first_isolate(x, ...), ]
-
- x %>% filter(first_isolate(...))
-
-
-filter_first_weighted_isolate()
is essentially equal to: x %>%
- mutate(keyab = key_antibiotics(.)) %>%
- mutate(only_weighted_firsts = first_isolate(x,
- col_keyantibiotics = "keyab", ...)) %>%
- filter(only_weighted_firsts == TRUE) %>%
- select(-only_weighted_firsts, -keyab)
-
+Isolate-based
- Key Antibiotics
+first_isolate()
function. For example, the default setting for include_unknown
(FALSE
) will omit selection of rows without a microbial ID.Patient-based
-
-
type = "keyantibiotics"
and argument ignore_I
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. Read more about this in the key_antibiotics()
function.episode_days
to Inf
. Although often inappropriate, this algorithm makes sure that no duplicate isolates are selected from the same patient.Episode-based
+
+
+episode_days
to a sensible number of days. Depending on the type of analysis, this could be 14, 30, 60 or 365. Short episodes are common for analysing specific hospital or ward data, long episodes are common for analysing regional and national data.Phenotype-based
+
+
+
+type = "points"
and argument points_threshold
points_threshold
, which defaults to 2
, an isolate will be (re)selected as a first weighted isolate.points_threshold
, which defaults to 2
, an isolate will be selected as a first weighted isolate.all_antimicrobials()
function. The output of this function does not need to be passed to the first_isolate()
function.type = "keyantimicrobials"
and argument ignore_I
ignore_I = FALSE
, also differences from I to S or R (or vice versa) will lead to this.key_antimicrobials()
function, but can also be added manually as a variable to the data and set in the col_keyantimicrobials
argument. Another option is to pass the output of the key_antimicrobials()
function directly to the col_keyantimicrobials
argument.type = "points"
) and episode-based (using episode_days = 365
). This makes sure that every genus-species combination is selected per patient once per year, while taking into account all antimicrobial test results.Stable Lifecycle
@@ -421,14 +454,13 @@ The lifecycle of this function is stableOn our website https://msberends.github.io/AMR/ you can find a comprehensive tutorial about how to conduct AMR data analysis, the complete documentation of all functions and an example analysis using WHONET data. As we would like to better understand the backgrounds and needs of our users, please participate in our survey!
# `example_isolates` is a data set available in the AMR package. # See ?example_isolates. example_isolates[first_isolate(example_isolates), ] - # \donttest{ # faster way, only works in R 3.2 and later: example_isolates[first_isolate(), ] @@ -466,7 +498,7 @@ The lifecycle of this function is stable# Have a look at A and B. # B is more reliable because every isolate is counted only once. - # Gentamicin resistance in hospital D appears to be 3.7% higher than + # Gentamicin resistance in hospital D appears to be 4.2% higher than # when you (erroneously) would have used all isolates for analysis. } # } diff --git a/docs/reference/index.html b/docs/reference/index.html index f8a17ecc..b310497e 100644 --- a/docs/reference/index.html +++ b/docs/reference/index.html @@ -81,7 +81,7 @@ @@ -496,9 +496,9 @@- + -+ Key Antibiotics for First (Weighted) Isolates
Deprecated Functions
@@ -667,7 +667,7 @@ diff --git a/docs/reference/key_antibiotics.html b/docs/reference/key_antimicrobials.html similarity index 59% rename from docs/reference/key_antibiotics.html rename to docs/reference/key_antimicrobials.html index 23646c27..770324ec 100644 --- a/docs/reference/key_antibiotics.html +++ b/docs/reference/key_antimicrobials.html @@ -6,7 +6,7 @@ - - + Deprecated Functions
Key Antibiotics for First (Weighted) Isolates — key_antibiotics • AMR (for R) +(Key) Antimicrobials for First Weighted Isolates — key_antimicrobials • AMR (for R) @@ -48,8 +48,8 @@ - - + + @@ -82,7 +82,7 @@ @@ -233,48 +233,39 @@diff --git a/docs/reference/microorganisms.html b/docs/reference/microorganisms.html index 327fa58f..bdf1e9f9 100644 --- a/docs/reference/microorganisms.html +++ b/docs/reference/microorganisms.html @@ -82,7 +82,7 @@ diff --git a/docs/sitemap.xml b/docs/sitemap.xml index f0c0e8de..90bec2ab 100644 --- a/docs/sitemap.xml +++ b/docs/sitemap.xml @@ -109,7 +109,7 @@diff --git a/docs/reference/mdro.html b/docs/reference/mdro.html index e53c5a0a..0acd9013 100644 --- a/docs/reference/mdro.html +++ b/docs/reference/mdro.html @@ -82,7 +82,7 @@-Key Antibiotics for First (Weighted) Isolates
- Source:R/key_antibiotics.R
-+key_antibiotics.Rd
(Key) Antimicrobials for First Weighted Isolates
+ Source:R/key_antimicrobials.R
+key_antimicrobials.Rd
--These function can be used to determine first isolates (see
+first_isolate()
). Using key antibiotics to determine first isolates is more reliable than without key antibiotics. These selected isolates can then be called first 'weighted' isolates.These functions can be used to determine first weighted isolates by considering the phenotype for isolate selection (see
first_isolate()
). Using a phenotype-based method to determine first isolates is more reliable than methods that disregard phenotypes.key_antibiotics( +key_antimicrobials( x = NULL, col_mo = NULL, - universal_1 = guess_ab_col(x, "amoxicillin"), - universal_2 = guess_ab_col(x, "amoxicillin/clavulanic acid"), - universal_3 = guess_ab_col(x, "cefuroxime"), - universal_4 = guess_ab_col(x, "piperacillin/tazobactam"), - universal_5 = guess_ab_col(x, "ciprofloxacin"), - universal_6 = guess_ab_col(x, "trimethoprim/sulfamethoxazole"), - GramPos_1 = guess_ab_col(x, "vancomycin"), - GramPos_2 = guess_ab_col(x, "teicoplanin"), - GramPos_3 = guess_ab_col(x, "tetracycline"), - GramPos_4 = guess_ab_col(x, "erythromycin"), - GramPos_5 = guess_ab_col(x, "oxacillin"), - GramPos_6 = guess_ab_col(x, "rifampin"), - GramNeg_1 = guess_ab_col(x, "gentamicin"), - GramNeg_2 = guess_ab_col(x, "tobramycin"), - GramNeg_3 = guess_ab_col(x, "colistin"), - GramNeg_4 = guess_ab_col(x, "cefotaxime"), - GramNeg_5 = guess_ab_col(x, "ceftazidime"), - GramNeg_6 = guess_ab_col(x, "meropenem"), - warnings = TRUE, + universal = c("ampicillin", "amoxicillin/clavulanic acid", "cefuroxime", + "piperacillin/tazobactam", "ciprofloxacin", "trimethoprim/sulfamethoxazole"), + gram_negative = c("gentamicin", "tobramycin", "colistin", "cefotaxime", + "ceftazidime", "meropenem"), + gram_positive = c("vancomycin", "teicoplanin", "tetracycline", "erythromycin", + "oxacillin", "rifampin"), + antifungal = c("anidulafungin", "caspofungin", "fluconazole", "miconazole", + "nystatin", "voriconazole"), + only_rsi_columns = FALSE, ... ) -key_antibiotics_equal( +all_antimicrobials(x = NULL, only_rsi_columns = FALSE, ...) + +antimicrobials_equal( y, z, - type = c("keyantibiotics", "points"), + type = c("points", "keyantimicrobials"), ignore_I = TRUE, points_threshold = 2, info = FALSE, - na.rm = TRUE, ... )@@ -290,24 +281,24 @@column name of the IDs of the microorganisms (see
as.mo()
), defaults to the first column of classmo
. Values will be coerced usingas.mo()
.- universal_1, universal_2, universal_3, universal_4, universal_5, universal_6 -+ column names of broad-spectrum antibiotics, case-insensitive. See details for which antibiotics will be used at default (which are guessed with
guess_ab_col()
).universal +names of broad-spectrum antimicrobial agents, case-insensitive. Set to
NULL
to ignore. See Details for the default agents.- GramPos_1, GramPos_2, GramPos_3, GramPos_4, GramPos_5, GramPos_6 -+ column names of antibiotics for Gram-positives, case-insensitive. See details for which antibiotics will be used at default (which are guessed with
guess_ab_col()
).gram_negative +names of antibiotic agents for Gram-positives, case-insensitive. Set to
NULL
to ignore. See Details for the default agents.- GramNeg_1, GramNeg_2, GramNeg_3, GramNeg_4, GramNeg_5, GramNeg_6 -+ column names of antibiotics for Gram-negatives, case-insensitive. See details for which antibiotics will be used at default (which are guessed with
guess_ab_col()
).gram_positive +names of antibiotic agents for Gram-negatives, case-insensitive. Set to
NULL
to ignore. See Details for the default agents.- warnings -+ give a warning about missing antibiotic columns (they will be ignored)
antifungal +names of antifungal agents for fungi, case-insensitive. Set to
NULL
to ignore. See Details for the default agents.... -+ other arguments passed on to functions
ignored, allows for future extensions
y, z @@ -315,62 +306,63 @@type -+ type to determine weighed isolates; can be
"keyantibiotics"
or"points"
, see Detailstype to determine weighed isolates; can be
"keyantimicrobials"
or"points"
, see Detailsignore_I -+ logical to indicate whether antibiotic interpretations with
"I"
will be ignored whentype = "keyantibiotics"
, see Detailslogical to indicate whether antibiotic interpretations with
"I"
will be ignored whentype = "keyantimicrobials"
, see Detailspoints_threshold -+ points until the comparison of key antibiotics will lead to inclusion of an isolate when
type = "points"
, see Detailsminimum number of points to require before differences in the antibiogram will lead to inclusion of an isolate when
type = "points"
, see Details- info unused - previously used to indicate whether a progress bar should print
- na.rm -- a logical to indicate whether comparison with
NA
should returnFALSE
(defaults toTRUE
for backwards compatibility)Details
-The
-key_antibiotics()
function is context-aware. This means that then thex
argument can be left blank, see Examples.The function
-key_antibiotics()
returns a character vector with 12 antibiotic results for every isolate. These isolates can then be compared usingkey_antibiotics_equal()
, to check if two isolates have generally the same antibiogram. Missing and invalid values are replaced with a dot ("."
) bykey_antibiotics()
and ignored bykey_antibiotics_equal()
.The
-first_isolate()
function only uses this function on the same microbial species from the same patient. Using this, e.g. an MRSA will be included after a susceptible S. aureus (MSSA) is found within the same patient episode. Without key antibiotic comparison it would not. Seefirst_isolate()
for more info.At default, the antibiotics that are used for Gram-positive bacteria are:
-
- +
Amoxicillin
The
+key_antimicrobials()
andall_antimicrobials()
functions are context-aware. This means that then thex
argument can be left blank, see Examples.The function
+key_antimicrobials()
returns a character vector with 12 antimicrobial results for every isolate. The functionall_antimicrobials()
returns a character vector with all antimicrobial results for every isolate. These vectors can then be compared usingantimicrobials_equal()
, to check if two isolates have generally the same antibiogram. Missing and invalid values are replaced with a dot ("."
) bykey_antimicrobials()
and ignored byantimicrobials_equal()
.Please see the
+first_isolate()
function how these important functions enable the 'phenotype-based' method for determination of first isolates.The default antimicrobial agents used for all rows (set in
universal
) are:+
+ +Ampicillin
Amoxicillin/clavulanic acid
- -
Cefuroxime
Piperacillin/tazobactam
- +
Ciprofloxacin
Piperacillin/tazobactam
- -
Trimethoprim/sulfamethoxazole
- -
Vancomycin
- -
Teicoplanin
- +
Tetracycline
The default antimicrobial agents used for Gram-negative bacteria (set in
gram_negative
) are:+
+ +- +
Cefotaxime
- +
Ceftazidime
- +
Colistin
- +
Gentamicin
- +
Meropenem
- +
Tobramycin
The default antimicrobial agents used for Gram-positive bacteria (set in
gram_positive
) are:-
Erythromycin
Oxacillin
- +
Rifampin
- +
Teicoplanin
- +
Tetracycline
Vancomycin
At default the antibiotics that are used for Gram-negative bacteria are:
-
- -
Amoxicillin
- -
Amoxicillin/clavulanic acid
- -
Cefuroxime
- -
Piperacillin/tazobactam
- -
Ciprofloxacin
- -
Trimethoprim/sulfamethoxazole
- -
Gentamicin
- -
Tobramycin
- -
Colistin
- -
Cefotaxime
- -
Ceftazidime
- +
Meropenem
The default antimicrobial agents used for fungi (set in
antifungal
) are:+
-- +
Anidulafungin
- +
Caspofungin
- +
Fluconazole
- +
Miconazole
- +
Nystatin
Voriconazole
The function
key_antibiotics_equal()
checks the characters returned bykey_antibiotics()
for equality, and returns alogical
vector.Stable Lifecycle
@@ -378,17 +370,6 @@
The lifecycle of this function is stable. In a stable function, major changes are unlikely. This means that the unlying code will generally evolve by adding new arguments; removing arguments or changing the meaning of existing arguments will be avoided.If the unlying code needs breaking changes, they will occur gradually. For example, a argument will be deprecated and first continue to work, but will emit an message informing you of the change. Next, typically after at least one newly released version on CRAN, the message will be transformed to an error.
-Key Antibiotics
- - - -There are two ways to determine whether isolates can be included as first weighted isolates which will give generally the same results:
-
-- -
Using
-type = "keyantibiotics"
and argumentignore_I
Any difference from S to R (or vice versa) will (re)select an isolate as a first weighted isolate. With
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. Read more about this in thekey_antibiotics()
function.- -
Using
-type = "points"
and argumentpoints_threshold
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
points_threshold
, which defaults to2
, an isolate will be (re)selected as a first weighted isolate.Read more on Our Website!
@@ -402,30 +383,30 @@ The lifecycle of this function is stable# `example_isolates` is a data set available in the AMR package. # See ?example_isolates. -# output of the `key_antibiotics()` function could be like this: +# output of the `key_antimicrobials()` function could be like this: strainA <- "SSSRR.S.R..S" strainB <- "SSSIRSSSRSSS" # those strings can be compared with: -key_antibiotics_equal(strainA, strainB) +antimicrobials_equal(strainA, strainB, type = "keyantimicrobials") # TRUE, because I is ignored (as well as missing values) -key_antibiotics_equal(strainA, strainB, ignore_I = FALSE) +antimicrobials_equal(strainA, strainB, type = "keyantimicrobials", ignore_I = FALSE) # FALSE, because I is not ignored and so the 4th character differs # \donttest{ if (require("dplyr")) { # set key antibiotics to a new variable my_patients <- example_isolates %>% - mutate(keyab = key_antibiotics()) %>% # no need to define `x` + mutate(keyab = key_antimicrobials(antifungal = NULL)) %>% # no need to define `x` mutate( # now calculate first isolates - first_regular = first_isolate(col_keyantibiotics = FALSE), + first_regular = first_isolate(col_keyantimicrobials = FALSE), # and first WEIGHTED isolates - first_weighted = first_isolate(col_keyantibiotics = "keyab") + first_weighted = first_isolate(col_keyantimicrobials = "keyab") ) - # Check the difference, in this data set it results in a lot more isolates: + # Check the difference, in this data set it results in more isolates: sum(my_patients$first_regular, na.rm = TRUE) sum(my_patients$first_weighted, na.rm = TRUE) } diff --git a/docs/reference/like.html b/docs/reference/like.html index f978776c..f8998870 100644 --- a/docs/reference/like.html +++ b/docs/reference/like.html @@ -82,7 +82,7 @@https://msberends.github.io/AMR//reference/join.html - https://msberends.github.io/AMR//reference/key_antibiotics.html +https://msberends.github.io/AMR//reference/key_antimicrobials.html https://msberends.github.io/AMR//reference/kurtosis.html diff --git a/docs/survey.html b/docs/survey.html index e98c581a..1da3feb9 100644 --- a/docs/survey.html +++ b/docs/survey.html @@ -81,7 +81,7 @@ diff --git a/man/AMR-deprecated.Rd b/man/AMR-deprecated.Rd index fa717930..7145536b 100644 --- a/man/AMR-deprecated.Rd +++ b/man/AMR-deprecated.Rd @@ -3,9 +3,47 @@ \name{AMR-deprecated} \alias{AMR-deprecated} \alias{p_symbol} +\alias{key_antibiotics} +\alias{key_antibiotics_equal} \title{Deprecated Functions} \usage{ p_symbol(p, emptychar = " ") + +key_antibiotics( + x = NULL, + col_mo = NULL, + universal_1 = guess_ab_col(x, "amoxicillin"), + universal_2 = guess_ab_col(x, "amoxicillin/clavulanic acid"), + universal_3 = guess_ab_col(x, "cefuroxime"), + universal_4 = guess_ab_col(x, "piperacillin/tazobactam"), + universal_5 = guess_ab_col(x, "ciprofloxacin"), + universal_6 = guess_ab_col(x, "trimethoprim/sulfamethoxazole"), + GramPos_1 = guess_ab_col(x, "vancomycin"), + GramPos_2 = guess_ab_col(x, "teicoplanin"), + GramPos_3 = guess_ab_col(x, "tetracycline"), + GramPos_4 = guess_ab_col(x, "erythromycin"), + GramPos_5 = guess_ab_col(x, "oxacillin"), + GramPos_6 = guess_ab_col(x, "rifampin"), + GramNeg_1 = guess_ab_col(x, "gentamicin"), + GramNeg_2 = guess_ab_col(x, "tobramycin"), + GramNeg_3 = guess_ab_col(x, "colistin"), + GramNeg_4 = guess_ab_col(x, "cefotaxime"), + GramNeg_5 = guess_ab_col(x, "ceftazidime"), + GramNeg_6 = guess_ab_col(x, "meropenem"), + warnings = TRUE, + ... +) + +key_antibiotics_equal( + y, + z, + type = "keyantimicrobials", + ignore_I = TRUE, + points_threshold = 2, + info = FALSE, + na.rm = TRUE, + ... +) } \description{ These functions are so-called '\link{Deprecated}'. They will be removed in a future release. Using the functions will give a warning with the name of the function it has been replaced by (if there is one). diff --git a/man/first_isolate.Rd b/man/first_isolate.Rd index 048e47c2..db51fb10 100755 --- a/man/first_isolate.Rd +++ b/man/first_isolate.Rd @@ -19,12 +19,13 @@ first_isolate( col_testcode = NULL, col_specimen = NULL, col_icu = NULL, - col_keyantibiotics = NULL, + col_keyantimicrobials = NULL, episode_days = 365, testcodes_exclude = NULL, icu_exclude = FALSE, specimen_group = NULL, - type = "keyantibiotics", + type = "points", + method = c("phenotype-based", "episode-based", "patient-based", "isolate-based"), ignore_I = TRUE, points_threshold = 2, info = interactive(), @@ -38,6 +39,7 @@ filter_first_isolate( col_date = NULL, col_patient_id = NULL, col_mo = NULL, + method = "episode-based", ... ) @@ -46,7 +48,7 @@ filter_first_weighted_isolate( col_date = NULL, col_patient_id = NULL, col_mo = NULL, - col_keyantibiotics = NULL, + method = "phenotype-based", ... ) } @@ -65,7 +67,7 @@ filter_first_weighted_isolate( \item{col_icu}{column name of the logicals (\code{TRUE}/\code{FALSE}) whether a ward or department is an Intensive Care Unit (ICU)} -\item{col_keyantibiotics}{column name of the key antibiotics to determine first (weighted) isolates, see \code{\link[=key_antibiotics]{key_antibiotics()}}. Defaults to the first column that starts with 'key' followed by 'ab' or 'antibiotics' (case insensitive). Use \code{col_keyantibiotics = FALSE} to prevent this. Can also be the output of \code{\link[=key_antibiotics]{key_antibiotics()}}.} +\item{col_keyantimicrobials}{(only useful when \code{method = "phenotype-based"}) column name of the key antimicrobials to determine first (weighted) isolates, see \code{\link[=key_antimicrobials]{key_antimicrobials()}}. Defaults to the first column that starts with 'key' followed by 'ab' or 'antibiotics' or 'antimicrobials' (case insensitive). Use \code{col_keyantimicrobials = FALSE} to prevent this. Can also be the output of \code{\link[=key_antimicrobials]{key_antimicrobials()}}.} \item{episode_days}{episode in days after which a genus/species combination will be determined as 'first isolate' again. The default of 365 days is based on the guideline by CLSI, see \emph{Source}.} @@ -75,11 +77,13 @@ filter_first_weighted_isolate( \item{specimen_group}{value in the column set with \code{col_specimen} to filter on} -\item{type}{type to determine weighed isolates; can be \code{"keyantibiotics"} or \code{"points"}, see \emph{Details}} +\item{type}{type to determine weighed isolates; can be \code{"keyantimicrobials"} or \code{"points"}, see \emph{Details}} -\item{ignore_I}{logical to indicate whether antibiotic interpretations with \code{"I"} will be ignored when \code{type = "keyantibiotics"}, see \emph{Details}} +\item{method}{the algorithm to apply, either \code{"phenotype-based"}, \code{"episode-based"}, \code{"patient-based"} or \code{"isolate-based"} (can be abbreviated), see \emph{Details}} -\item{points_threshold}{points until the comparison of key antibiotics will lead to inclusion of an isolate when \code{type = "points"}, see \emph{Details}} +\item{ignore_I}{logical to indicate whether antibiotic interpretations with \code{"I"} will be ignored when \code{type = "keyantimicrobials"}, see \emph{Details}} + +\item{points_threshold}{minimum number of points to require before differences in the antibiogram will lead to inclusion of an isolate when \code{type = "points"}, see \emph{Details}} \item{info}{a \link{logical} to indicate info should be printed, defaults to \code{TRUE} only in interactive mode} @@ -87,7 +91,7 @@ filter_first_weighted_isolate( \item{include_untested_rsi}{logical to indicate whether also rows without antibiotic results are still eligible for becoming a first isolate. Use \code{include_untested_rsi = FALSE} to always return \code{FALSE} for such rows. This checks the data set for columns of class \verb{} and consequently requires transforming columns with antibiotic results using \code{\link[=as.rsi]{as.rsi()}} first.} -\item{...}{arguments passed on to \code{\link[=first_isolate]{first_isolate()}} when using \code{\link[=filter_first_isolate]{filter_first_isolate()}}, or arguments passed on to \code{\link[=key_antibiotics]{key_antibiotics()}} when using \code{\link[=filter_first_weighted_isolate]{filter_first_weighted_isolate()}}} +\item{...}{arguments passed on to \code{\link[=first_isolate]{first_isolate()}} when using \code{\link[=filter_first_isolate]{filter_first_isolate()}}, or arguments passed on to \code{\link[=key_antimicrobials]{key_antimicrobials()}} otherwise (such as \code{universal}, \code{gram_negative}, \code{gram_positive})} } \value{ A \code{\link{logical}} vector @@ -96,47 +100,77 @@ A \code{\link{logical}} vector Determine first (weighted) isolates of all microorganisms of every patient per episode and (if needed) per specimen type. To determine patient episodes not necessarily based on microorganisms, use \code{\link[=is_new_episode]{is_new_episode()}} that also supports grouping with the \code{dplyr} package. } \details{ +To conduct epidemiological analyses on antimicrobial resistance data, only so-called first isolates should be included to prevent overestimation and underestimation of antimicrobial resistance. Different algorithms can be used to do so, see below. + These functions are context-aware. This means that then the \code{x} argument can be left blank, see \emph{Examples}. The \code{\link[=first_isolate]{first_isolate()}} function is a wrapper around the \code{\link[=is_new_episode]{is_new_episode()}} function, but more efficient for data sets containing microorganism codes or names. All isolates with a microbial ID of \code{NA} will be excluded as first isolate. -\subsection{Why this is so Important}{ +\subsection{Different algorithms}{ -To conduct an analysis of antimicrobial resistance, you should only include the first isolate of every patient per episode \href{https://pubmed.ncbi.nlm.nih.gov/17304462/}{(Hindler \emph{et al.} 2007)}. 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}. +According to Hindler \emph{et al.} (2007, \doi{10.1086/511864}), there are different algorithms to select first isolates with increasing reliability: isolate-based, patient-based, episode-based and phenotype-based. All algorithms select on a combination of the taxonomic genus and species (not subspecies). + +All mentioned algorithms are covered in the \code{\link[=first_isolate]{first_isolate()}} function:\tabular{ll}{ + \strong{Algorithm} \tab \strong{Function to apply} \cr + Isolate-based \tab \code{first_isolate(x, method = "isolate-based")} \cr + \emph{(= all isolates)} \tab \cr + \tab \cr + \tab \cr + Patient-based \tab \code{first_isolate(x, method = "patient-based")} \cr + \emph{(= first isolate per patient)} \tab \cr + \tab \cr + \tab \cr + Episode-based \tab \code{first_isolate(x, method = "episode-based")}, or: \cr + \emph{(= first isolate per episode)} \tab \cr + - 7-Day interval from initial isolate \tab - \code{first_isolate(x, method = "e", episode_days = 7)} \cr + - 30-Day interval from initial isolate \tab - \code{first_isolate(x, method = "e", episode_days = 30)} \cr + \tab \cr + \tab \cr + Phenotype-based \tab \code{first_isolate(x, method = "phenotype-based")}, or: \cr + \emph{(= first isolate per phenotype)} \tab \cr + - Major difference in any antimicrobial result \tab - \code{first_isolate(x, type = "points")} \cr + - Any difference in key antimicrobial results \tab - \code{first_isolate(x, type = "keyantimicrobials")} \cr } -\subsection{\verb{filter_*()} Shortcuts}{ +\subsection{Isolate-based}{ -The functions \code{\link[=filter_first_isolate]{filter_first_isolate()}} and \code{\link[=filter_first_weighted_isolate]{filter_first_weighted_isolate()}} are helper functions to quickly filter on first isolates. - -The function \code{\link[=filter_first_isolate]{filter_first_isolate()}} is essentially equal to either:\preformatted{ x[first_isolate(x, ...), ] - - x \%>\% filter(first_isolate(...)) +This algorithm does not require any selection, as all isolates should be included. It does, however, respect all arguments set in the \code{\link[=first_isolate]{first_isolate()}} function. For example, the default setting for \code{include_unknown} (\code{FALSE}) will omit selection of rows without a microbial ID. } -The function \code{\link[=filter_first_weighted_isolate]{filter_first_weighted_isolate()}} is essentially equal to:\preformatted{ x \%>\% - mutate(keyab = key_antibiotics(.)) \%>\% - mutate(only_weighted_firsts = first_isolate(x, - col_keyantibiotics = "keyab", ...)) \%>\% - filter(only_weighted_firsts == TRUE) \%>\% - select(-only_weighted_firsts, -keyab) -} -} -} -\section{Key Antibiotics}{ +\subsection{Patient-based}{ -There are two ways to determine whether isolates can be included as first weighted isolates which will give generally the same results: +To include every genus-species combination per patient once, set the \code{episode_days} to \code{Inf}. Although often inappropriate, this algorithm makes sure that no duplicate isolates are selected from the same patient. +} + +\subsection{Episode-based}{ + +To include every genus-species combination per patient episode once, set the \code{episode_days} to a sensible number of days. Depending on the type of analysis, this could be 14, 30, 60 or 365. Short episodes are common for analysing specific hospital or ward data, long episodes are common for analysing regional and national data. + +This is the most common algorithm to correct for duplicate isolates. Patients are categorised into episodes based on their ID and dates (e.g., the date of specimen receipt or laboratory result). While this is a common algorithm, it does not take into account antimicrobial test results. This means that e.g. a methicillin-resistant \emph{Staphylococcus aureus} (MRSA) isolate cannot be differentiated from a wildtype \emph{Staphylococcus aureus} isolate. +} + +\subsection{Phenotype-based}{ + +This is a more reliable algorithm, since it also \emph{weighs} the antibiogram (antimicrobial test results) yielding so-called 'first weighted isolates'. There are two different methods to weigh the antibiogram: \enumerate{ -\item Using \code{type = "keyantibiotics"} and argument \code{ignore_I} - -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. Read more about this in the \code{\link[=key_antibiotics]{key_antibiotics()}} function. \item Using \code{type = "points"} and argument \code{points_threshold} -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}, which defaults to \code{2}, an isolate will be (re)selected as a first weighted isolate. -} +This method weighs \emph{all} antimicrobial agents available in the data set. Any difference from I to S or R (or vice versa) counts as 0.5 points, a difference from S to R (or vice versa) counts as 1 point. When the sum of points exceeds \code{points_threshold}, which defaults to \code{2}, an isolate will be selected as a first weighted isolate. + +All antimicrobials are internally selected using the \code{\link[=all_antimicrobials]{all_antimicrobials()}} function. The output of this function does not need to be passed to the \code{\link[=first_isolate]{first_isolate()}} function. +\item Using \code{type = "keyantimicrobials"} and argument \code{ignore_I} + +This method only weighs specific antimicrobial agents, called \emph{key antimicrobials}. Any difference from S to R (or vice versa) in these key antimicrobials will select an isolate as a first weighted isolate. With \code{ignore_I = FALSE}, also differences from I to S or R (or vice versa) will lead to this. + +Key antimicrobials are internally selected using the \code{\link[=key_antimicrobials]{key_antimicrobials()}} function, but can also be added manually as a variable to the data and set in the \code{col_keyantimicrobials} argument. Another option is to pass the output of the \code{\link[=key_antimicrobials]{key_antimicrobials()}} function directly to the \code{col_keyantimicrobials} argument. } +The default algorithm is phenotype-based (using \code{type = "points"}) and episode-based (using \code{episode_days = 365}). This makes sure that every genus-species combination is selected per patient once per year, while taking into account all antimicrobial test results. +} + +} +} \section{Stable Lifecycle}{ \if{html}{\figure{lifecycle_stable.svg}{options: style=margin-bottom:5px} \cr} @@ -155,7 +189,6 @@ On our website \url{https://msberends.github.io/AMR/} you can find \href{https:/ # See ?example_isolates. example_isolates[first_isolate(example_isolates), ] - \donttest{ # faster way, only works in R 3.2 and later: example_isolates[first_isolate(), ] @@ -193,11 +226,11 @@ if (require("dplyr")) { # Have a look at A and B. # B is more reliable because every isolate is counted only once. - # Gentamicin resistance in hospital D appears to be 3.7\% higher than + # Gentamicin resistance in hospital D appears to be 4.2\% higher than # when you (erroneously) would have used all isolates for analysis. } } } \seealso{ -\code{\link[=key_antibiotics]{key_antibiotics()}} +\code{\link[=key_antimicrobials]{key_antimicrobials()}} } diff --git a/man/key_antibiotics.Rd b/man/key_antibiotics.Rd deleted file mode 100755 index 13c3ac52..00000000 --- a/man/key_antibiotics.Rd +++ /dev/null @@ -1,176 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/key_antibiotics.R -\name{key_antibiotics} -\alias{key_antibiotics} -\alias{key_antibiotics_equal} -\title{Key Antibiotics for First (Weighted) Isolates} -\usage{ -key_antibiotics( - x = NULL, - col_mo = NULL, - universal_1 = guess_ab_col(x, "amoxicillin"), - universal_2 = guess_ab_col(x, "amoxicillin/clavulanic acid"), - universal_3 = guess_ab_col(x, "cefuroxime"), - universal_4 = guess_ab_col(x, "piperacillin/tazobactam"), - universal_5 = guess_ab_col(x, "ciprofloxacin"), - universal_6 = guess_ab_col(x, "trimethoprim/sulfamethoxazole"), - GramPos_1 = guess_ab_col(x, "vancomycin"), - GramPos_2 = guess_ab_col(x, "teicoplanin"), - GramPos_3 = guess_ab_col(x, "tetracycline"), - GramPos_4 = guess_ab_col(x, "erythromycin"), - GramPos_5 = guess_ab_col(x, "oxacillin"), - GramPos_6 = guess_ab_col(x, "rifampin"), - GramNeg_1 = guess_ab_col(x, "gentamicin"), - GramNeg_2 = guess_ab_col(x, "tobramycin"), - GramNeg_3 = guess_ab_col(x, "colistin"), - GramNeg_4 = guess_ab_col(x, "cefotaxime"), - GramNeg_5 = guess_ab_col(x, "ceftazidime"), - GramNeg_6 = guess_ab_col(x, "meropenem"), - warnings = TRUE, - ... -) - -key_antibiotics_equal( - y, - z, - type = c("keyantibiotics", "points"), - ignore_I = TRUE, - points_threshold = 2, - info = FALSE, - na.rm = TRUE, - ... -) -} -\arguments{ -\item{x}{a \link{data.frame} with antibiotics columns, like \code{AMX} or \code{amox}. Can be left blank to determine automatically} - -\item{col_mo}{column name of the IDs of the microorganisms (see \code{\link[=as.mo]{as.mo()}}), defaults to the first column of class \code{\link{mo}}. Values will be coerced using \code{\link[=as.mo]{as.mo()}}.} - -\item{universal_1, universal_2, universal_3, universal_4, universal_5, universal_6}{column names of \strong{broad-spectrum} antibiotics, case-insensitive. See details for which antibiotics will be used at default (which are guessed with \code{\link[=guess_ab_col]{guess_ab_col()}}).} - -\item{GramPos_1, GramPos_2, GramPos_3, GramPos_4, GramPos_5, GramPos_6}{column names of antibiotics for \strong{Gram-positives}, case-insensitive. See details for which antibiotics will be used at default (which are guessed with \code{\link[=guess_ab_col]{guess_ab_col()}}).} - -\item{GramNeg_1, GramNeg_2, GramNeg_3, GramNeg_4, GramNeg_5, GramNeg_6}{column names of antibiotics for \strong{Gram-negatives}, case-insensitive. See details for which antibiotics will be used at default (which are guessed with \code{\link[=guess_ab_col]{guess_ab_col()}}).} - -\item{warnings}{give a warning about missing antibiotic columns (they will be ignored)} - -\item{...}{other arguments passed on to functions} - -\item{y, z}{character vectors to compare} - -\item{type}{type to determine weighed isolates; can be \code{"keyantibiotics"} or \code{"points"}, see \emph{Details}} - -\item{ignore_I}{logical to indicate whether antibiotic interpretations with \code{"I"} will be ignored when \code{type = "keyantibiotics"}, see \emph{Details}} - -\item{points_threshold}{points until the comparison of key antibiotics will lead to inclusion of an isolate when \code{type = "points"}, see \emph{Details}} - -\item{info}{unused - previously used to indicate whether a progress bar should print} - -\item{na.rm}{a \link{logical} to indicate whether comparison with \code{NA} should return \code{FALSE} (defaults to \code{TRUE} for backwards compatibility)} -} -\description{ -These function can be used to determine first isolates (see \code{\link[=first_isolate]{first_isolate()}}). Using key antibiotics to determine first isolates is more reliable than without key antibiotics. These selected isolates can then be called first 'weighted' isolates. -} -\details{ -The \code{\link[=key_antibiotics]{key_antibiotics()}} function is context-aware. This means that then the \code{x} argument can be left blank, see \emph{Examples}. - -The function \code{\link[=key_antibiotics]{key_antibiotics()}} returns a character vector with 12 antibiotic results for every isolate. These isolates can then be compared using \code{\link[=key_antibiotics_equal]{key_antibiotics_equal()}}, to check if two isolates have generally the same antibiogram. Missing and invalid values are replaced with a dot (\code{"."}) by \code{\link[=key_antibiotics]{key_antibiotics()}} and ignored by \code{\link[=key_antibiotics_equal]{key_antibiotics_equal()}}. - -The \code{\link[=first_isolate]{first_isolate()}} function only uses this function on the same microbial species from the same patient. Using this, e.g. an MRSA will be included after a susceptible \emph{S. aureus} (MSSA) is found within the same patient episode. Without key antibiotic comparison it would not. See \code{\link[=first_isolate]{first_isolate()}} for more info. - -At default, the antibiotics that are used for \strong{Gram-positive bacteria} are: -\itemize{ -\item Amoxicillin -\item Amoxicillin/clavulanic acid -\item Cefuroxime -\item Piperacillin/tazobactam -\item Ciprofloxacin -\item Trimethoprim/sulfamethoxazole -\item Vancomycin -\item Teicoplanin -\item Tetracycline -\item Erythromycin -\item Oxacillin -\item Rifampin -} - -At default the antibiotics that are used for \strong{Gram-negative bacteria} are: -\itemize{ -\item Amoxicillin -\item Amoxicillin/clavulanic acid -\item Cefuroxime -\item Piperacillin/tazobactam -\item Ciprofloxacin -\item Trimethoprim/sulfamethoxazole -\item Gentamicin -\item Tobramycin -\item Colistin -\item Cefotaxime -\item Ceftazidime -\item Meropenem -} - -The function \code{\link[=key_antibiotics_equal]{key_antibiotics_equal()}} checks the characters returned by \code{\link[=key_antibiotics]{key_antibiotics()}} for equality, and returns a \code{\link{logical}} vector. -} -\section{Stable Lifecycle}{ - -\if{html}{\figure{lifecycle_stable.svg}{options: style=margin-bottom:5px} \cr} -The \link[=lifecycle]{lifecycle} of this function is \strong{stable}. In a stable function, major changes are unlikely. This means that the unlying code will generally evolve by adding new arguments; removing arguments or changing the meaning of existing arguments will be avoided. - -If the unlying code needs breaking changes, they will occur gradually. For example, a argument will be deprecated and first continue to work, but will emit an message informing you of the change. Next, typically after at least one newly released version on CRAN, the message will be transformed to an error. -} - -\section{Key Antibiotics}{ - -There are two ways to determine whether isolates can be included as first weighted isolates which will give generally the same results: -\enumerate{ -\item Using \code{type = "keyantibiotics"} and argument \code{ignore_I} - -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. Read more about this in the \code{\link[=key_antibiotics]{key_antibiotics()}} function. -\item Using \code{type = "points"} and argument \code{points_threshold} - -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}, which defaults to \code{2}, an isolate will be (re)selected as a first weighted isolate. -} -} - -\section{Read more on Our Website!}{ - -On our website \url{https://msberends.github.io/AMR/} you can find \href{https://msberends.github.io/AMR/articles/AMR.html}{a comprehensive tutorial} about how to conduct AMR data analysis, the \href{https://msberends.github.io/AMR/reference/}{complete documentation of all functions} and \href{https://msberends.github.io/AMR/articles/WHONET.html}{an example analysis using WHONET data}. As we would like to better understand the backgrounds and needs of our users, please \href{https://msberends.github.io/AMR/survey.html}{participate in our survey}! -} - -\examples{ -# `example_isolates` is a data set available in the AMR package. -# See ?example_isolates. - -# output of the `key_antibiotics()` function could be like this: -strainA <- "SSSRR.S.R..S" -strainB <- "SSSIRSSSRSSS" - -# those strings can be compared with: -key_antibiotics_equal(strainA, strainB) -# TRUE, because I is ignored (as well as missing values) - -key_antibiotics_equal(strainA, strainB, ignore_I = FALSE) -# FALSE, because I is not ignored and so the 4th character differs - -\donttest{ -if (require("dplyr")) { - # set key antibiotics to a new variable - my_patients <- example_isolates \%>\% - mutate(keyab = key_antibiotics()) \%>\% # no need to define `x` - mutate( - # now calculate first isolates - first_regular = first_isolate(col_keyantibiotics = FALSE), - # and first WEIGHTED isolates - first_weighted = first_isolate(col_keyantibiotics = "keyab") - ) - - # Check the difference, in this data set it results in a lot more isolates: - sum(my_patients$first_regular, na.rm = TRUE) - sum(my_patients$first_weighted, na.rm = TRUE) -} -} -} -\seealso{ -\code{\link[=first_isolate]{first_isolate()}} -} diff --git a/man/key_antimicrobials.Rd b/man/key_antimicrobials.Rd new file mode 100644 index 00000000..ba992c9a --- /dev/null +++ b/man/key_antimicrobials.Rd @@ -0,0 +1,159 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/key_antimicrobials.R +\name{key_antimicrobials} +\alias{key_antimicrobials} +\alias{all_antimicrobials} +\alias{antimicrobials_equal} +\title{(Key) Antimicrobials for First Weighted Isolates} +\usage{ +key_antimicrobials( + x = NULL, + col_mo = NULL, + universal = c("ampicillin", "amoxicillin/clavulanic acid", "cefuroxime", + "piperacillin/tazobactam", "ciprofloxacin", "trimethoprim/sulfamethoxazole"), + gram_negative = c("gentamicin", "tobramycin", "colistin", "cefotaxime", + "ceftazidime", "meropenem"), + gram_positive = c("vancomycin", "teicoplanin", "tetracycline", "erythromycin", + "oxacillin", "rifampin"), + antifungal = c("anidulafungin", "caspofungin", "fluconazole", "miconazole", + "nystatin", "voriconazole"), + only_rsi_columns = FALSE, + ... +) + +all_antimicrobials(x = NULL, only_rsi_columns = FALSE, ...) + +antimicrobials_equal( + y, + z, + type = c("points", "keyantimicrobials"), + ignore_I = TRUE, + points_threshold = 2, + info = FALSE, + ... +) +} +\arguments{ +\item{x}{a \link{data.frame} with antibiotics columns, like \code{AMX} or \code{amox}. Can be left blank to determine automatically} + +\item{col_mo}{column name of the IDs of the microorganisms (see \code{\link[=as.mo]{as.mo()}}), defaults to the first column of class \code{\link{mo}}. Values will be coerced using \code{\link[=as.mo]{as.mo()}}.} + +\item{universal}{names of \strong{broad-spectrum} antimicrobial agents, case-insensitive. Set to \code{NULL} to ignore. See \emph{Details} for the default agents.} + +\item{gram_negative}{names of antibiotic agents for \strong{Gram-positives}, case-insensitive. Set to \code{NULL} to ignore. See \emph{Details} for the default agents.} + +\item{gram_positive}{names of antibiotic agents for \strong{Gram-negatives}, case-insensitive. Set to \code{NULL} to ignore. See \emph{Details} for the default agents.} + +\item{antifungal}{names of antifungal agents for \strong{fungi}, case-insensitive. Set to \code{NULL} to ignore. See \emph{Details} for the default agents.} + +\item{...}{ignored, allows for future extensions} + +\item{y, z}{character vectors to compare} + +\item{type}{type to determine weighed isolates; can be \code{"keyantimicrobials"} or \code{"points"}, see \emph{Details}} + +\item{ignore_I}{logical to indicate whether antibiotic interpretations with \code{"I"} will be ignored when \code{type = "keyantimicrobials"}, see \emph{Details}} + +\item{points_threshold}{minimum number of points to require before differences in the antibiogram will lead to inclusion of an isolate when \code{type = "points"}, see \emph{Details}} + +\item{info}{unused - previously used to indicate whether a progress bar should print} +} +\description{ +These functions can be used to determine first weighted isolates by considering the phenotype for isolate selection (see \code{\link[=first_isolate]{first_isolate()}}). Using a phenotype-based method to determine first isolates is more reliable than methods that disregard phenotypes. +} +\details{ +The \code{\link[=key_antimicrobials]{key_antimicrobials()}} and \code{\link[=all_antimicrobials]{all_antimicrobials()}} functions are context-aware. This means that then the \code{x} argument can be left blank, see \emph{Examples}. + +The function \code{\link[=key_antimicrobials]{key_antimicrobials()}} returns a character vector with 12 antimicrobial results for every isolate. The function \code{\link[=all_antimicrobials]{all_antimicrobials()}} returns a character vector with all antimicrobial results for every isolate. These vectors can then be compared using \code{\link[=antimicrobials_equal]{antimicrobials_equal()}}, to check if two isolates have generally the same antibiogram. Missing and invalid values are replaced with a dot (\code{"."}) by \code{\link[=key_antimicrobials]{key_antimicrobials()}} and ignored by \code{\link[=antimicrobials_equal]{antimicrobials_equal()}}. + +Please see the \code{\link[=first_isolate]{first_isolate()}} function how these important functions enable the 'phenotype-based' method for determination of first isolates. + +The default antimicrobial agents used for \strong{all rows} (set in \code{universal}) are: +\itemize{ +\item Ampicillin +\item Amoxicillin/clavulanic acid +\item Cefuroxime +\item Ciprofloxacin +\item Piperacillin/tazobactam +\item Trimethoprim/sulfamethoxazole +} + +The default antimicrobial agents used for \strong{Gram-negative bacteria} (set in \code{gram_negative}) are: +\itemize{ +\item Cefotaxime +\item Ceftazidime +\item Colistin +\item Gentamicin +\item Meropenem +\item Tobramycin +} + +The default antimicrobial agents used for \strong{Gram-positive bacteria} (set in \code{gram_positive}) are: +\itemize{ +\item Erythromycin +\item Oxacillin +\item Rifampin +\item Teicoplanin +\item Tetracycline +\item Vancomycin +} + +The default antimicrobial agents used for \strong{fungi} (set in \code{antifungal}) are: +\itemize{ +\item Anidulafungin +\item Caspofungin +\item Fluconazole +\item Miconazole +\item Nystatin +\item Voriconazole +} +} +\section{Stable Lifecycle}{ + +\if{html}{\figure{lifecycle_stable.svg}{options: style=margin-bottom:5px} \cr} +The \link[=lifecycle]{lifecycle} of this function is \strong{stable}. In a stable function, major changes are unlikely. This means that the unlying code will generally evolve by adding new arguments; removing arguments or changing the meaning of existing arguments will be avoided. + +If the unlying code needs breaking changes, they will occur gradually. For example, a argument will be deprecated and first continue to work, but will emit an message informing you of the change. Next, typically after at least one newly released version on CRAN, the message will be transformed to an error. +} + +\section{Read more on Our Website!}{ + +On our website \url{https://msberends.github.io/AMR/} you can find \href{https://msberends.github.io/AMR/articles/AMR.html}{a comprehensive tutorial} about how to conduct AMR data analysis, the \href{https://msberends.github.io/AMR/reference/}{complete documentation of all functions} and \href{https://msberends.github.io/AMR/articles/WHONET.html}{an example analysis using WHONET data}. As we would like to better understand the backgrounds and needs of our users, please \href{https://msberends.github.io/AMR/survey.html}{participate in our survey}! +} + +\examples{ +# `example_isolates` is a data set available in the AMR package. +# See ?example_isolates. + +# output of the `key_antimicrobials()` function could be like this: +strainA <- "SSSRR.S.R..S" +strainB <- "SSSIRSSSRSSS" + +# those strings can be compared with: +antimicrobials_equal(strainA, strainB, type = "keyantimicrobials") +# TRUE, because I is ignored (as well as missing values) + +antimicrobials_equal(strainA, strainB, type = "keyantimicrobials", ignore_I = FALSE) +# FALSE, because I is not ignored and so the 4th character differs + +\donttest{ +if (require("dplyr")) { + # set key antibiotics to a new variable + my_patients <- example_isolates \%>\% + mutate(keyab = key_antimicrobials(antifungal = NULL)) \%>\% # no need to define `x` + mutate( + # now calculate first isolates + first_regular = first_isolate(col_keyantimicrobials = FALSE), + # and first WEIGHTED isolates + first_weighted = first_isolate(col_keyantimicrobials = "keyab") + ) + + # Check the difference, in this data set it results in more isolates: + sum(my_patients$first_regular, na.rm = TRUE) + sum(my_patients$first_weighted, na.rm = TRUE) +} +} +} +\seealso{ +\code{\link[=first_isolate]{first_isolate()}} +} diff --git a/tests/testthat/test-first_isolate.R b/tests/testthat/test-first_isolate.R index b2e7b548..2f68e193 100755 --- a/tests/testthat/test-first_isolate.R +++ b/tests/testthat/test-first_isolate.R @@ -28,58 +28,29 @@ context("first_isolate.R") test_that("first isolates work", { skip_on_cran() - # first isolates - expect_equal( - sum( - first_isolate(x = example_isolates, - col_date = "date", - col_patient_id = "patient_id", - col_mo = "mo", - info = TRUE), - na.rm = TRUE), - 1300) - - # first weighted isolates - ex_iso_with_keyab <- example_isolates - ex_iso_with_keyab$keyab <- key_antibiotics(example_isolates, warnings = FALSE) - expect_equal( - suppressWarnings( - sum( - first_isolate(x = ex_iso_with_keyab, - # let syntax determine arguments automatically - type = "keyantibiotics", - info = TRUE), - na.rm = TRUE)), - 1398) - - # when not ignoring I - expect_equal( - suppressWarnings( - sum( - first_isolate(x = ex_iso_with_keyab, - col_date = "date", - col_patient_id = "patient_id", - col_mo = "mo", - col_keyantibiotics = "keyab", - ignore_I = FALSE, - type = "keyantibiotics", - info = TRUE), - na.rm = TRUE)), - 1421) - # when using points - expect_equal( - suppressWarnings( - sum( - first_isolate(x = ex_iso_with_keyab, - col_date = "date", - col_patient_id = "patient_id", - col_mo = "mo", - col_keyantibiotics = "keyab", - type = "points", - info = TRUE), - na.rm = TRUE)), - 1348) - + # all four methods + expect_equal(sum(first_isolate(x = example_isolates, method = "isolate-based", info = TRUE), na.rm = TRUE), + 1984) + expect_equal(sum(first_isolate(x = example_isolates, method = "patient-based", info = TRUE), na.rm = TRUE), + 1265) + expect_equal(sum(first_isolate(x = example_isolates, method = "episode-based", info = TRUE), na.rm = TRUE), + 1300) + expect_equal(sum(first_isolate(x = example_isolates, method = "phenotype-based", info = TRUE), na.rm = TRUE), + 1379) + + # Phenotype-based, using key antimicrobials + expect_equal(sum(first_isolate(x = example_isolates, + method = "phenotype-based", + type = "keyantimicrobials", + antifungal = NULL, info = TRUE), na.rm = TRUE), + 1395) + expect_equal(sum(first_isolate(x = example_isolates, + method = "phenotype-based", + type = "keyantimicrobials", + antifungal = NULL, info = TRUE, ignore_I = FALSE), na.rm = TRUE), + 1418) + + # first non-ICU isolates expect_equal( sum( @@ -91,7 +62,7 @@ test_that("first isolates work", { info = TRUE, icu_exclude = TRUE), na.rm = TRUE), - 881) + 941) # set 1500 random observations to be of specimen type 'Urine' random_rows <- sample(x = 1:2000, size = 1500, replace = FALSE) @@ -157,11 +128,13 @@ test_that("first isolates work", { mutate(mo = as.character(mo)) %>% first_isolate(col_date = "date", col_mo = "mo", - col_patient_id = "patient_id"), + col_patient_id = "patient_id", + info = FALSE), example_isolates %>% first_isolate(col_date = "date", col_mo = "mo", - col_patient_id = "patient_id")) + col_patient_id = "patient_id", + info = FALSE)) # support for WHONET expect_message(example_isolates %>% @@ -182,31 +155,29 @@ test_that("first isolates work", { col_mo = "mo", info = TRUE), na.rm = TRUE), - 1305) + 1382) # unknown MOs test_unknown <- example_isolates test_unknown$mo <- ifelse(test_unknown$mo == "B_ESCHR_COLI", "UNKNOWN", test_unknown$mo) expect_equal(sum(first_isolate(test_unknown, include_unknown = FALSE)), - 1045) + 1108) expect_equal(sum(first_isolate(test_unknown, include_unknown = TRUE)), - 1528) + 1591) test_unknown$mo <- ifelse(test_unknown$mo == "UNKNOWN", NA, test_unknown$mo) expect_equal(sum(first_isolate(test_unknown)), - 1045) + 1108) # empty rsi results expect_equal(sum(first_isolate(example_isolates, include_untested_rsi = FALSE)), - 1287) + 1366) # shortcuts expect_identical(filter_first_isolate(example_isolates), - subset(example_isolates, first_isolate(example_isolates))) - ex <- example_isolates - ex$keyab <- key_antibiotics(ex) + subset(example_isolates, first_isolate(example_isolates, method = "episode-based"))) expect_identical(filter_first_weighted_isolate(example_isolates), - subset(example_isolates, first_isolate(ex))) + subset(example_isolates, first_isolate(example_isolates, method = "phenotype-based"))) # notice that all mo's are distinct, so all are TRUE expect_true(all(example_isolates %pm>% diff --git a/tests/testthat/test-key_antibiotics.R b/tests/testthat/test-key_antimicrobials.R similarity index 66% rename from tests/testthat/test-key_antibiotics.R rename to tests/testthat/test-key_antimicrobials.R index 1f493c06..c97788b8 100644 --- a/tests/testthat/test-key_antibiotics.R +++ b/tests/testthat/test-key_antimicrobials.R @@ -23,19 +23,20 @@ # how to conduct AMR data analysis: https://msberends.github.io/AMR/ # # ==================================================================== # -context("key_antibiotics.R") +context("key_antimcrobials.R") -test_that("keyantibiotics work", { +test_that("key_antimcrobials work", { skip_on_cran() - expect_equal(length(key_antibiotics(example_isolates, warnings = FALSE)), nrow(example_isolates)) - expect_false(all(is.na(key_antibiotics(example_isolates)))) - expect_true(key_antibiotics_equal("SSS", "SSS")) - expect_false(key_antibiotics_equal("SSS", "SRS")) - expect_true(key_antibiotics_equal("SSS", "SIS", ignore_I = TRUE)) - expect_false(key_antibiotics_equal("SSS", "SIS", ignore_I = FALSE)) - expect_true(key_antibiotics_equal(".SS", "SI.", ignore_I = TRUE)) - expect_false(key_antibiotics_equal(".SS", "SI.", ignore_I = FALSE)) + expect_equal(length(key_antimicrobials(example_isolates, antifungal = NULL)), nrow(example_isolates)) + expect_false(all(is.na(key_antimicrobials(example_isolates, antifungal = NULL)))) + expect_true(antimicrobials_equal("SSS", "SSS")) + expect_false(antimicrobials_equal("SSS", "SRS", type = "keyantimicrobials")) + expect_true(antimicrobials_equal("SSS", "SRS", type = "points")) + expect_true(antimicrobials_equal("SSS", "SIS", ignore_I = TRUE, type = "keyantimicrobials")) + expect_false(antimicrobials_equal("SSS", "SIS", ignore_I = FALSE, type = "keyantimicrobials")) + expect_true(antimicrobials_equal(".SS", "SI.", ignore_I = TRUE, type = "keyantimicrobials")) + expect_false(antimicrobials_equal(".SS", "SI.", ignore_I = FALSE, type = "keyantimicrobials")) library(dplyr, warn.conflicts = FALSE) - expect_warning(key_antibiotics(example_isolates %>% slice(rep(1, 10)))) + expect_warning(key_antimicrobials(example_isolates %>% slice(rep(1, 10)))) })