2019-05-10 16:44:59 +02:00
# ==================================================================== #
# TITLE #
2021-02-02 23:57:35 +01:00
# Antimicrobial Resistance (AMR) Data Analysis for R #
2019-05-10 16:44:59 +02:00
# #
# SOURCE #
2020-07-08 14:48:06 +02:00
# https://github.com/msberends/AMR #
2019-05-10 16:44:59 +02:00
# #
# LICENCE #
2021-12-23 18:56:28 +01:00
# (c) 2018-2022 Berends MS, Luz CF et al. #
2020-10-08 11:16:03 +02:00
# Developed at the University of Groningen, the Netherlands, in #
# collaboration with non-profit organisations Certe Medical #
# Diagnostics & Advice, and University Medical Center Groningen. #
2019-05-10 16:44:59 +02:00
# #
# This R package is free software; you can freely use and distribute #
# it for both personal and commercial purposes under the terms of the #
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
# the Free Software Foundation. #
2020-01-05 17:22:09 +01:00
# We created this package for both routine data analysis and academic #
# research and it was publicly released in the hope that it will be #
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
2020-10-08 11:16:03 +02:00
# #
# Visit our website for the full manual and a complete tutorial about #
2021-02-02 23:57:35 +01:00
# how to conduct AMR data analysis: https://msberends.github.io/AMR/ #
2019-05-10 16:44:59 +02:00
# ==================================================================== #
2021-01-18 16:57:56 +01:00
#' Transform Input to Disk Diffusion Diameters
2019-05-10 16:44:59 +02:00
#'
2020-09-03 12:31:48 +02:00
#' This transforms a vector to a new class [`disk`], which is a disk diffusion growth zone size (around an antibiotic disk) in millimetres between 6 and 50.
2021-01-18 16:57:56 +01:00
#' @inheritSection lifecycle Stable Lifecycle
2019-05-10 16:44:59 +02:00
#' @rdname as.disk
#' @param x vector
2021-05-12 18:15:03 +02:00
#' @param na.rm a [logical] indicating whether missing values should be removed
2019-11-28 22:32:17 +01:00
#' @details Interpret disk values as RSI values with [as.rsi()]. It supports guidelines from EUCAST and CLSI.
2020-09-18 16:05:53 +02:00
#' @return An [integer] with additional class [`disk`]
2019-11-06 14:43:23 +01:00
#' @aliases disk
2019-05-10 16:44:59 +02:00
#' @export
2019-11-28 22:32:17 +01:00
#' @seealso [as.rsi()]
2021-01-18 16:57:56 +01:00
#' @inheritSection AMR Read more on Our Website!
2019-05-10 16:44:59 +02:00
#' @examples
2020-09-29 23:35:46 +02:00
#' \donttest{
2020-02-17 14:38:01 +01:00
#' # transform existing disk zones to the `disk` class
#' df <- data.frame(microorganism = "E. coli",
#' AMP = 20,
#' CIP = 14,
#' GEN = 18,
#' TOB = 16)
2020-09-29 23:35:46 +02:00
#' df[, 2:5] <- lapply(df[, 2:5], as.disk)
#' # same with dplyr:
#' # df %>% mutate(across(AMP:TOB, as.disk))
2020-02-17 14:38:01 +01:00
#'
#' # interpret disk values, see ?as.rsi
#' as.rsi(x = as.disk(18),
#' mo = "Strep pneu", # `mo` will be coerced with as.mo()
#' ab = "ampicillin", # and `ab` with as.ab()
2019-05-10 16:44:59 +02:00
#' guideline = "EUCAST")
2020-02-17 14:38:01 +01:00
#'
#' as.rsi(df)
2020-05-16 21:40:50 +02:00
#' }
2019-05-10 16:44:59 +02:00
as.disk <- function ( x , na.rm = FALSE ) {
2020-10-19 17:09:19 +02:00
meet_criteria ( x , allow_class = c ( " disk" , " character" , " numeric" , " integer" ) , allow_NA = TRUE )
meet_criteria ( na.rm , allow_class = " logical" , has_length = 1 )
2020-05-19 12:08:49 +02:00
if ( ! is.disk ( x ) ) {
2021-01-24 14:48:56 +01:00
x <- unlist ( x )
2019-05-10 16:44:59 +02:00
if ( na.rm == TRUE ) {
x <- x [ ! is.na ( x ) ]
}
x.bak <- x
2020-07-13 09:17:24 +02:00
2019-05-10 16:44:59 +02:00
na_before <- length ( x [is.na ( x ) ] )
2020-07-13 09:17:24 +02:00
2020-12-28 22:24:33 +01:00
# heavily based on cleaner::clean_double():
2020-08-16 21:38:42 +02:00
clean_double2 <- function ( x , remove = " [^0-9.,-]" , fixed = FALSE ) {
x <- gsub ( " ," , " ." , x )
# remove ending dot/comma
x <- gsub ( " [,.]$" , " " , x )
# only keep last dot/comma
2020-12-28 22:24:33 +01:00
reverse <- function ( x ) vapply ( FUN.VALUE = character ( 1 ) , lapply ( strsplit ( x , NULL ) , rev ) , paste , collapse = " " )
2020-08-16 21:38:42 +02:00
x <- sub ( " {{dot}}" , " ." ,
gsub ( " ." , " " ,
reverse ( sub ( " ." , " }}tod{{" ,
reverse ( x ) ,
fixed = TRUE ) ) ,
fixed = TRUE ) ,
fixed = TRUE )
x_clean <- gsub ( remove , " " , x , ignore.case = TRUE , fixed = fixed )
# remove everything that is not a number or dot
2021-05-24 00:06:28 +02:00
as.double ( gsub ( " [^0-9.]+" , " " , x_clean ) )
2020-08-16 21:38:42 +02:00
}
# round up and make it an integer
x <- as.integer ( ceiling ( clean_double2 ( x ) ) )
2020-07-13 09:17:24 +02:00
2019-12-21 10:56:06 +01:00
# disks can never be less than 6 mm (size of smallest disk) or more than 50 mm
x [x < 6 | x > 50 ] <- NA_integer_
2019-05-10 16:44:59 +02:00
na_after <- length ( x [is.na ( x ) ] )
2020-07-13 09:17:24 +02:00
2019-05-10 16:44:59 +02:00
if ( na_before != na_after ) {
2020-09-18 16:05:53 +02:00
list_missing <- x.bak [is.na ( x ) & ! is.na ( x.bak ) ] %pm>%
unique ( ) %pm>%
2021-02-04 16:48:16 +01:00
sort ( ) %pm>%
vector_and ( quotes = TRUE )
2022-03-02 15:38:55 +01:00
warning_ ( " in `as.disk()`: " , na_after - na_before , " results truncated (" ,
2020-11-10 16:35:56 +01:00
round ( ( ( na_after - na_before ) / length ( x ) ) * 100 ) ,
" %) that were invalid disk zones: " ,
2022-03-02 15:38:55 +01:00
list_missing )
2019-05-10 16:44:59 +02:00
}
}
2020-11-16 16:57:55 +01:00
set_clean_class ( as.integer ( x ) ,
new_class = c ( " disk" , " integer" ) )
2019-05-10 16:44:59 +02:00
}
2020-02-20 13:19:23 +01:00
all_valid_disks <- function ( x ) {
2020-10-19 17:09:19 +02:00
if ( ! inherits ( x , c ( " disk" , " character" , " numeric" , " integer" ) ) ) {
return ( FALSE )
}
2020-12-17 16:22:25 +01:00
x_disk <- tryCatch ( suppressWarnings ( as.disk ( x [ ! is.na ( x ) ] ) ) ,
error = function ( e ) NA )
! any ( is.na ( x_disk ) ) && ! all ( is.na ( x ) )
2020-02-20 13:19:23 +01:00
}
2021-11-28 23:01:26 +01:00
#' @rdname as.disk
#' @details `NA_disk_` is a missing value of the new `<disk>` class.
#' @export
NA_disk_ <- set_clean_class ( as.integer ( NA_real_ ) ,
new_class = c ( " disk" , " integer" ) )
2019-05-10 16:44:59 +02:00
#' @rdname as.disk
#' @export
is.disk <- function ( x ) {
2020-02-10 14:18:15 +01:00
inherits ( x , " disk" )
2019-05-10 16:44:59 +02:00
}
2020-08-28 21:55:47 +02:00
# will be exported using s3_register() in R/zzz.R
2020-08-26 11:33:54 +02:00
pillar_shaft.disk <- function ( x , ... ) {
out <- trimws ( format ( x ) )
2020-08-28 21:55:47 +02:00
out [is.na ( x ) ] <- font_na ( NA )
create_pillar_column ( out , align = " right" , width = 2 )
2020-08-26 11:33:54 +02:00
}
2020-08-28 21:55:47 +02:00
# will be exported using s3_register() in R/zzz.R
2020-08-26 11:33:54 +02:00
type_sum.disk <- function ( x , ... ) {
" disk"
}
2020-05-28 16:48:55 +02:00
#' @method print disk
2019-05-10 16:44:59 +02:00
#' @export
#' @noRd
print.disk <- function ( x , ... ) {
2020-05-27 16:37:49 +02:00
cat ( " Class <disk>\n" )
2019-05-10 16:44:59 +02:00
print ( as.integer ( x ) , quote = FALSE )
}
2019-08-12 14:48:09 +02:00
2020-05-28 16:48:55 +02:00
#' @method [ disk
2020-03-14 14:05:43 +01:00
#' @export
#' @noRd
" [.disk" <- function ( x , ... ) {
y <- NextMethod ( )
attributes ( y ) <- attributes ( x )
y
}
2020-05-28 16:48:55 +02:00
#' @method [[ disk
2020-03-14 14:05:43 +01:00
#' @export
#' @noRd
" [[.disk" <- function ( x , ... ) {
y <- NextMethod ( )
attributes ( y ) <- attributes ( x )
y
}
2020-05-28 16:48:55 +02:00
#' @method [<- disk
2020-03-14 14:05:43 +01:00
#' @export
#' @noRd
" [<-.disk" <- function ( i , j , ... , value ) {
2020-04-13 21:09:56 +02:00
value <- as.disk ( value )
2020-03-14 14:05:43 +01:00
y <- NextMethod ( )
attributes ( y ) <- attributes ( i )
y
}
2020-05-28 16:48:55 +02:00
#' @method [[<- disk
2020-03-14 14:05:43 +01:00
#' @export
#' @noRd
" [[<-.disk" <- function ( i , j , ... , value ) {
2020-04-13 21:09:56 +02:00
value <- as.disk ( value )
2020-03-14 14:05:43 +01:00
y <- NextMethod ( )
attributes ( y ) <- attributes ( i )
y
}
2020-05-28 16:48:55 +02:00
#' @method c disk
2020-03-14 14:05:43 +01:00
#' @export
#' @noRd
2021-05-03 13:06:43 +02:00
c.disk <- function ( ... ) {
as.disk ( unlist ( lapply ( list ( ... ) , as.character ) ) )
2020-03-14 14:05:43 +01:00
}
2020-09-25 14:44:50 +02:00
#' @method unique disk
#' @export
#' @noRd
unique.disk <- function ( x , incomparables = FALSE , ... ) {
y <- NextMethod ( )
attributes ( y ) <- attributes ( x )
y
}
2020-09-28 01:08:55 +02:00
2021-07-06 16:35:14 +02:00
#' @method rep disk
#' @export
#' @noRd
rep.disk <- function ( x , ... ) {
y <- NextMethod ( )
attributes ( y ) <- attributes ( x )
y
}
2020-09-28 01:08:55 +02:00
# will be exported using s3_register() in R/zzz.R
get_skimmers.disk <- function ( column ) {
2020-12-17 16:22:25 +01:00
skimr :: sfl (
2020-09-28 01:08:55 +02:00
skim_type = " disk" ,
2020-09-28 11:00:59 +02:00
min = ~ min ( as.double ( .) , na.rm = TRUE ) ,
max = ~ max ( as.double ( .) , na.rm = TRUE ) ,
2020-09-28 01:08:55 +02:00
median = ~ stats :: median ( as.double ( .) , na.rm = TRUE ) ,
2021-05-06 15:17:11 +02:00
n_unique = ~ length ( unique ( stats :: na.omit ( .) ) ) ,
2020-12-17 16:22:25 +01:00
hist = ~ skimr :: inline_hist ( stats :: na.omit ( as.double ( .) ) )
2020-09-28 01:08:55 +02:00
)
}