diff --git a/DESCRIPTION b/DESCRIPTION index 5ef11236..3638d34f 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: AMR -Version: 0.5.0.9014 -Date: 2019-01-28 +Version: 0.5.0.9015 +Date: 2019-01-29 Title: Antimicrobial Resistance Analysis Authors@R: c( person( diff --git a/NEWS.md b/NEWS.md index 75468aa8..e424788b 100755 --- a/NEWS.md +++ b/NEWS.md @@ -3,6 +3,9 @@ #### New * **BREAKING**: removed deprecated functions, parameters and references to 'bactid'. Use `as.mo()` to identify an MO code. +* Support for data from [WHONET](https://whonet.org/) and [EARS-Net](https://ecdc.europa.eu/en/about-us/partnerships-and-networks/disease-and-laboratory-networks/ears-net) (European Antimicrobial Resistance Surveillance Network): + * Exported files from WHONET can be read and used in this package. For functions like `first_isolate()` and `eucast_rules()`, all parameters will be filled in automatically. + * This package now knows all antibiotic abbrevations by EARS-Net (which are also being used by WHONET) - the `antibiotics` data set now contains a column `ears_net`. * All `ab_*` functions are deprecated and replaced by `atc_*` functions: ```r ab_property -> atc_property() @@ -75,10 +78,11 @@ * Merged data sets `microorganisms.certe` and `microorganisms.umcg` into `microorganisms.codes` * Function `mo_taxonomy()` now contains the kingdom too * Reduce false positives for `is.rsi.eligible()` +* New colours for `scale_rsi_colours()` * Summaries of class `mo` will now return the top 3 and the unique count, e.g. using `summary(mo)` * Small text updates to summaries of class `rsi` and `mic` * Frequency tables (`freq()` function): - * Support for tidyverse quasiquotation! So now you can create frequency tables of function outcomes: + * Support for tidyverse quasiquotation! Now you can create frequency tables of function outcomes: ```r # Determine genus of microorganisms (mo) in `septic_patients` data set: # OLD WAY diff --git a/R/atc.R b/R/atc.R index bcc791c0..b609dceb 100755 --- a/R/atc.R +++ b/R/atc.R @@ -60,10 +60,15 @@ as.atc <- function(x) { x[!x %like% "[A-Z][0-9]{2}[A-Z]{2}[0-9]{2}"] <- gsub("[^a-zA-Z]+", "", x[!x %like% "[A-Z][0-9]{2}[A-Z]{2}[0-9]{2}"]) x.bak <- x - x <- unique(x[!is.na(x)]) + x <- unique(x) failures <- character(0) for (i in 1:length(x)) { + if (is.na(x[i]) | is.null(x[i]) | identical(x[i], "")) { + x.new[i] <- x[i] + next + } + fail <- TRUE # first try atc @@ -80,6 +85,13 @@ as.atc <- function(x) { x.new[is.na(x.new) & x.bak == x[i]] <- x[i] } + # try abbreviation of EARS-Net/WHONET + found <- AMR::antibiotics[which(tolower(AMR::antibiotics$ears_net) == tolower(x[i])),]$atc + if (length(found) > 0) { + fail <- FALSE + x.new[is.na(x.new) & x.bak == x[i]] <- found[1L] + } + # try abbreviation of certe and glims found <- AMR::antibiotics[which(tolower(AMR::antibiotics$certe) == tolower(x[i])),]$atc if (length(found) > 0) { diff --git a/R/data.R b/R/data.R index 3793064e..0843ee78 100755 --- a/R/data.R +++ b/R/data.R @@ -22,9 +22,10 @@ #' Data set with ~500 antibiotics #' #' A data set containing all antibiotics with a J0 code and some other antimicrobial agents, with their DDDs. Except for trade names and abbreviations, all properties were downloaded from the WHO, see Source. -#' @format A \code{\link{data.frame}} with 488 observations and 16 variables: +#' @format A \code{\link{data.frame}} with 488 observations and 17 variables: #' \describe{ -#' \item{\code{atc}}{ATC code, like \code{J01CR02}} +#' \item{\code{atc}}{ATC code (Anatomical Therapeutic Chemical), like \code{J01CR02}} +#' \item{\code{ears_net}}{EARS-Net code (European Antimicrobial Resistance Surveillance Network), like \code{AMC}} #' \item{\code{certe}}{Certe code, like \code{amcl}} #' \item{\code{umcg}}{UMCG code, like \code{AMCL}} #' \item{\code{abbr}}{Abbreviation as used by many countries, used internally by \code{\link{as.atc}}} @@ -43,6 +44,8 @@ #' } #' @source - World Health Organization (WHO) Collaborating Centre for Drug Statistics Methodology: \url{https://www.whocc.no/atc_ddd_index/} #' +#' Table antibiotic coding EARSS (from WHONET 5.3): \url{http://www.madsonline.dk/Tutorials/landskoder_antibiotika_WM.pdf} +#' #' EUCAST Expert Rules, Intrinsic Resistance and Exceptional Phenotypes Tables. Version 3.1, 2016: \url{http://www.eucast.org/fileadmin/src/media/PDFs/EUCAST_files/Expert_Rules/Expert_rules_intrinsic_exceptional_V3.1.pdf} #' #' European Commission Public Health PHARMACEUTICALS - COMMUNITY REGISTER: \url{http://ec.europa.eu/health/documents/community-register/html/atc.htm} diff --git a/R/first_isolate.R b/R/first_isolate.R index 20335186..8b5c13f8 100755 --- a/R/first_isolate.R +++ b/R/first_isolate.R @@ -220,6 +220,14 @@ first_isolate <- function(tbl, col_keyantibiotics <- NULL } + # -- specimen + if (is.null(col_specimen)) { + col_specimen <- search_type_in_df(tbl = tbl, type = "specimen") + } + if (isFALSE(col_specimen)) { + col_specimen <- NULL + } + # check if columns exist check_columns_existance <- function(column, tblname = tbl) { if (NROW(tblname) <= 1 | NCOL(tblname) <= 1) { diff --git a/R/ggplot_rsi.R b/R/ggplot_rsi.R index b5bccfc4..bb0961b2 100755 --- a/R/ggplot_rsi.R +++ b/R/ggplot_rsi.R @@ -313,8 +313,8 @@ scale_y_percent <- function(breaks = seq(0, 1, 0.1), limits = NULL) { #' @rdname ggplot_rsi #' @export scale_rsi_colours <- function() { - ggplot2::scale_fill_brewer(palette = "RdYlGn") - #ggplot2::scale_fill_gradient2(low = "#d5613e", mid = "#ae5ac0", high = "#7daf44") + #ggplot2::scale_fill_brewer(palette = "RdYlGn") + ggplot2::scale_fill_manual(values = c("#b22222", "#ae9c20", "#7cfc00")) } #' @rdname ggplot_rsi diff --git a/R/guess_ab_col.R b/R/guess_ab_col.R index ef25dc00..1c3e3b29 100755 --- a/R/guess_ab_col.R +++ b/R/guess_ab_col.R @@ -21,7 +21,7 @@ #' Guess antibiotic column #' -#' This tries to find a column name in a data set based on information from the \code{\link{antibiotics}} data set. You can look for an antibiotic (trade) name or abbreviation and it will search the \code{data.frame} for any column containing a name or ATC code of that antibiotic. +#' This tries to find a column name in a data set based on information from the \code{\link{antibiotics}} data set. Also supports WHONET abbreviations. You can look for an antibiotic (trade) name or abbreviation and it will search the \code{data.frame} for any column containing a name or ATC code of that antibiotic. #' @param tbl a \code{data.frame} #' @param col a character to look for #' @param verbose a logical to indicate whether additional info should be printed @@ -40,6 +40,16 @@ #' guess_ab_col(df, "J01AA07", verbose = TRUE) #' # using column `tetr` for col "J01AA07" #' # [1] "tetr" +#' +#' # WHONET codes +#' df <- data.frame(AMP_ND10 = "R", +#' AMC_ED20 = "S") +#' guess_ab_col(df, "ampicillin") +#' # [1] "AMP_ND10" +#' guess_ab_col(df, "J01CR02") +#' # [1] "AMC_ED20" +#' guess_ab_col(df, as.atc("augmentin")) +#' # [1] "AMC_ED20" guess_ab_col <- function(tbl = NULL, col = NULL, verbose = FALSE) { if (is.null(tbl) & is.null(col)) { return(as.name("guess_ab_col")) @@ -54,6 +64,11 @@ guess_ab_col <- function(tbl = NULL, col = NULL, verbose = FALSE) { } tbl_names <- colnames(tbl) + tbl_names_stripped <- colnames(tbl) %>% + strsplit("_") %>% + lapply(function(x) {x[1]}) %>% + unlist() + if (col %in% tbl_names) { return(col) } @@ -70,6 +85,15 @@ guess_ab_col <- function(tbl = NULL, col = NULL, verbose = FALSE) { filter_all(any_vars(. %in% tbl_names)) } + # WHONET + if (nrow(ab_result) == 0) { + # use like when col >= 5 characters + ab_result <- antibiotics %>% + select(atc:trade_name) %>% + filter_all(any_vars(tolower(.) == tolower(col))) %>% + filter_all(any_vars(. %in% tbl_names_stripped)) + } + if (nrow(ab_result) > 1) { # looking more and more for reliable hit ab_result_1 <- ab_result %>% filter(tolower(atc) == tolower(col)) @@ -95,6 +119,9 @@ guess_ab_col <- function(tbl = NULL, col = NULL, verbose = FALSE) { return(NULL) } else { result <- tbl_names[tbl_names %in% ab_result] + if (length(result) == 0) { + result <- tbl_names[tbl_names_stripped %in% ab_result] + } if (length(result) == 0) { if (verbose == TRUE) { message('no result found for col "', col, '"') diff --git a/R/misc.R b/R/misc.R index 846ebefe..4b0a696f 100755 --- a/R/misc.R +++ b/R/misc.R @@ -130,11 +130,18 @@ search_type_in_df <- function(tbl, type) { # try to find columns based on type found <- NULL + colnames(tbl) <- trimws(colnames(tbl)) + # -- mo if (type == "mo") { if ("mo" %in% lapply(tbl, class)) { found <- colnames(tbl)[lapply(tbl, class) == "mo"][1] + } else if (any(colnames(tbl) %like% "^(mo|microorganism|organism|bacteria)")) { + found <- colnames(tbl)[colnames(tbl) %like% "^(mo|microorganism|organism|bacteria)"][1] + } else if (any(colnames(tbl) %like% "species")) { + found <- colnames(tbl)[colnames(tbl) %like% "species"][1] } + } # -- key antibiotics if (type == "keyantibiotics") { @@ -154,15 +161,23 @@ search_type_in_df <- function(tbl, type) { } # -- patient id if (type == "patient_id") { - if (any(colnames(tbl) %like% "^(patient|patid)")) { - found <- colnames(tbl)[colnames(tbl) %like% "^(patient|patid)"][1] + if (any(colnames(tbl) %like% "^(identification |patient|patid)")) { + found <- colnames(tbl)[colnames(tbl) %like% "^(identification |patient|patid)"][1] + } + } + # -- specimen + if (type == "specimen") { + if (any(colnames(tbl) %like% "(specimen type)")) { + found <- colnames(tbl)[colnames(tbl) %like% "(specimen type)"][1] + } else if (any(colnames(tbl) %like% "^(specimen)")) { + found <- colnames(tbl)[colnames(tbl) %like% "^(specimen)"][1] } } if (!is.null(found)) { msg <- paste0("NOTE: Using column `", bold(found), "` as input for `col_", type, "`.") - if (type == "keyantibiotics") { - msg <- paste(msg, "Use", bold("col_keyantibiotics = FALSE"), "to prevent this.") + if (type %in% c("keyantibiotics", "specimen")) { + msg <- paste(msg, "Use", bold(paste0("col_", type), " = FALSE"), "to prevent this.") } message(blue(msg)) } diff --git a/R/mo_source.R b/R/mo_source.R index 60128ced..9748bd29 100644 --- a/R/mo_source.R +++ b/R/mo_source.R @@ -107,11 +107,7 @@ set_mo_source <- function(path) { if (!"readxl" %in% utils::installed.packages()) { stop("Install the 'readxl' package first.") } - if (path %like% '[.]xlsx$') { - df <- readxl::read_xlsx(path) - } else { - df <- readxl::read_xls(path) - } + df <- readxl::read_excel(path) } else { # try comma first diff --git a/_pkgdown.yml b/_pkgdown.yml index 29f376b6..c896b0ff 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -38,6 +38,9 @@ navbar: - text: 'Predict antimicrobial resistance' icon: 'fa-dice' href: 'articles/Predict.html' + - text: 'Work with WHONET data' + icon: 'fa-globe-americas' + href: 'articles/WHONET.html' - text: 'Apply EUCAST rules' icon: 'fa-exchange-alt' href: 'articles/EUCAST.html' diff --git a/data/antibiotics.rda b/data/antibiotics.rda index f5015913..6782d134 100755 Binary files a/data/antibiotics.rda and b/data/antibiotics.rda differ diff --git a/docs/LICENSE-text.html b/docs/LICENSE-text.html index 79527f39..8c3c0770 100644 --- a/docs/LICENSE-text.html +++ b/docs/LICENSE-text.html @@ -78,7 +78,7 @@ AMR (for R) - 0.5.0.9014 + 0.5.0.9015 @@ -114,6 +114,13 @@ Predict antimicrobial resistance +
  • + + + + Work with WHONET data + +
  • diff --git a/docs/articles/AMR.html b/docs/articles/AMR.html index 80381a47..af02aedf 100644 --- a/docs/articles/AMR.html +++ b/docs/articles/AMR.html @@ -40,7 +40,7 @@ AMR (for R) - 0.5.0.9012 + 0.5.0.9015 @@ -76,6 +76,13 @@ Predict antimicrobial resistance
  • +
  • + + + + Work with WHONET data + +
  • @@ -178,7 +185,7 @@

    How to conduct AMR analysis

    Matthijs S. Berends

    -

    27 January 2019

    +

    28 January 2019

    @@ -187,7 +194,7 @@ -

    Note: values on this page will change with every website update since they are based on randomly created values and the page was written in RMarkdown. However, the methodology remains unchanged. This page was generated on 27 January 2019.

    +

    Note: values on this page will change with every website update since they are based on randomly created values and the page was written in RMarkdown. However, the methodology remains unchanged. This page was generated on 28 January 2019.

    Introduction

    @@ -203,21 +210,21 @@ -2019-01-27 +2019-01-28 abcd Escherichia coli S S -2019-01-27 +2019-01-28 abcd Escherichia coli S R -2019-01-27 +2019-01-28 efgh Escherichia coli R @@ -231,12 +238,12 @@ Needed R packages

    As with many uses in R, we need some additional packages for AMR analysis. Our package works closely together with the tidyverse packages dplyr and ggplot2 by Dr Hadley Wickham. The tidyverse tremendously improves the way we conduct data science - it allows for a very natural way of writing syntaxes and creating beautiful plots in R.

    Our AMR package depends on these packages and even extends their use and functions.

    -
    library(dplyr)
    -library(ggplot2)
    -library(AMR)
    -
    -# (if not yet installed, install with:)
    -# install.packages(c("tidyverse", "AMR"))
    +

    @@ -247,51 +254,51 @@

    Patients

    To start with patients, we need a unique list of patients.

    -
    patients <- unlist(lapply(LETTERS, paste0, 1:10))
    +
    patients <- unlist(lapply(LETTERS, paste0, 1:10))

    The LETTERS object is available in R - it’s a vector with 26 characters: A to Z. The patients object we just created is now a vector of length 260, with values (patient IDs) varying from A1 to Z10. Now we we also set the gender of our patients, by putting the ID and the gender in a table:

    -
    patients_table <- data.frame(patient_id = patients,
    -                             gender = c(rep("M", 135),
    -                                        rep("F", 125)))
    +
    patients_table <- data.frame(patient_id = patients,
    +                             gender = c(rep("M", 135),
    +                                        rep("F", 125)))

    The first 135 patient IDs are now male, the other 125 are female.

    Dates

    Let’s pretend that our data consists of blood cultures isolates from 1 January 2010 until 1 January 2018.

    -
    dates <- seq(as.Date("2010-01-01"), as.Date("2018-01-01"), by = "day")
    +
    dates <- seq(as.Date("2010-01-01"), as.Date("2018-01-01"), by = "day")

    This dates object now contains all days in our date range.

    Microorganisms

    For this tutorial, we will uses four different microorganisms: Escherichia coli, Staphylococcus aureus, Streptococcus pneumoniae, and Klebsiella pneumoniae:

    -
    bacteria <- c("Escherichia coli", "Staphylococcus aureus",
    -              "Streptococcus pneumoniae", "Klebsiella pneumoniae")
    +
    bacteria <- c("Escherichia coli", "Staphylococcus aureus",
    +              "Streptococcus pneumoniae", "Klebsiella pneumoniae")

    Other variables

    For completeness, we can also add the hospital where the patients was admitted and we need to define valid antibmicrobial results for our randomisation:

    -
    hospitals <- c("Hospital A", "Hospital B", "Hospital C", "Hospital D")
    -ab_interpretations <- c("S", "I", "R")
    +
    hospitals <- c("Hospital A", "Hospital B", "Hospital C", "Hospital D")
    +ab_interpretations <- c("S", "I", "R")

    Put everything together

    -

    Using the sample() function, we can randomly select items from all objects we defined earlier. To let our fake data reflect reality a bit, we will also approximately define the probabilities of bacteria and the antibiotic results with the prob parameter.

    -
    data <- data.frame(date = sample(dates, 5000, replace = TRUE),
    -                   patient_id = sample(patients, 5000, replace = TRUE),
    -                   hospital = sample(hospitals, 5000, replace = TRUE, prob = c(0.30, 0.35, 0.15, 0.20)),
    -                   bacteria = sample(bacteria, 5000, replace = TRUE, prob = c(0.50, 0.25, 0.15, 0.10)),
    -                   amox = sample(ab_interpretations, 5000, replace = TRUE, prob = c(0.60, 0.05, 0.35)),
    -                   amcl = sample(ab_interpretations, 5000, replace = TRUE, prob = c(0.75, 0.10, 0.15)),
    -                   cipr = sample(ab_interpretations, 5000, replace = TRUE, prob = c(0.80, 0.00, 0.20)),
    -                   gent = sample(ab_interpretations, 5000, replace = TRUE, prob = c(0.92, 0.00, 0.08))
    -                   )
    -

    Using the left_join() function from the dplyr package, we can ‘map’ the gender to the patient ID using the patients_table object we created earlier:

    -
    data <- data %>% left_join(patients_table)
    +

    Using the sample() function, we can randomly select items from all objects we defined earlier. To let our fake data reflect reality a bit, we will also approximately define the probabilities of bacteria and the antibiotic results with the prob parameter.

    +
    data <- data.frame(date = sample(dates, 5000, replace = TRUE),
    +                   patient_id = sample(patients, 5000, replace = TRUE),
    +                   hospital = sample(hospitals, 5000, replace = TRUE, prob = c(0.30, 0.35, 0.15, 0.20)),
    +                   bacteria = sample(bacteria, 5000, replace = TRUE, prob = c(0.50, 0.25, 0.15, 0.10)),
    +                   amox = sample(ab_interpretations, 5000, replace = TRUE, prob = c(0.60, 0.05, 0.35)),
    +                   amcl = sample(ab_interpretations, 5000, replace = TRUE, prob = c(0.75, 0.10, 0.15)),
    +                   cipr = sample(ab_interpretations, 5000, replace = TRUE, prob = c(0.80, 0.00, 0.20)),
    +                   gent = sample(ab_interpretations, 5000, replace = TRUE, prob = c(0.92, 0.00, 0.08))
    +                   )
    +

    Using the left_join() function from the dplyr package, we can ‘map’ the gender to the patient ID using the patients_table object we created earlier:

    +

    The resulting data set contains 5,000 blood culture isolates. With the head() function we can preview the first 6 values of this data set:

    -
    head(data)
    +
    head(data)
    @@ -306,66 +313,66 @@ ab_interpretations <- - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -380,8 +387,8 @@ ab_interpretations <- Cleaning the data

    Use the frequency table function freq() to look specifically for unique values in any variable. For example, for the gender variable:

    -
    data %>% freq(gender) # this would be the same: freq(data$gender)
    -
    # Frequency table of `gender` 
    +
    data %>% freq(gender) # this would be the same: freq(data$gender)
    +
    # Frequency table 
     # Class:   factor (numeric)  
     # Levels:  F, M  
     # Length:  5,000 (of which NA: 0 = 0.00%)  
    @@ -389,67 +396,67 @@ ab_interpretations <- mutate() function of the dplyr package makes this really easy:

    -
    data <- data %>%
    -  mutate(bacteria = as.mo(bacteria))
    -

    We also want to transform the antibiotics, because in real life data we don’t know if they are really clean. The as.rsi() function ensures reliability and reproducibility in these kind of variables. The mutate_at() will run the as.rsi() function on defined variables:

    -
    data <- data %>%
    -  mutate_at(vars(amox:gent), as.rsi)
    +

    The data is already quite clean, but we still need to transform some variables. The bacteria column now consists of text, and we want to add more variables based on microbial IDs later on. So, we will transform this column to valid IDs. The mutate() function of the dplyr package makes this really easy:

    +
    data <- data %>%
    +  mutate(bacteria = as.mo(bacteria))
    +

    We also want to transform the antibiotics, because in real life data we don’t know if they are really clean. The as.rsi() function ensures reliability and reproducibility in these kind of variables. The mutate_at() will run the as.rsi() function on defined variables:

    +
    data <- data %>%
    +  mutate_at(vars(amox:gent), as.rsi)

    Finally, we will apply EUCAST rules on our antimicrobial results. In Europe, most medical microbiological laboratories already apply these rules. Our package features their latest insights on intrinsic resistance and exceptional phenotypes. Moreover, the eucast_rules() function can also apply additional rules, like forcing ampicillin = R when amoxicillin/clavulanic acid = R.

    Because the amoxicillin (column amox) and amoxicillin/clavulanic acid (column amcl) in our data were generated randomly, some rows will undoubtedly contain amox = S and amcl = R, which is technically impossible. The eucast_rules() fixes this:

    -
    data <- eucast_rules(data, col_mo = "bacteria")
    -# 
    -# Rules by the European Committee on Antimicrobial Susceptibility Testing (EUCAST)
    -# 
    -# EUCAST Clinical Breakpoints (v9.0, 2019)
    -# Enterobacteriales (Order) (no changes)
    -# Staphylococcus (no changes)
    -# Enterococcus (no changes)
    -# Streptococcus groups A, B, C, G (no changes)
    -# Streptococcus pneumoniae (no changes)
    -# Viridans group streptococci (no changes)
    -# Haemophilus influenzae (no changes)
    -# Moraxella catarrhalis (no changes)
    -# Anaerobic Gram positives (no changes)
    -# Anaerobic Gram negatives (no changes)
    -# Pasteurella multocida (no changes)
    -# Campylobacter jejuni and C. coli (no changes)
    -# Aerococcus sanguinicola and A. urinae (no changes)
    -# Kingella kingae (no changes)
    -# 
    -# EUCAST Expert Rules, Intrinsic Resistance and Exceptional Phenotypes (v3.1, 2016)
    -# Table 1:  Intrinsic resistance in Enterobacteriaceae (316 changes)
    -# Table 2:  Intrinsic resistance in non-fermentative Gram-negative bacteria (no changes)
    -# Table 3:  Intrinsic resistance in other Gram-negative bacteria (no changes)
    -# Table 4:  Intrinsic resistance in Gram-positive bacteria (690 changes)
    -# Table 8:  Interpretive rules for B-lactam agents and Gram-positive cocci (no changes)
    -# Table 9:  Interpretive rules for B-lactam agents and Gram-negative rods (no changes)
    -# Table 10: Interpretive rules for B-lactam agents and other Gram-negative bacteria (no changes)
    -# Table 11: Interpretive rules for macrolides, lincosamides, and streptogramins (no changes)
    -# Table 12: Interpretive rules for aminoglycosides (no changes)
    -# Table 13: Interpretive rules for quinolones (no changes)
    -# 
    -# Other rules
    -# Non-EUCAST: ampicillin = R where amoxicillin/clav acid = R (no changes)
    -# Non-EUCAST: piperacillin = R where piperacillin/tazobactam = R (no changes)
    -# Non-EUCAST: trimethoprim = R where trimethoprim/sulfa = R (no changes)
    -# Non-EUCAST: amoxicillin/clav acid = S where ampicillin = S (no changes)
    -# Non-EUCAST: piperacillin/tazobactam = S where piperacillin = S (no changes)
    -# Non-EUCAST: trimethoprim/sulfa = S where trimethoprim = S (no changes)
    -# 
    -# => EUCAST rules affected 1,865 out of 5,000 rows -> changed 1,006 test results.
    +
    data <- eucast_rules(data, col_mo = "bacteria")
    +# 
    +# Rules by the European Committee on Antimicrobial Susceptibility Testing (EUCAST)
    +# 
    +# EUCAST Clinical Breakpoints (v9.0, 2019)
    +# Enterobacteriales (Order) (no changes)
    +# Staphylococcus (no changes)
    +# Enterococcus (no changes)
    +# Streptococcus groups A, B, C, G (no changes)
    +# Streptococcus pneumoniae (no changes)
    +# Viridans group streptococci (no changes)
    +# Haemophilus influenzae (no changes)
    +# Moraxella catarrhalis (no changes)
    +# Anaerobic Gram positives (no changes)
    +# Anaerobic Gram negatives (no changes)
    +# Pasteurella multocida (no changes)
    +# Campylobacter jejuni and C. coli (no changes)
    +# Aerococcus sanguinicola and A. urinae (no changes)
    +# Kingella kingae (no changes)
    +# 
    +# EUCAST Expert Rules, Intrinsic Resistance and Exceptional Phenotypes (v3.1, 2016)
    +# Table 1:  Intrinsic resistance in Enterobacteriaceae (313 changes)
    +# Table 2:  Intrinsic resistance in non-fermentative Gram-negative bacteria (no changes)
    +# Table 3:  Intrinsic resistance in other Gram-negative bacteria (no changes)
    +# Table 4:  Intrinsic resistance in Gram-positive bacteria (649 changes)
    +# Table 8:  Interpretive rules for B-lactam agents and Gram-positive cocci (no changes)
    +# Table 9:  Interpretive rules for B-lactam agents and Gram-negative rods (no changes)
    +# Table 10: Interpretive rules for B-lactam agents and other Gram-negative bacteria (no changes)
    +# Table 11: Interpretive rules for macrolides, lincosamides, and streptogramins (no changes)
    +# Table 12: Interpretive rules for aminoglycosides (no changes)
    +# Table 13: Interpretive rules for quinolones (no changes)
    +# 
    +# Other rules
    +# Non-EUCAST: ampicillin = R where amoxicillin/clav acid = R (no changes)
    +# Non-EUCAST: piperacillin = R where piperacillin/tazobactam = R (no changes)
    +# Non-EUCAST: trimethoprim = R where trimethoprim/sulfa = R (no changes)
    +# Non-EUCAST: amoxicillin/clav acid = S where ampicillin = S (no changes)
    +# Non-EUCAST: piperacillin/tazobactam = S where piperacillin = S (no changes)
    +# Non-EUCAST: trimethoprim/sulfa = S where trimethoprim = S (no changes)
    +# 
    +# => EUCAST rules affected 1,804 out of 5,000 rows -> changed 962 test results.

    Adding new variables

    Now that we have the microbial ID, we can add some taxonomic properties:

    -
    data <- data %>% 
    -  mutate(gramstain = mo_gramstain(bacteria),
    -         genus = mo_genus(bacteria),
    -         species = mo_species(bacteria))
    +
    data <- data %>% 
    +  mutate(gramstain = mo_gramstain(bacteria),
    +         genus = mo_genus(bacteria),
    +         species = mo_species(bacteria))

    First isolates

    @@ -460,18 +467,18 @@ ab_interpretations <- M39-A4 Analysis and Presentation of Cumulative Antimicrobial Susceptibility Test Data, 4th Edition. CLSI, 2014. Chapter 6.4

    This AMR package includes this methodology with the first_isolate() function. It adopts the episode of a year (can be changed by user) and it starts counting days after every selected isolate. This new variable can easily be added to our data:

    -
    data <- data %>% 
    -  mutate(first = first_isolate(.))
    -# NOTE: Using column `bacteria` as input for `col_mo`.
    -# NOTE: Using column `date` as input for `col_date`.
    -# NOTE: Using column `patient_id` as input for `col_patient_id`.
    -# => Found 2,938 first isolates (58.8% of total)
    -

    So only 58.8% is suitable for resistance analysis! We can now filter on is with the filter() function, also from the dplyr package:

    -
    data_1st <- data %>% 
    -  filter(first == TRUE)
    + +

    So only 58.8% is suitable for resistance analysis! We can now filter on is with the filter() function, also from the dplyr package:

    +

    For future use, the above two syntaxes can be shortened with the filter_first_isolate() function:

    -
    data_1st <- data %>% 
    -  filter_first_isolate()
    +

    @@ -492,10 +499,10 @@ ab_interpretations <-

    - - + + - + @@ -503,41 +510,41 @@ ab_interpretations <- - - + + - + + - - + - - + + + - - - + + - + - - + + @@ -547,19 +554,19 @@ ab_interpretations <- - - + + + - - + - - + + @@ -569,30 +576,30 @@ ab_interpretations <- - - + + - + - - + + - - + + - - + + @@ -602,18 +609,18 @@ ab_interpretations <- key_antibiotics() function adds a vector with 18 key antibiotics: 6 broad spectrum ones, 6 small spectrum for Gram negatives and 6 small spectrum for Gram positives. These can be defined by the user.

    +

    Only 4 isolates are marked as ‘first’ according to CLSI guideline. But when reviewing the antibiogram, it is obvious that some isolates are absolutely different strains and show be included too. This is why we weigh isolates, based on their antibiogram. The key_antibiotics() function adds a vector with 18 key antibiotics: 6 broad spectrum ones, 6 small spectrum for Gram negatives and 6 small spectrum for Gram positives. These can be defined by the user.

    If a column exists with a name like ‘key(…)ab’ the first_isolate() function will automatically use it and determine the first weighted isolates. Mind the NOTEs in below output:

    -
    data <- data %>% 
    -  mutate(keyab = key_antibiotics(.)) %>% 
    -  mutate(first_weighted = first_isolate(.))
    -# NOTE: Using column `bacteria` as input for `col_mo`.
    -# NOTE: Using column `bacteria` as input for `col_mo`.
    -# NOTE: Using column `date` as input for `col_date`.
    -# NOTE: Using column `patient_id` as input for `col_patient_id`.
    -# NOTE: Using column `keyab` as input for `col_keyantibiotics`. Use col_keyantibiotics = FALSE to prevent this.
    -# [Criterion] Inclusion based on key antibiotics, ignoring I.
    -# => Found 4,388 first weighted isolates (87.8% of total)
    +
    date2015-08-07D6Hospital AStaphylococcus aureusRRSSM
    2016-06-04T32011-12-05N6 Hospital BStaphylococcus aureusRSSSF
    2012-09-25R6Hospital CStaphylococcus aureusRSSSF
    2015-10-07A4Hospital BStaphylococcus aureusSRRSM
    2016-04-12S6Hospital DKlebsiella pneumoniaeRSSSF
    2010-11-24Z3Hospital C Escherichia coli RISSF
    2012-08-21O9Hospital BStreptococcus pneumoniaeIRRSF
    2015-10-17P4Hospital DEscherichia coliSSSSF
    2014-03-12V8Hospital AEscherichia coliSSRSF
    2015-04-17L3Hospital DEscherichia coliSRSSM
    2012-09-29Q10Hospital BEscherichia coliS S S S 12010-02-28H32010-02-22Y8 B_ESCHR_COLSR S S S22010-05-15H32011-11-07Y8 B_ESCHR_COLRSI S SSFALSETRUE
    32010-07-09H32012-05-14Y8 B_ESCHR_COLI R S SR FALSE
    42011-01-05H32012-10-27Y8 B_ESCHR_COL S SRS S FALSE
    52011-08-01H32013-03-26Y8 B_ESCHR_COL S I62011-08-28H32013-05-26Y8 B_ESCHR_COL SR SSSR FALSE
    72011-10-28H32013-10-20Y8 B_ESCHR_COL S S82012-11-10H32015-03-07Y8 B_ESCHR_COL SSR S S TRUE
    92013-01-14H32015-03-20Y8 B_ESCHR_COL SRRIS S FALSE
    102013-03-14H32015-10-18Y8 B_ESCHR_COL R S
    @@ -630,10 +637,10 @@ ab_interpretations <- - - + + - + @@ -642,44 +649,44 @@ ab_interpretations <- - - + + - + + - - + - - + + + - - + - - + + - + - - + + @@ -690,35 +697,35 @@ ab_interpretations <- - - + + + - - - + + - - + + - + - - + + - + @@ -726,20 +733,20 @@ ab_interpretations <- - - + + - - + + - + - - + + @@ -750,16 +757,16 @@ ab_interpretations <- filter_first_isolate(), there’s a shortcut for this new algorithm too:

    -
    data_1st <- data %>% 
    -  filter_first_weighted_isolate()
    -

    So we end up with 4,388 isolates for analysis.

    + +

    So we end up with 4,452 isolates for analysis.

    We can remove unneeded columns:

    -
    data_1st <- data_1st %>% 
    -  select(-c(first, keyab))
    +

    Now our data looks like:

    -
    head(data_1st)
    +
    head(data_1st)
    isolate12010-02-28H32010-02-22Y8 B_ESCHR_COLSR S S S22010-05-15H32011-11-07Y8 B_ESCHR_COLRSI S SSFALSETRUE TRUE
    32010-07-09H32012-05-14Y8 B_ESCHR_COLI R S SR FALSETRUEFALSE
    42011-01-05H32012-10-27Y8 B_ESCHR_COL S SRS S FALSE TRUE
    52011-08-01H32013-03-26Y8 B_ESCHR_COL S I62011-08-28H32013-05-26Y8 B_ESCHR_COL SR SSSFALSER FALSETRUE
    72011-10-28H32013-10-20Y8 B_ESCHR_COL S S S S FALSEFALSETRUE
    82012-11-10H32015-03-07Y8 B_ESCHR_COL SSR S S TRUE92013-01-14H32015-03-20Y8 B_ESCHR_COL SRRIS S FALSETRUEFALSE
    102013-03-14H32015-10-18Y8 B_ESCHR_COL R S
    @@ -778,87 +785,87 @@ ab_interpretations <- - - - - - - - - - - - - - - - - - + + - + - + - - - - - - - - - - - - - - - - - - + + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -877,12 +884,12 @@ ab_interpretations <- Analysing the data

    You might want to start by getting an idea of how the data is distributed. It’s an important start, because it also decides how you will continue your analysis. ## Dispersion of species To just get an idea how the species are distributed, create a frequency table with our freq() function. We created the genus and species column earlier based on the microbial ID. With paste(), we can concatenate them together.

    The freq() function can be used like the base R language was intended:

    -
    freq(paste(data_1st$genus, data_1st$species))
    +
    freq(paste(data_1st$genus, data_1st$species))

    Or can be used like the dplyr way, which is easier readable:

    -
    data_1st %>% freq(genus, species)
    -

    Frequency table of genus and species
    +

    data_1st %>% freq(genus, species)
    +

    Frequency table
    Columns: 2
    -Length: 4,388 (of which NA: 0 = 0.00%)
    +Length: 4,452 (of which NA: 0 = 0.00%)
    Unique: 4

    Shortest: 16
    Longest: 24

    @@ -899,33 +906,33 @@ Longest: 24

    - - - - + + + + - - - - + + + + - - - - + + + + - - - + + + @@ -934,12 +941,12 @@ Longest: 24

    Resistance percentages

    The functions portion_R, portion_RI, portion_I, portion_IS and portion_S can be used to determine the portion of a specific antimicrobial outcome. They can be used on their own:

    -
    data_1st %>% portion_IR(amox)
    -# [1] 0.4617138
    -

    Or can be used in conjuction with group_by() and summarise(), both from the dplyr package:

    -
    data_1st %>% 
    -  group_by(hospital) %>% 
    -  summarise(amoxicillin = portion_IR(amox))
    + +

    Or can be used in conjuction with group_by() and summarise(), both from the dplyr package:

    +
    data_1st %>% 
    +  group_by(hospital) %>% 
    +  summarise(amoxicillin = portion_IR(amox))
    date2015-08-07D6Hospital AB_STPHY_AURRRSSMGram positiveStaphylococcusaureusTRUE
    2016-06-04T32011-12-05N6 Hospital BB_STPHY_AURB_ESCHR_COL RSI S S FGram positiveStaphylococcusaureusTRUE
    2012-09-25R6Hospital CB_STPHY_AURRSSSFGram positiveStaphylococcusaureusGram negativeEscherichiacoli TRUE
    2015-10-07A42012-08-21O9 Hospital BB_STPHY_AURSB_STRPTC_PNEI R RSMRF Gram positiveStaphylococcusaureusStreptococcuspneumoniae TRUE
    2016-04-12S62015-10-17P4 Hospital DB_KLBSL_PNERB_ESCHR_COLS S S S F Gram negativeKlebsiellapneumoniaeEscherichiacoli TRUE
    2010-11-24Z3Hospital C2014-03-12V8Hospital A B_ESCHR_COLSS R SFGram negativeEscherichiacoliTRUE
    2015-04-17L3Hospital DB_ESCHR_COLSRSSMGram negativeEscherichiacoliTRUE
    2012-09-29Q10Hospital BB_ESCHR_COLSS S S F
    1 Escherichia coli2,15749.2%2,15749.2%2,19549.3%2,19549.3%
    2 Staphylococcus aureus1,08924.8%3,24674.0%1,14225.7%3,33775.0%
    3 Streptococcus pneumoniae69415.8%3,94089.8%66615.0%4,00389.9%
    4 Klebsiella pneumoniae44810.2%4,38844910.1%4,452 100.0%
    @@ -948,27 +955,27 @@ Longest: 24

    - + - + - + - +
    hospital
    Hospital A0.45171100.5003802
    Hospital B0.44609160.4556401
    Hospital C0.48343370.4829822
    Hospital D0.48540540.4787686
    -

    Of course it would be very convenient to know the number of isolates responsible for the percentages. For that purpose the n_rsi() can be used, which works exactly like n_distinct() from the dplyr package. It counts all isolates available for every group (i.e. values S, I or R):

    -
    data_1st %>% 
    -  group_by(hospital) %>% 
    -  summarise(amoxicillin = portion_IR(amox),
    -            available = n_rsi(amox))
    +

    Of course it would be very convenient to know the number of isolates responsible for the percentages. For that purpose the n_rsi() can be used, which works exactly like n_distinct() from the dplyr package. It counts all isolates available for every group (i.e. values S, I or R):

    +
    data_1st %>% 
    +  group_by(hospital) %>% 
    +  summarise(amoxicillin = portion_IR(amox),
    +            available = n_rsi(amox))
    @@ -978,32 +985,32 @@ Longest: 24

    - + - - + + - - + + - - + +
    hospital
    Hospital A0.45171100.5003802 1315
    Hospital B0.446091614840.45564011578
    Hospital C0.48343376640.4829822617
    Hospital D0.48540549250.4787686942

    These functions can also be used to get the portion of multiple antibiotics, to calculate co-resistance very easily:

    -
    data_1st %>% 
    -  group_by(genus) %>% 
    -  summarise(amoxicillin = portion_S(amcl),
    -            gentamicin = portion_S(gent),
    -            "amox + gent" = portion_S(amcl, gent))
    +
    data_1st %>% 
    +  group_by(genus) %>% 
    +  summarise(amoxicillin = portion_S(amcl),
    +            gentamicin = portion_S(gent),
    +            "amox + gent" = portion_S(amcl, gent))
    @@ -1014,94 +1021,94 @@ Longest: 24

    - - - + + + - - - + + + - - - + + + - + - +
    genus
    Escherichia0.73018080.91515990.97728330.73120730.89749430.9753986
    Klebsiella0.71428570.90401790.98883930.75055680.93095770.9799555
    Staphylococcus0.75573920.91551880.97704320.74080560.92294220.9851138
    Streptococcus0.73054760.7522523 0.00000000.73054760.7522523

    To make a transition to the next part, let’s see how this difference could be plotted:

    -
    data_1st %>% 
    -  group_by(genus) %>% 
    -  summarise("1. Amoxicillin" = portion_S(amcl),
    -            "2. Gentamicin" = portion_S(gent),
    -            "3. Amox + gent" = portion_S(amcl, gent)) %>% 
    -  tidyr::gather("Antibiotic", "S", -genus) %>%
    -  ggplot(aes(x = genus,
    -             y = S,
    -             fill = Antibiotic)) +
    -  geom_col(position = "dodge2")
    +
    data_1st %>% 
    +  group_by(genus) %>% 
    +  summarise("1. Amoxicillin" = portion_S(amcl),
    +            "2. Gentamicin" = portion_S(gent),
    +            "3. Amox + gent" = portion_S(amcl, gent)) %>% 
    +  tidyr::gather("Antibiotic", "S", -genus) %>%
    +  ggplot(aes(x = genus,
    +             y = S,
    +             fill = Antibiotic)) +
    +  geom_col(position = "dodge2")

    Plots

    To show results in plots, most R users would nowadays use the ggplot2 package. This package lets you create plots in layers. You can read more about it on their website. A quick example would look like these syntaxes:

    -
    ggplot(data = a_data_set,
    -       mapping = aes(x = year,
    -                     y = value)) +
    -  geom_col() +
    -  labs(title = "A title",
    -       subtitle = "A subtitle",
    -       x = "My X axis",
    -       y = "My Y axis")
    -
    -ggplot(a_data_set,
    -       aes(year, value) +
    -  geom_bar()
    +
    ggplot(data = a_data_set,
    +       mapping = aes(x = year,
    +                     y = value)) +
    +  geom_col() +
    +  labs(title = "A title",
    +       subtitle = "A subtitle",
    +       x = "My X axis",
    +       y = "My Y axis")
    +
    +ggplot(a_data_set,
    +       aes(year, value) +
    +  geom_bar()

    The AMR package contains functions to extend this ggplot2 package, for example geom_rsi(). It automatically transforms data with count_df() or portion_df() and show results in stacked bars. Its simplest and shortest example:

    -
    ggplot(data_1st) +
    -  geom_rsi(translate_ab = FALSE)
    +
    ggplot(data_1st) +
    +  geom_rsi(translate_ab = FALSE)

    Omit the translate_ab = FALSE to have the antibiotic codes (amox, amcl, cipr, gent) translated to official WHO names (amoxicillin, amoxicillin and betalactamase inhibitor, ciprofloxacin, gentamicin).

    If we group on e.g. the genus column and add some additional functions from our package, we can create this:

    -
    # group the data on `genus`
    -ggplot(data_1st %>% group_by(genus)) + 
    -  # create bars with genus on x axis
    -  # it looks for variables with class `rsi`,
    -  # of which we have 4 (earlier created with `as.rsi`)
    -  geom_rsi(x = "genus") + 
    -  # split plots on antibiotic
    -  facet_rsi(facet = "Antibiotic") +
    -  # make R red, I yellow and S green
    -  scale_rsi_colours() +
    -  # show percentages on y axis
    -  scale_y_percent(breaks = 0:4 * 25) +
    -  # turn 90 degrees, make it bars instead of columns
    -  coord_flip() +
    -  # add labels
    -  labs(title = "Resistance per genus and antibiotic", 
    -       subtitle = "(this is fake data)") +
    -  # and print genus in italic to follow our convention
    -  # (is now y axis because we turned the plot)
    -  theme(axis.text.y = element_text(face = "italic"))
    +

    To simplify this, we also created the ggplot_rsi() function, which combines almost all above functions:

    -
    data_1st %>% 
    -  group_by(genus) %>%
    -  ggplot_rsi(x = "genus",
    -             facet = "Antibiotic",
    -             breaks = 0:4 * 25,
    -             datalabels = FALSE) +
    -  coord_flip()
    +

    @@ -1129,26 +1136,26 @@ Longest: 24

    We can transform the data and apply the test in only a couple of lines:

    -
    septic_patients %>%
    -  filter(hospital_id %in% c("A", "D")) %>% # filter on only hospitals A and D
    -  select(hospital_id, fosf) %>%            # select the hospitals and fosfomycin
    -  group_by(hospital_id) %>%                # group on the hospitals
    -  count_df(combine_IR = TRUE) %>%          # count all isolates per group (hospital_id)
    -  tidyr::spread(hospital_id, Value) %>%    # transform output so A and D are columns
    -  select(A, D) %>%                         # and select these only
    -  as.matrix() %>%                          # transform to good old matrix for fisher.test()
    -  fisher.test()                            # do Fisher's Exact Test
    -# 
    -#   Fisher's Exact Test for Count Data
    -# 
    -# data:  .
    -# p-value = 0.03104
    -# alternative hypothesis: true odds ratio is not equal to 1
    -# 95 percent confidence interval:
    -#  1.054283 4.735995
    -# sample estimates:
    -# odds ratio 
    -#   2.228006
    +
    septic_patients %>%
    +  filter(hospital_id %in% c("A", "D")) %>% # filter on only hospitals A and D
    +  select(hospital_id, fosf) %>%            # select the hospitals and fosfomycin
    +  group_by(hospital_id) %>%                # group on the hospitals
    +  count_df(combine_IR = TRUE) %>%          # count all isolates per group (hospital_id)
    +  tidyr::spread(hospital_id, Value) %>%    # transform output so A and D are columns
    +  select(A, D) %>%                         # and select these only
    +  as.matrix() %>%                          # transform to good old matrix for fisher.test()
    +  fisher.test()                            # do Fisher's Exact Test
    +# 
    +#   Fisher's Exact Test for Count Data
    +# 
    +# data:  .
    +# p-value = 0.03104
    +# alternative hypothesis: true odds ratio is not equal to 1
    +# 95 percent confidence interval:
    +#  1.054283 4.735995
    +# sample estimates:
    +# odds ratio 
    +#   2.228006

    As can be seen, the p value is 0.03, which means that the fosfomycin resistances found in hospital A and D are really different.

    diff --git a/docs/articles/AMR_files/figure-html/plot 1-1.png b/docs/articles/AMR_files/figure-html/plot 1-1.png index 3e32a38e..bed4123c 100644 Binary files a/docs/articles/AMR_files/figure-html/plot 1-1.png and b/docs/articles/AMR_files/figure-html/plot 1-1.png differ diff --git a/docs/articles/AMR_files/figure-html/plot 3-1.png b/docs/articles/AMR_files/figure-html/plot 3-1.png index 7756096e..1b5d363b 100644 Binary files a/docs/articles/AMR_files/figure-html/plot 3-1.png and b/docs/articles/AMR_files/figure-html/plot 3-1.png differ diff --git a/docs/articles/AMR_files/figure-html/plot 4-1.png b/docs/articles/AMR_files/figure-html/plot 4-1.png index ab474966..13ab47ff 100644 Binary files a/docs/articles/AMR_files/figure-html/plot 4-1.png and b/docs/articles/AMR_files/figure-html/plot 4-1.png differ diff --git a/docs/articles/AMR_files/figure-html/plot 5-1.png b/docs/articles/AMR_files/figure-html/plot 5-1.png index 36e811a0..9aa21099 100644 Binary files a/docs/articles/AMR_files/figure-html/plot 5-1.png and b/docs/articles/AMR_files/figure-html/plot 5-1.png differ diff --git a/docs/articles/EUCAST.html b/docs/articles/EUCAST.html index 577986e8..3e5fecf6 100644 --- a/docs/articles/EUCAST.html +++ b/docs/articles/EUCAST.html @@ -40,7 +40,7 @@ AMR (for R) - 0.5.0.9012 + 0.5.0.9015 @@ -76,6 +76,13 @@ Predict antimicrobial resistance
  • +
  • + + + + Work with WHONET data + +
  • @@ -178,7 +185,7 @@

    How to apply EUCAST rules

    Matthijs S. Berends

    -

    26 January 2019

    +

    28 January 2019

    diff --git a/docs/articles/G_test.html b/docs/articles/G_test.html index 7994429a..41a1a366 100644 --- a/docs/articles/G_test.html +++ b/docs/articles/G_test.html @@ -40,7 +40,7 @@
    AMR (for R) - 0.5.0.9012 + 0.5.0.9015 @@ -76,6 +76,13 @@ Predict antimicrobial resistance
  • +
  • + + + + Work with WHONET data + +
  • @@ -178,7 +185,7 @@

    How to use the G-test

    Matthijs S. Berends

    -

    26 January 2019

    +

    28 January 2019

    diff --git a/docs/articles/Predict.html b/docs/articles/Predict.html index 1099d4d7..ea6fe8e7 100644 --- a/docs/articles/Predict.html +++ b/docs/articles/Predict.html @@ -40,7 +40,7 @@
    AMR (for R) - 0.5.0.9012 + 0.5.0.9015 @@ -76,6 +76,13 @@ Predict antimicrobial resistance
  • +
  • + + + + Work with WHONET data + +
  • @@ -178,7 +185,7 @@

    How to predict antimicrobial resistance

    Matthijs S. Berends

    -

    26 January 2019

    +

    28 January 2019

    diff --git a/docs/articles/WHONET.html b/docs/articles/WHONET.html new file mode 100644 index 00000000..a63b7a2c --- /dev/null +++ b/docs/articles/WHONET.html @@ -0,0 +1,233 @@ + + + + + + + +How to work with WHONET data • AMR (for R) + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    +
    + + + + +

    (will be available soon)

    +
    + + + +
    + + + +
    + + + + + diff --git a/docs/articles/ab_property.html b/docs/articles/ab_property.html index 646f2b66..e9ab22eb 100644 --- a/docs/articles/ab_property.html +++ b/docs/articles/ab_property.html @@ -40,7 +40,7 @@ AMR (for R) - 0.5.0.9012 + 0.5.0.9015 @@ -76,6 +76,13 @@ Predict antimicrobial resistance
  • +
  • + + + + Work with WHONET data + +
  • @@ -178,7 +185,7 @@

    How to get properties of an antibiotic

    Matthijs S. Berends

    -

    26 January 2019

    +

    28 January 2019

    diff --git a/docs/articles/benchmarks.html b/docs/articles/benchmarks.html index 5336f0bd..14d3b463 100644 --- a/docs/articles/benchmarks.html +++ b/docs/articles/benchmarks.html @@ -40,7 +40,7 @@
    AMR (for R) - 0.5.0.9012 + 0.5.0.9015 @@ -76,6 +76,13 @@ Predict antimicrobial resistance
  • +
  • + + + + Work with WHONET data + +
  • @@ -178,7 +185,7 @@

    Benchmarks

    Matthijs S. Berends

    -

    26 January 2019

    +

    28 January 2019

    @@ -240,15 +247,15 @@
    library(dplyr)
     # take 500,000 random MO codes from the septic_patients data set
     x = septic_patients %>%
    -  sample_n(500000, replace = TRUE) %>%
    -  pull(mo)
    +  sample_n(500000, replace = TRUE) %>%
    +  pull(mo)
       
     # got the right length?
     length(x)
     # [1] 500000
     
     # and how many unique values do we have?
    -n_distinct(x)
    +n_distinct(x)
     # [1] 96
     
     # only 96, but distributed in 500,000 results. now let's see:
    diff --git a/docs/articles/freq.html b/docs/articles/freq.html
    index fdba7fd2..1bf094bf 100644
    --- a/docs/articles/freq.html
    +++ b/docs/articles/freq.html
    @@ -40,7 +40,7 @@
           
           
             AMR (for R)
    -        0.5.0.9012
    +        0.5.0.9015
           
         
    @@ -76,6 +76,13 @@ Predict antimicrobial resistance
  • +
  • + + + + Work with WHONET data + +
  • @@ -178,7 +185,7 @@

    How to create frequency tables

    Matthijs S. Berends

    -

    26 January 2019

    +

    28 January 2019

    @@ -197,7 +204,7 @@
    Frequencies of one variable

    To only show and quickly review the content of one variable, you can just select this variable in various ways. Let’s say we want to get the frequencies of the gender variable of the septic_patients dataset:

    -

    Frequency table of gender

    +

    Frequency table

    @@ -248,7 +255,7 @@

    So now the genus and species variables are available. A frequency table of these combined variables can be created like this:

    my_patients %>%
       freq(genus, species, nmax = 15)
    -

    Frequency table of genus and species

    +

    Frequency table

    @@ -392,7 +399,7 @@ septic_patients %>% distinct(patient_id, .keep_all = TRUE) %>% freq(age, nmax =5, header =TRUE) -

    Frequency table of age
    +

    Frequency table
    Class: numeric
    Length: 981 (of which NA: 0 = 0.00%)
    Unique: 73

    @@ -471,7 +478,7 @@ Outliers: 15 (unique count: 12)

    sort.count is TRUE by default. Compare this default behaviour…

    -

    Frequency table of hospital_id

    +

    Frequency table

    @@ -519,7 +526,7 @@ Outliers: 15 (unique count: 12)

    … with this, where items are now sorted on count:

    septic_patients %>%
       freq(hospital_id, sort.count = FALSE)
    -

    Frequency table of hospital_id

    +

    Frequency table

    @@ -567,7 +574,7 @@ Outliers: 15 (unique count: 12)

    All classes will be printed into the header (default is FALSE when using markdown like this document). Variables with the new rsi class of this AMR package are actually ordered factors and have three classes (look at Class in the header):

    septic_patients %>%
       freq(amox, header = TRUE)
    -

    Frequency table of amox
    +

    Frequency table
    Class: factor > ordered > rsi (numeric)
    Levels: S < I < R
    Length: 2,000 (of which NA: 828 = 41.40%)
    @@ -616,7 +623,7 @@ Unique: 3

    Frequencies of dates will show the oldest and newest date in the data, and the amount of days between them:

    septic_patients %>%
       freq(date, nmax = 5, header = TRUE)
    -

    Frequency table of date
    +

    Frequency table
    Class: Date (numeric)
    Length: 2,000 (of which NA: 0 = 0.00%)
    Unique: 1,140

    @@ -698,7 +705,7 @@ Median: 31 July 2009 (47.39%)

    With the na.rm parameter (defaults to TRUE, but they will always be shown into the header), you can include NA values in the frequency table:

    septic_patients %>%
       freq(amox, na.rm = FALSE)
    -

    Frequency table of amox

    +

    Frequency table

    @@ -751,7 +758,7 @@ Median: 31 July 2009 (47.39%)

    The default frequency tables shows row indices. To remove them, use row.names = FALSE:

    septic_patients %>%
       freq(hospital_id, row.names = FALSE)
    -

    Frequency table of hospital_id

    +

    Frequency table

    @@ -799,7 +806,7 @@ Median: 31 July 2009 (47.39%)

    The markdown parameter is TRUE at default in non-interactive sessions, like in reports created with R Markdown. This will always print all rows, unless nmax is set.

    septic_patients %>%
       freq(hospital_id, markdown = TRUE)
    -

    Frequency table of hospital_id

    +

    Frequency table

    Item
    diff --git a/docs/articles/index.html b/docs/articles/index.html index 9c46efc2..510e651c 100644 --- a/docs/articles/index.html +++ b/docs/articles/index.html @@ -78,7 +78,7 @@ AMR (for R) - 0.5.0.9014 + 0.5.0.9015 @@ -114,6 +114,13 @@ Predict antimicrobial resistance +
  • + + + + Work with WHONET data + +
  • @@ -226,6 +233,7 @@
  • How to apply EUCAST rules
  • How to use the *G*-test
  • How to predict antimicrobial resistance
  • +
  • How to work with WHONET data
  • How to get properties of an antibiotic
  • Benchmarks
  • How to create frequency tables
  • diff --git a/docs/articles/mo_property.html b/docs/articles/mo_property.html index 23456cc7..3b565b7c 100644 --- a/docs/articles/mo_property.html +++ b/docs/articles/mo_property.html @@ -40,7 +40,7 @@ AMR (for R) - 0.5.0.9012 + 0.5.0.9015 @@ -76,6 +76,13 @@ Predict antimicrobial resistance +
  • + + + + Work with WHONET data + +
  • @@ -178,7 +185,7 @@

    How to get properties of a microorganism

    Matthijs S. Berends

    -

    26 January 2019

    +

    28 January 2019

    diff --git a/docs/authors.html b/docs/authors.html index 6eee37d7..30d97985 100644 --- a/docs/authors.html +++ b/docs/authors.html @@ -78,7 +78,7 @@
    AMR (for R) - 0.5.0.9014 + 0.5.0.9015 @@ -114,6 +114,13 @@ Predict antimicrobial resistance
  • +
  • + + + + Work with WHONET data + +
  • diff --git a/docs/index.html b/docs/index.html index 0cd2fc42..289501ae 100644 --- a/docs/index.html +++ b/docs/index.html @@ -42,7 +42,7 @@ AMR (for R) - 0.5.0.9014 + 0.5.0.9015 @@ -78,6 +78,13 @@ Predict antimicrobial resistance
  • +
  • + + + + Work with WHONET data + +
  • @@ -182,7 +189,7 @@

    (TLDR - to find out how to conduct AMR analysis, please continue reading here to get started.


    -

    AMR is a free and open-source R package to simplify the analysis and prediction of Antimicrobial Resistance (AMR) and to work with microbial and antimicrobial properties by using evidence-based methods.

    +

    AMR is a free and open-source R package to simplify the analysis and prediction of Antimicrobial Resistance (AMR) and to work with microbial and antimicrobial properties by using evidence-based methods. It supports any table format, including WHONET/EARS-Net data.

    We created this package for both academic research and routine analysis at the Faculty of Medical Sciences of the University of Groningen and the Medical Microbiology & Infection Prevention (MMBI) department of the University Medical Center Groningen (UMCG). This R package is actively maintained and free software; you can freely use and distribute it for both personal and commercial (but not patent) purposes under the terms of the GNU General Public Licence version 2.0 (GPL-2), as published by the Free Software Foundation. Read the full licence here.

    This package can be used for:

      @@ -222,28 +229,30 @@
    • Software developers
    • Web application / Shiny developers
    -
    -

    -Get this package

    +
    +

    +Get this package

    This package is available on the official R network (CRAN), which has a peer-reviewed submission process. Install this package in R with:

    It will be downloaded and installed automatically. For RStudio, click on the menu Tools > Install Packages… and then type in “AMR” and press Install.

    +

    The latest and unpublished development version can be installed with (precaution: may be unstable):

    +
    install.packages("devtools")
    +devtools::install_gitlab("msberends/AMR")
    -
    -

    -Get started

    +
    +

    +Get started

    To find out how to conduct AMR analysis, please continue reading here to get started or click the links in the ‘How to’ menu.

    -
    -

    -Short introduction

    -
    +
    +

    +Short introduction

    +

    -Microbial (taxonomic) reference data

    -

    -

    This package contains the complete microbial taxonomic data (with all nine taxonomic ranks - from kingdom to subspecies) from the publicly available Integrated Taxonomic Information System (ITIS, https://www.itis.gov).

    -

    All ~20,000 (sub)species from the taxonomic kingdoms Bacteria, Fungi and Protozoa are included in this package, as well as all their ~2,500 previously accepted names known to ITIS. Furthermore, the responsible authors and year of publication are available. This allows users to use authoritative taxonomic information for their data analysis on any microorganism, not only human pathogens. It also helps to quickly determine the Gram stain of bacteria, since ITIS honours the taxonomic branching order of bacterial phyla according to Cavalier-Smith (2002), which defines that all bacteria are classified into either subkingdom Negibacteria or subkingdom Posibacteria.

    -

    Read more about the data from ITIS in our manual.

    +WHONET / EARS-Net +

    +

    We support data (exported files) from WHONET. The AMR package contains a data set antibiotics which also contains all EARS-Net antibiotic abbreviations. Furthermore, when using WHONET data as input for analysis all input parameters will be set automatically.

    +

    Read our tutorial about how to work with WHONET data here.

    @@ -254,6 +263,14 @@

    This package contains all ~500 antimicrobial drugs and their Anatomical Therapeutic Chemical (ATC) codes, ATC groups and Defined Daily Dose (DDD) from the World Health Organization Collaborating Centre for Drug Statistics Methodology (WHOCC, https://www.whocc.no) and the Pharmaceuticals Community Register of the European Commission.

    Read more about the data from WHOCC in our manual.

    +
    +

    +Microbial (taxonomic) reference data

    +

    +

    This package contains the complete microbial taxonomic data (with all nine taxonomic ranks - from kingdom to subspecies) from the publicly available Integrated Taxonomic Information System (ITIS, https://www.itis.gov).

    +

    All ~20,000 (sub)species from the taxonomic kingdoms Bacteria, Fungi and Protozoa are included in this package, as well as all their ~2,500 previously accepted names known to ITIS. Furthermore, the responsible authors and year of publication are available. This allows users to use authoritative taxonomic information for their data analysis on any microorganism, not only human pathogens. It also helps to quickly determine the Gram stain of bacteria, since ITIS honours the taxonomic branching order of bacterial phyla according to Cavalier-Smith (2002), which defines that all bacteria are classified into either subkingdom Negibacteria or subkingdom Posibacteria.

    +

    Read more about the data from ITIS in our manual.

    +

    Overview of functions

    diff --git a/docs/news/index.html b/docs/news/index.html index c74c4e51..5aebe7e9 100644 --- a/docs/news/index.html +++ b/docs/news/index.html @@ -78,7 +78,7 @@ AMR (for R) - 0.5.0.9014 + 0.5.0.9015
    @@ -114,6 +114,13 @@ Predict antimicrobial resistance
  • +
  • + + + + Work with WHONET data + +
  • @@ -229,6 +236,12 @@