From d0d914364d9128ce90d13e54dce5953f8801932e Mon Sep 17 00:00:00 2001 From: Marcin <133694481+m7pr@users.noreply.github.com> Date: Wed, 18 Oct 2023 21:14:55 +0200 Subject: [PATCH 1/4] 373 slices_restore will restore Dates and POSIXT classes (#432) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #373 A very small proposition on how we can guess that a character contains a Date a POSIXT time. Up to be discussed as we might want to just use jsonlite::serializeJSON and jsonlite::unserializeJSON # The code ```{R} x <- teal_slice( dataname = "ADSL", varname = "COUNTRY", selected = as.POSIXct(c("2023-06-29 18:05:32 CEST", "2023-06-29 18:15:32 CEST")), fixed = TRUE ) class(as.list(x)$selected) t <- teal_slice( dataname = "ADSL", varname = "TIME", selected = as.Date(c("2023-06-29", "2023-06-30")), fixed = TRUE ) class(as.list(t)$selected) y <- teal_slices(x, t) slices_store(y, file = 'test1.json') z <- slices_restore('test1.json') class(shiny::isolate(z[[1]]$selected)) class(shiny::isolate(z[[2]]$selected)) ```` # The code with results ```{R} > x <- + teal_slice( + dataname = "ADSL", + varname = "COUNTRY", + selected = as.POSIXct(c("2023-06-29 18:05:32 CEST", "2023-06-29 18:15:32 CEST")), + fixed = TRUE + ) > class(as.list(x)$selected) [1] "POSIXct" "POSIXt" > > t <- + teal_slice( + dataname = "ADSL", + varname = "TIME", + selected = as.Date(c("2023-06-29", "2023-06-30")), + fixed = TRUE + ) > class(as.list(t)$selected) [1] "Date" > > y <- teal_slices(x, t) > slices_store(y, file = 'test1.json') > > z <- slices_restore('test1.json') > > class(shiny::isolate(z[[1]]$selected)) [1] "POSIXct" "POSIXt" > class(shiny::isolate(z[[2]]$selected)) [1] "Date" ``` --------- Signed-off-by: Marcin <133694481+m7pr@users.noreply.github.com> Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: André Veríssimo <211358+averissimo@users.noreply.github.com> --- R/teal_slice-store.R | 25 ++++ R/teal_slice.R | 20 +++- R/teal_slices.R | 4 + man/slices_store.Rd | 7 ++ man/teal_slice.Rd | 9 +- man/teal_slices.Rd | 5 + tests/testthat/test-teal_slice-store.R | 151 +++++++++++++++++++++++++ tests/testthat/test-teal_slice.R | 18 +++ 8 files changed, 234 insertions(+), 5 deletions(-) create mode 100644 tests/testthat/test-teal_slice-store.R diff --git a/R/teal_slice-store.R b/R/teal_slice-store.R index 5bc570dd2..39faebc00 100644 --- a/R/teal_slice-store.R +++ b/R/teal_slice-store.R @@ -9,6 +9,12 @@ #' @param file (`character(1)`) The file path where `teal_slices` object will be saved. #' The file extension should be `".json"`. #' +#' @details `Date` classes is stored in `"ISO8601"` format (`YYYY-MM-DD`). `POSIX*t` classes are converted to a +#' character with the usage of `format.POSIX*t(usetz = TRUE, tz = "UTC")` (`YYYY-MM-DD {N}{N}:{N}{N}:{N}{N} UTC`, where +#' `{N} = [0-9]` is a number and `UTC` is `Coordinated Universal Time` timezone short-code). +#' This format is assumed during `slices_restore`. All `teal_slices` containing `teal_slice`s that have `selected` or +#' `choices` fields of `POSIX*t` class are always converted to `UTC` timezone during `print` and `format` as well. +#' #' @return `NULL`, invisibly. #' #' @examples @@ -51,6 +57,25 @@ slices_restore <- function(file) { checkmate::assert_file_exists(file, access = "r", extension = "json") tss_json <- jsonlite::fromJSON(file, simplifyDataFrame = FALSE) + tss_json$slices <- + lapply(tss_json$slices, function(slice) { + for (field in c("selected", "choices")) { + if (!is.null(slice[[field]])) { + date_partial_regex <- "^[0-9]{4}-[0-9]{2}-[0-9]{2}" + time_stamp_regex <- paste0(date_partial_regex, "\\s[0-9]{2}:[0-9]{2}:[0-9]{2}\\sUTC$") + + slice[[field]] <- + if (all(grepl(paste0(date_partial_regex, "$"), slice[[field]]))) { + as.Date(slice[[field]]) + } else if (all(grepl(time_stamp_regex, slice[[field]]))) { + as.POSIXct(slice[[field]], tz = "UTC") + } else { + slice[[field]] + } + } + } + slice + }) tss_elements <- lapply(tss_json$slices, as.teal_slice) diff --git a/R/teal_slice.R b/R/teal_slice.R index 938c04e6f..c24fef7f5 100644 --- a/R/teal_slice.R +++ b/R/teal_slice.R @@ -58,9 +58,9 @@ #' requires `dataname` prefix, *e.g.* `data$var == "x"`. #' @param choices (optional `vector`) specifying allowed choices; #' When specified it should be a subset of values in variable denoted by `varname`; -#' Type and size depends on variable type. +#' Type and size depends on variable type. Factors are coerced to character. #' @param selected (optional `vector`) of selected values from `choices`; -#' Type and size depends on variable type. +#' Type and size depends on variable type. Factors are coerced to character. #' @param multiple (optional `logical(1)`) flag specifying whether more than one value can be selected; #' only applicable to `ChoicesFilterState` and `LogicalFilterState` #' @param keep_na (optional `logical(1)`) flag specifying whether to keep missing values @@ -78,6 +78,10 @@ #' @return A `teal.slice` object. Depending on whether `varname` or `expr` was specified, the resulting #' `teal_slice` also receives class `teal_slice_var` or `teal_slice_expr`, respectively. #' +#' @note When `teal_slice` is printed and contains a `POSIX*t` class in `selected` or `choices` fields, then those +#' fields are converted to `UTC` timezone, for enhanced and unified storage and restoring with `slices_store()` and +#' `slices_restore()`. +#' #' @examples #' x1 <- teal_slice( #' dataname = "data", @@ -155,6 +159,8 @@ teal_slice <- function(dataname, ) formal_args <- formal_args[ts_var_args] args <- c(formal_args, list(...)) + args[c("choices", "selected")] <- + lapply(args[c("choices", "selected")], function(x) if (is.factor(x)) as.character(x) else x) if (missing(id)) { args$id <- get_default_slice_id(args) } else { @@ -268,7 +274,7 @@ to_json <- function(x) { vars <- c("selected", "choices") if (is.list(x)) { for (var in vars) { - if (!is.null(x[[var]])) x[[var]] <- I(x[[var]]) + if (!is.null(x[[var]])) x[[var]] <- I(format_time(x[[var]])) } lapply(x, no_unbox) } else { @@ -279,6 +285,14 @@ to_json <- function(x) { jsonlite::toJSON(no_unbox(x), pretty = TRUE, auto_unbox = TRUE, digits = 16, null = "null") } +format_time <- function(x) { + if ("POSIXt" %in% class(x)) { + format(x, format = "%Y-%m-%d %H:%M:%S", usetz = TRUE, tz = "UTC") + } else { + x + } +} + #' Justify Colons in `JSON` String #' #' This function takes a `JSON` string as input, splits it into lines, and pads element names diff --git a/R/teal_slices.R b/R/teal_slices.R index ec0a7dbb5..9686ff79b 100644 --- a/R/teal_slices.R +++ b/R/teal_slices.R @@ -30,6 +30,10 @@ #' @param i (`character` or `numeric` or `logical`) indicating which elements to extract #' @param recursive (`logical(1)`) flag specifying whether to also convert to list the elements of this `teal_slices` #' +#' @note When `teal_slices` are printed and any of `teal_slice` elements contain a `POSIX*t` class in `selected` or +#' `choices` fields, then those fields are converted to `UTC` timezone, for enhanced and unified storage and restoring +#' with `slices_store()` and `slices_restore()`. +#' #' @return #' `teal_slices`, which is an unnamed list of `teal_slice` objects. #' diff --git a/man/slices_store.Rd b/man/slices_store.Rd index 1d16c1ccb..5722a4cb0 100644 --- a/man/slices_store.Rd +++ b/man/slices_store.Rd @@ -21,6 +21,13 @@ The \code{teal_slices} object contains information about filter states and can b create, modify, and delete filter states. The saved file can be later loaded using the \code{slices_restore} function. } +\details{ +\code{Date} classes is stored in \code{"ISO8601"} format (\code{YYYY-MM-DD}). \code{POSIX*t} classes are converted to a +character with the usage of \code{format.POSIX*t(usetz = TRUE, tz = "UTC")} (\verb{YYYY-MM-DD \{N\}\{N\}:\{N\}\{N\}:\{N\}\{N\} UTC}, where +\verb{\{N\} = [0-9]} is a number and \code{UTC} is \verb{Coordinated Universal Time} timezone short-code). +This format is assumed during \code{slices_restore}. All \code{teal_slices} containing \code{teal_slice}s that have \code{selected} or +\code{choices} fields of \code{POSIX*t} class are always converted to \code{UTC} timezone during \code{print} and \code{format} as well. +} \examples{ # Create a teal_slices object tss <- teal_slices( diff --git a/man/teal_slice.Rd b/man/teal_slice.Rd index bab8f4c9d..b94c3ec0d 100644 --- a/man/teal_slice.Rd +++ b/man/teal_slice.Rd @@ -50,10 +50,10 @@ requires \code{dataname} prefix, \emph{e.g.} \code{data$var == "x"}.} \item{choices}{(optional \code{vector}) specifying allowed choices; When specified it should be a subset of values in variable denoted by \code{varname}; -Type and size depends on variable type.} +Type and size depends on variable type. Factors are coerced to character.} \item{selected}{(optional \code{vector}) of selected values from \code{choices}; -Type and size depends on variable type.} +Type and size depends on variable type. Factors are coerced to character.} \item{keep_na}{(optional \code{logical(1)}) flag specifying whether to keep missing values} @@ -121,6 +121,11 @@ In a \code{FilterState} instantiated with \code{fixed = TRUE} the features Note that a \code{FilterStateExpr} is always considered to have \code{fixed = TRUE}. A \code{FilterState} instantiated with \code{anchored = TRUE} cannot be removed. } +\note{ +When \code{teal_slice} is printed and contains a \code{POSIX*t} class in \code{selected} or \code{choices} fields, then those +fields are converted to \code{UTC} timezone, for enhanced and unified storage and restoring with \code{slices_store()} and +\code{slices_restore()}. +} \section{Filters in \code{SumarizedExperiment} and \code{MultiAssayExperiment} objects}{ diff --git a/man/teal_slices.Rd b/man/teal_slices.Rd index 681db4e65..befc8e2c6 100644 --- a/man/teal_slices.Rd +++ b/man/teal_slices.Rd @@ -83,6 +83,11 @@ The former enumerates allowed variables, the latter enumerates forbidden values. Since these could be mutually exclusive, it is impossible to set both allowed and forbidden variables for one data set in one \code{teal_slices}. } +\note{ +When \code{teal_slices} are printed and any of \code{teal_slice} elements contain a \code{POSIX*t} class in \code{selected} or +\code{choices} fields, then those fields are converted to \code{UTC} timezone, for enhanced and unified storage and restoring +with \code{slices_store()} and \code{slices_restore()}. +} \examples{ filter_1 <- teal_slice( dataname = "dataname1", diff --git a/tests/testthat/test-teal_slice-store.R b/tests/testthat/test-teal_slice-store.R new file mode 100644 index 000000000..30e251130 --- /dev/null +++ b/tests/testthat/test-teal_slice-store.R @@ -0,0 +1,151 @@ +testthat::test_that("teal_slice store/restore supports saving `POSIXct` timestamps in selected", { + slices_path <- withr::local_file("slices.json") + + time_stamps <- Sys.time() + c(-10 * 60 * 60 * 24, -30, 0) + + # ISO8601 does not keep milliseconds + time_stamps <- as.POSIXct( + ceiling(as.double(time_stamps)), + tz = "UTC", + origin = "1970-01-01" + ) + + tss <- teal_slices( + teal_slice( + dataname = "ADSL", + varname = "EOSDTM", + selected = time_stamps, + fixed = TRUE + ) + ) + + # Store the teal_slices object to a file + slices_store(tss, slices_path) + tss_restored <- slices_restore(slices_path) + + tss_restored_list <- shiny::isolate(shiny::reactiveValuesToList(tss_restored[[1]])) + testthat::expect_s3_class(tss_restored_list$selected, "POSIXct") + + expect_identical_slice(tss[[1]], tss_restored[[1]]) +}) + +testthat::test_that("teal_slice store/restore supports saving `Date` dates in selected", { + slices_path <- withr::local_file("slices.json") + + time_stamps <- Sys.Date() + c(-10 * 600, -30, 0) + + tss <- teal_slices( + teal_slice( + dataname = "ADSL", + varname = "EOSDT", + selected = time_stamps, + fixed = TRUE + ) + ) + + # Store the teal_slices object to a file + slices_store(tss, slices_path) + tss_restored <- slices_restore(slices_path) + + tss_restored_list <- shiny::isolate(shiny::reactiveValuesToList(tss_restored[[1]])) + testthat::expect_s3_class(tss_restored_list$selected, "Date") + + expect_identical_slice(tss[[1]], tss_restored[[1]]) +}) + +testthat::test_that("teal_slice store/restore supports saving `POSIXct` timestamps in choices", { + slices_path <- withr::local_file("slices.json") + + time_stamps <- Sys.time() + c(-10 * 60 * 60 * 24, -30, 0) + + # ISO8601 does not keep milliseconds + time_stamps <- as.POSIXct( + ceiling(as.double(time_stamps)), + tz = "UTC", + origin = "1970-01-01" + ) + + tss <- teal_slices( + teal_slice( + dataname = "ADSL", + varname = "EOSDTM", + selected = sample(time_stamps, 2), + choices = time_stamps, + fixed = TRUE + ) + ) + + # Store the teal_slices object to a file + slices_store(tss, slices_path) + tss_restored <- slices_restore(slices_path) + + tss_restored_list <- shiny::isolate(shiny::reactiveValuesToList(tss_restored[[1]])) + testthat::expect_s3_class(tss_restored_list$choices, "POSIXct") + + expect_identical_slice(tss[[1]], tss_restored[[1]]) +}) + +testthat::test_that("teal_slice store/restore supports saving `Date` timestamps in choices", { + slices_path <- withr::local_file("slices.json") + + time_stamps <- Sys.Date() + c(-10 * 600, -30, 0) + + tss <- teal_slices( + teal_slice( + dataname = "ADSL", + varname = "EOSDT", + selected = sample(time_stamps, 2), + choices = time_stamps, + fixed = TRUE + ) + ) + + # Store the teal_slices object to a file + slices_store(tss, slices_path) + tss_restored <- slices_restore(slices_path) + + tss_restored_list <- shiny::isolate(shiny::reactiveValuesToList(tss_restored[[1]])) + testthat::expect_s3_class(tss_restored_list$choices, "Date") + + expect_identical_slice(tss[[1]], tss_restored[[1]]) +}) + + +testthat::test_that("teal_slice store/restore restores mixed `Date`-characters as characters in selected", { + slices_path <- withr::local_file("slices.json") + tss <- teal_slices( + teal_slice( + dataname = "ADSL", + varname = "EOSDTM", + selected = c( + "beta 2023-09-11", + "release candidate 2023-09-21", + "release 2023-09-21" + ), + fixed = TRUE + ) + ) + + slices_store(tss, slices_path) + tss_restored <- slices_restore(slices_path) + expect_identical_slice(tss[[1]], tss_restored[[1]]) +}) + +testthat::test_that("teal_slice store/restore restores characters as characters in selected and choices", { + slices_path <- withr::local_file("slices.json") + tss <- teal_slices( + teal_slice( + dataname = "ADSL", + varname = "EOSDTM", + choices = c("a", "b", "c"), + selected = c("a", "b") + ) + ) + + slices_store(tss, slices_path) + tss_restored <- slices_restore(slices_path) + + testthat::expect_type(shiny::isolate(tss_restored[[1]]$selected), "character") + testthat::expect_type(shiny::isolate(tss_restored[[1]]$choices), "character") + expect_identical_slice(tss[[1]], tss_restored[[1]]) +}) diff --git a/tests/testthat/test-teal_slice.R b/tests/testthat/test-teal_slice.R index b0996b7b2..579319798 100644 --- a/tests/testthat/test-teal_slice.R +++ b/tests/testthat/test-teal_slice.R @@ -219,3 +219,21 @@ testthat::test_that("teal_slice dataname has to be a string when expr is specifi teal_slice(dataname = character(0), id = "x", title = "x", expr = "x == 'x'"), "length" ) }) + +testthat::test_that( + "teal_slice converts factors to characters for 'selected' and 'choices' parameters", + { + slices_path <- withr::local_file("slices.json") + tss <- teal_slices( + teal_slice( + dataname = "ADSL", + varname = "EOSDTM", + choices = factor(c("a", "b", "c")), + selected = factor(c("a", "b")) + ) + ) + + testthat::expect_type(shiny::isolate(tss[[1]]$selected), "character") + testthat::expect_type(shiny::isolate(tss[[1]]$choices), "character") + } +) From e7d899540e7efd559014d7d6820154d9acaf3ca3 Mon Sep 17 00:00:00 2001 From: m7pr Date: Wed, 18 Oct 2023 19:16:09 +0000 Subject: [PATCH 2/4] [skip actions] Bump version to 0.4.0.9017 --- .pre-commit-config.yaml | 2 +- DESCRIPTION | 4 ++-- NEWS.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1b8260f5d..4e2dde45a 100755 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,7 +6,7 @@ default_language_version: python: python3 repos: - repo: https://github.com/lorenzwalthert/precommit - rev: v0.3.2.9021 + rev: v0.3.2.9023 hooks: - id: style-files name: Style code with `styler` diff --git a/DESCRIPTION b/DESCRIPTION index 8d37bc6c6..6a97f9f3b 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Type: Package Package: teal.slice Title: Filter Module for 'teal' Applications -Version: 0.4.0.9016 -Date: 2023-10-12 +Version: 0.4.0.9017 +Date: 2023-10-18 Authors@R: c( person("Dawid", "Kaledkowski", , "dawid.kaledkowski@roche.com", role = c("aut", "cre")), person("Pawel", "Rucki", , "pawel.rucki@roche.com", role = "aut"), diff --git a/NEWS.md b/NEWS.md index 1442e64b3..eb150b85d 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,4 +1,4 @@ -# teal.slice 0.4.0.9016 +# teal.slice 0.4.0.9017 ### Miscellaneous From 2d2dad0ec1f0670cae626b1a1661031421e7f96b Mon Sep 17 00:00:00 2001 From: Aleksander Chlebowski <114988527+chlebowa@users.noreply.github.com> Date: Thu, 19 Oct 2023 10:46:46 +0200 Subject: [PATCH 3/4] 477 transfer slices store (#478) Closes #477 Removed functions `slices_store` and `slices_restore`. --------- Co-authored-by: m7pr --- NAMESPACE | 2 - NEWS.md | 1 + R/teal_slice-store.R | 83 -------------- R/teal_slice.R | 4 +- R/teal_slices.R | 2 +- _pkgdown.yml | 2 - man/slices_restore.Rd | 25 ---- man/slices_store.Rd | 43 ------- man/teal_slice.Rd | 4 +- man/teal_slices.Rd | 2 +- tests/testthat/test-teal_slice-store.R | 151 ------------------------- 11 files changed, 7 insertions(+), 312 deletions(-) delete mode 100644 R/teal_slice-store.R delete mode 100644 man/slices_restore.Rd delete mode 100644 man/slices_store.Rd delete mode 100644 tests/testthat/test-teal_slice-store.R diff --git a/NAMESPACE b/NAMESPACE index 082fe0b30..47a9a5d3b 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -46,8 +46,6 @@ export(is.teal_slices) export(list_to_teal_slices) export(remove_filter_state) export(set_filter_state) -export(slices_restore) -export(slices_store) export(teal_slice) export(teal_slices) import(R6) diff --git a/NEWS.md b/NEWS.md index eb150b85d..6f97328d4 100644 --- a/NEWS.md +++ b/NEWS.md @@ -3,6 +3,7 @@ ### Miscellaneous * Specified minimal version of package dependencies. +* Removed storing and restoring of `teal_slices` objects. # teal.slice 0.4.0 diff --git a/R/teal_slice-store.R b/R/teal_slice-store.R deleted file mode 100644 index 39faebc00..000000000 --- a/R/teal_slice-store.R +++ /dev/null @@ -1,83 +0,0 @@ -#' Store teal_slices object to a file -#' -#' This function takes a `teal_slices` object and saves it to a file in `JSON` format. -#' The `teal_slices` object contains information about filter states and can be used to -#' create, modify, and delete filter states. The saved file can be later loaded using -#' the `slices_restore` function. -#' -#' @param tss (`teal_slices`) object to be stored. -#' @param file (`character(1)`) The file path where `teal_slices` object will be saved. -#' The file extension should be `".json"`. -#' -#' @details `Date` classes is stored in `"ISO8601"` format (`YYYY-MM-DD`). `POSIX*t` classes are converted to a -#' character with the usage of `format.POSIX*t(usetz = TRUE, tz = "UTC")` (`YYYY-MM-DD {N}{N}:{N}{N}:{N}{N} UTC`, where -#' `{N} = [0-9]` is a number and `UTC` is `Coordinated Universal Time` timezone short-code). -#' This format is assumed during `slices_restore`. All `teal_slices` containing `teal_slice`s that have `selected` or -#' `choices` fields of `POSIX*t` class are always converted to `UTC` timezone during `print` and `format` as well. -#' -#' @return `NULL`, invisibly. -#' -#' @examples -#' # Create a teal_slices object -#' tss <- teal_slices( -#' teal_slice(dataname = "data", varname = "var"), -#' teal_slice(dataname = "data", expr = "x > 0", id = "positive_x", title = "Positive x") -#' ) -#' -#' if (interactive()) { -#' # Store the teal_slices object to a file -#' slices_store(tss, "path/to/file.json") -#' } -#' -#' @export -slices_store <- function(tss, file) { - checkmate::assert_class(tss, "teal_slices") - checkmate::assert_path_for_output(file, overwrite = TRUE, extension = "json") - - cat(format(tss, trim_lines = FALSE), "\n", file = file) -} - -#' Restore teal_slices object from a file -#' -#' This function takes a file path to a `JSON` file containing a `teal_slices` object -#' and restores it to its original form. The restored `teal_slices` object can be used -#' to access filter states and their corresponding attributes. -#' -#' @param file Path to file where `teal_slices` is stored. Must have a `.json` extension and read access. -#' -#' @return A `teal_slices` object restored from the file. -#' -#' @examples -#' if (interactive()) { -#' # Restore a teal_slices object from a file -#' tss_restored <- slices_restore("path/to/file.json") -#' } -#' @export -slices_restore <- function(file) { - checkmate::assert_file_exists(file, access = "r", extension = "json") - - tss_json <- jsonlite::fromJSON(file, simplifyDataFrame = FALSE) - tss_json$slices <- - lapply(tss_json$slices, function(slice) { - for (field in c("selected", "choices")) { - if (!is.null(slice[[field]])) { - date_partial_regex <- "^[0-9]{4}-[0-9]{2}-[0-9]{2}" - time_stamp_regex <- paste0(date_partial_regex, "\\s[0-9]{2}:[0-9]{2}:[0-9]{2}\\sUTC$") - - slice[[field]] <- - if (all(grepl(paste0(date_partial_regex, "$"), slice[[field]]))) { - as.Date(slice[[field]]) - } else if (all(grepl(time_stamp_regex, slice[[field]]))) { - as.POSIXct(slice[[field]], tz = "UTC") - } else { - slice[[field]] - } - } - } - slice - }) - - tss_elements <- lapply(tss_json$slices, as.teal_slice) - - do.call(teal_slices, c(tss_elements, tss_json$attributes)) -} diff --git a/R/teal_slice.R b/R/teal_slice.R index c24fef7f5..053ac1b9d 100644 --- a/R/teal_slice.R +++ b/R/teal_slice.R @@ -79,8 +79,8 @@ #' `teal_slice` also receives class `teal_slice_var` or `teal_slice_expr`, respectively. #' #' @note When `teal_slice` is printed and contains a `POSIX*t` class in `selected` or `choices` fields, then those -#' fields are converted to `UTC` timezone, for enhanced and unified storage and restoring with `slices_store()` and -#' `slices_restore()`. +#' fields are converted to `UTC` timezone, for enhanced and unified storage and restoring with `teal::slices_store()` +#' and `teal::slices_restore()`. #' #' @examples #' x1 <- teal_slice( diff --git a/R/teal_slices.R b/R/teal_slices.R index 9686ff79b..cfad12948 100644 --- a/R/teal_slices.R +++ b/R/teal_slices.R @@ -32,7 +32,7 @@ #' #' @note When `teal_slices` are printed and any of `teal_slice` elements contain a `POSIX*t` class in `selected` or #' `choices` fields, then those fields are converted to `UTC` timezone, for enhanced and unified storage and restoring -#' with `slices_store()` and `slices_restore()`. +#' with `teal::slices_store()` and `teal::slices_restore()`. #' #' @return #' `teal_slices`, which is an unnamed list of `teal_slice` objects. diff --git a/_pkgdown.yml b/_pkgdown.yml index 6bcf44357..b469c81de 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -32,8 +32,6 @@ reference: - clear_filter_states - teal_slice - teal_slices - - slices_store - - slices_restore - title: For Developers subtitle: R6 Classes desc: Abstract and concrete classes used to build teal functionality. diff --git a/man/slices_restore.Rd b/man/slices_restore.Rd deleted file mode 100644 index 34784b96e..000000000 --- a/man/slices_restore.Rd +++ /dev/null @@ -1,25 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/teal_slice-store.R -\name{slices_restore} -\alias{slices_restore} -\title{Restore teal_slices object from a file} -\usage{ -slices_restore(file) -} -\arguments{ -\item{file}{Path to file where \code{teal_slices} is stored. Must have a \code{.json} extension and read access.} -} -\value{ -A \code{teal_slices} object restored from the file. -} -\description{ -This function takes a file path to a \code{JSON} file containing a \code{teal_slices} object -and restores it to its original form. The restored \code{teal_slices} object can be used -to access filter states and their corresponding attributes. -} -\examples{ -if (interactive()) { - # Restore a teal_slices object from a file - tss_restored <- slices_restore("path/to/file.json") -} -} diff --git a/man/slices_store.Rd b/man/slices_store.Rd deleted file mode 100644 index 5722a4cb0..000000000 --- a/man/slices_store.Rd +++ /dev/null @@ -1,43 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/teal_slice-store.R -\name{slices_store} -\alias{slices_store} -\title{Store teal_slices object to a file} -\usage{ -slices_store(tss, file) -} -\arguments{ -\item{tss}{(\code{teal_slices}) object to be stored.} - -\item{file}{(\code{character(1)}) The file path where \code{teal_slices} object will be saved. -The file extension should be \code{".json"}.} -} -\value{ -\code{NULL}, invisibly. -} -\description{ -This function takes a \code{teal_slices} object and saves it to a file in \code{JSON} format. -The \code{teal_slices} object contains information about filter states and can be used to -create, modify, and delete filter states. The saved file can be later loaded using -the \code{slices_restore} function. -} -\details{ -\code{Date} classes is stored in \code{"ISO8601"} format (\code{YYYY-MM-DD}). \code{POSIX*t} classes are converted to a -character with the usage of \code{format.POSIX*t(usetz = TRUE, tz = "UTC")} (\verb{YYYY-MM-DD \{N\}\{N\}:\{N\}\{N\}:\{N\}\{N\} UTC}, where -\verb{\{N\} = [0-9]} is a number and \code{UTC} is \verb{Coordinated Universal Time} timezone short-code). -This format is assumed during \code{slices_restore}. All \code{teal_slices} containing \code{teal_slice}s that have \code{selected} or -\code{choices} fields of \code{POSIX*t} class are always converted to \code{UTC} timezone during \code{print} and \code{format} as well. -} -\examples{ -# Create a teal_slices object -tss <- teal_slices( - teal_slice(dataname = "data", varname = "var"), - teal_slice(dataname = "data", expr = "x > 0", id = "positive_x", title = "Positive x") -) - -if (interactive()) { - # Store the teal_slices object to a file - slices_store(tss, "path/to/file.json") -} - -} diff --git a/man/teal_slice.Rd b/man/teal_slice.Rd index b94c3ec0d..5de699169 100644 --- a/man/teal_slice.Rd +++ b/man/teal_slice.Rd @@ -123,8 +123,8 @@ A \code{FilterState} instantiated with \code{anchored = TRUE} cannot be removed. } \note{ When \code{teal_slice} is printed and contains a \code{POSIX*t} class in \code{selected} or \code{choices} fields, then those -fields are converted to \code{UTC} timezone, for enhanced and unified storage and restoring with \code{slices_store()} and -\code{slices_restore()}. +fields are converted to \code{UTC} timezone, for enhanced and unified storage and restoring with \code{teal::slices_store()} +and \code{teal::slices_restore()}. } \section{Filters in \code{SumarizedExperiment} and \code{MultiAssayExperiment} objects}{ diff --git a/man/teal_slices.Rd b/man/teal_slices.Rd index befc8e2c6..9658283b1 100644 --- a/man/teal_slices.Rd +++ b/man/teal_slices.Rd @@ -86,7 +86,7 @@ variables for one data set in one \code{teal_slices}. \note{ When \code{teal_slices} are printed and any of \code{teal_slice} elements contain a \code{POSIX*t} class in \code{selected} or \code{choices} fields, then those fields are converted to \code{UTC} timezone, for enhanced and unified storage and restoring -with \code{slices_store()} and \code{slices_restore()}. +with \code{teal::slices_store()} and \code{teal::slices_restore()}. } \examples{ filter_1 <- teal_slice( diff --git a/tests/testthat/test-teal_slice-store.R b/tests/testthat/test-teal_slice-store.R deleted file mode 100644 index 30e251130..000000000 --- a/tests/testthat/test-teal_slice-store.R +++ /dev/null @@ -1,151 +0,0 @@ -testthat::test_that("teal_slice store/restore supports saving `POSIXct` timestamps in selected", { - slices_path <- withr::local_file("slices.json") - - time_stamps <- Sys.time() + c(-10 * 60 * 60 * 24, -30, 0) - - # ISO8601 does not keep milliseconds - time_stamps <- as.POSIXct( - ceiling(as.double(time_stamps)), - tz = "UTC", - origin = "1970-01-01" - ) - - tss <- teal_slices( - teal_slice( - dataname = "ADSL", - varname = "EOSDTM", - selected = time_stamps, - fixed = TRUE - ) - ) - - # Store the teal_slices object to a file - slices_store(tss, slices_path) - tss_restored <- slices_restore(slices_path) - - tss_restored_list <- shiny::isolate(shiny::reactiveValuesToList(tss_restored[[1]])) - testthat::expect_s3_class(tss_restored_list$selected, "POSIXct") - - expect_identical_slice(tss[[1]], tss_restored[[1]]) -}) - -testthat::test_that("teal_slice store/restore supports saving `Date` dates in selected", { - slices_path <- withr::local_file("slices.json") - - time_stamps <- Sys.Date() + c(-10 * 600, -30, 0) - - tss <- teal_slices( - teal_slice( - dataname = "ADSL", - varname = "EOSDT", - selected = time_stamps, - fixed = TRUE - ) - ) - - # Store the teal_slices object to a file - slices_store(tss, slices_path) - tss_restored <- slices_restore(slices_path) - - tss_restored_list <- shiny::isolate(shiny::reactiveValuesToList(tss_restored[[1]])) - testthat::expect_s3_class(tss_restored_list$selected, "Date") - - expect_identical_slice(tss[[1]], tss_restored[[1]]) -}) - -testthat::test_that("teal_slice store/restore supports saving `POSIXct` timestamps in choices", { - slices_path <- withr::local_file("slices.json") - - time_stamps <- Sys.time() + c(-10 * 60 * 60 * 24, -30, 0) - - # ISO8601 does not keep milliseconds - time_stamps <- as.POSIXct( - ceiling(as.double(time_stamps)), - tz = "UTC", - origin = "1970-01-01" - ) - - tss <- teal_slices( - teal_slice( - dataname = "ADSL", - varname = "EOSDTM", - selected = sample(time_stamps, 2), - choices = time_stamps, - fixed = TRUE - ) - ) - - # Store the teal_slices object to a file - slices_store(tss, slices_path) - tss_restored <- slices_restore(slices_path) - - tss_restored_list <- shiny::isolate(shiny::reactiveValuesToList(tss_restored[[1]])) - testthat::expect_s3_class(tss_restored_list$choices, "POSIXct") - - expect_identical_slice(tss[[1]], tss_restored[[1]]) -}) - -testthat::test_that("teal_slice store/restore supports saving `Date` timestamps in choices", { - slices_path <- withr::local_file("slices.json") - - time_stamps <- Sys.Date() + c(-10 * 600, -30, 0) - - tss <- teal_slices( - teal_slice( - dataname = "ADSL", - varname = "EOSDT", - selected = sample(time_stamps, 2), - choices = time_stamps, - fixed = TRUE - ) - ) - - # Store the teal_slices object to a file - slices_store(tss, slices_path) - tss_restored <- slices_restore(slices_path) - - tss_restored_list <- shiny::isolate(shiny::reactiveValuesToList(tss_restored[[1]])) - testthat::expect_s3_class(tss_restored_list$choices, "Date") - - expect_identical_slice(tss[[1]], tss_restored[[1]]) -}) - - -testthat::test_that("teal_slice store/restore restores mixed `Date`-characters as characters in selected", { - slices_path <- withr::local_file("slices.json") - tss <- teal_slices( - teal_slice( - dataname = "ADSL", - varname = "EOSDTM", - selected = c( - "beta 2023-09-11", - "release candidate 2023-09-21", - "release 2023-09-21" - ), - fixed = TRUE - ) - ) - - slices_store(tss, slices_path) - tss_restored <- slices_restore(slices_path) - expect_identical_slice(tss[[1]], tss_restored[[1]]) -}) - -testthat::test_that("teal_slice store/restore restores characters as characters in selected and choices", { - slices_path <- withr::local_file("slices.json") - tss <- teal_slices( - teal_slice( - dataname = "ADSL", - varname = "EOSDTM", - choices = c("a", "b", "c"), - selected = c("a", "b") - ) - ) - - slices_store(tss, slices_path) - tss_restored <- slices_restore(slices_path) - - testthat::expect_type(shiny::isolate(tss_restored[[1]]$selected), "character") - testthat::expect_type(shiny::isolate(tss_restored[[1]]$choices), "character") - expect_identical_slice(tss[[1]], tss_restored[[1]]) -}) From be2b2e21f52837e0a27e689c74fd395d562a5ca8 Mon Sep 17 00:00:00 2001 From: chlebowa Date: Thu, 19 Oct 2023 08:48:00 +0000 Subject: [PATCH 4/4] [skip actions] Bump version to 0.4.0.9018 --- DESCRIPTION | 4 ++-- NEWS.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 6a97f9f3b..f692e0117 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Type: Package Package: teal.slice Title: Filter Module for 'teal' Applications -Version: 0.4.0.9017 -Date: 2023-10-18 +Version: 0.4.0.9018 +Date: 2023-10-19 Authors@R: c( person("Dawid", "Kaledkowski", , "dawid.kaledkowski@roche.com", role = c("aut", "cre")), person("Pawel", "Rucki", , "pawel.rucki@roche.com", role = "aut"), diff --git a/NEWS.md b/NEWS.md index 6f97328d4..80ae507f6 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,4 +1,4 @@ -# teal.slice 0.4.0.9017 +# teal.slice 0.4.0.9018 ### Miscellaneous