Skip to content

Commit

Permalink
rename qenv (#733)
Browse files Browse the repository at this point in the history
  • Loading branch information
Nikolas Burkoff authored Sep 22, 2022
1 parent 671804f commit 0a5bbe0
Show file tree
Hide file tree
Showing 14 changed files with 262 additions and 35 deletions.
1 change: 1 addition & 0 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ Collate:
'modules_debugging.R'
'reporter_previewer_module.R'
'show_rcode_modal.R'
'tdata.R'
'teal.R'
'utils.R'
'validations.R'
Expand Down
9 changes: 9 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Generated by roxygen2: do not edit by hand

S3method(get_code,tdata)
S3method(get_join_keys,default)
S3method(get_join_keys,tdata)
S3method(get_metadata,default)
S3method(get_metadata,tdata)
S3method(is_arg_used,"function")
S3method(is_arg_used,default)
S3method(is_arg_used,teal_module)
Expand All @@ -20,17 +25,21 @@ export(.log)
export(bookmarkableShinyApp)
export(default_filter)
export(example_module)
export(get_join_keys)
export(get_metadata)
export(get_rcode)
export(get_rcode_srv)
export(get_rcode_ui)
export(init)
export(log_app_usage)
export(module)
export(modules)
export(new_tdata)
export(reporter_previewer_module)
export(root_modules)
export(show_rcode_modal)
export(srv_teal_with_splash)
export(tdata2env)
export(ui_teal_with_splash)
export(validate_has_data)
export(validate_has_elements)
Expand Down
2 changes: 1 addition & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
### Enhancements

* Added option to choose which variables can be filtered in the filter panel by using the `filterable` attributes for the per-dataset lists in the `filter` argument of `init`.
* `teal_module` having `data` argument in its arguments will receive a list of reactive filter data with `"code"` and `"join_keys"` attributes.
* `teal_module` having `data` argument in its arguments of type `tdata`. Modules receive this object (a list of reactive filtered datasets with `"code"` and `"join_keys"` attributes).
* Updated the internals of `module_teal` to reflect changes in `teal.slice`.
* `teal_module` having `filter_panel_api` argument in its arguments will receive a `FilterPanelAPI` object.

Expand Down
1 change: 1 addition & 0 deletions R/example_module.R
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ example_module <- function(label = "example teal module") {
module(
label,
server = function(id, data) {
checkmate::assert_class(data, "tdata")
moduleServer(id, function(input, output, session) {
output$text <- renderPrint(data[[input$dataname]]())
})
Expand Down
17 changes: 10 additions & 7 deletions R/module_nested_tabs.R
Original file line number Diff line number Diff line change
Expand Up @@ -228,9 +228,9 @@ srv_nested_tabs.teal_module <- function(id, datasets, modules, reporter) {
reactive(modules)
}

#' Convert `FilteredData` to reactive list of data
#' Convert `FilteredData` to reactive list of datasets of the `tdata` type.
#'
#' Converts `FilteredData` object to list of data containing datasets needed for specific module.
#' Converts `FilteredData` object to `tdata` object containing datasets needed for a specific module.
#' Please note that if module needs dataset which has a parent, then parent will be also returned.
#'
#' @param module (`teal_module`) module where needed filters are taken from
Expand All @@ -255,10 +255,13 @@ srv_nested_tabs.teal_module <- function(id, datasets, modules, reporter) {
}
)

# code from previous stages
attr(data, "code") <- get_datasets_code(datanames, datasets)
metadata <- lapply(datanames, datasets$get_metadata)
names(metadata) <- datanames

# join_keys
attr(data, "join_keys") <- datasets$get_join_keys()
data
new_tdata(
data,
reactive(get_datasets_code(datanames, datasets)),
datasets$get_join_keys(),
metadata
)
}
18 changes: 8 additions & 10 deletions R/modules_debugging.R
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
#' and avoids session restarts!
#'
#' @param label `character` label of module
#' @param active_datanames `character vector` datanames shown in filter panel;
#' can be `"all"` to mean all available datasets
#' @keywords internal
#'
#' @examples
Expand All @@ -34,19 +32,19 @@
#' ),
#' header = "Simple teal app"
#' )
#' \dontrun{
#' shinyApp(app$ui, app$server)
#' if (interactive()) {
#' shinyApp(app$ui, app$server)
#' }
filter_calls_module <- function(label = "Filter Calls Module", active_datanames = "all") { # nolint
filter_calls_module <- function(label = "Filter Calls Module") { # nolint
checkmate::assert_string(label)
checkmate::check_character(active_datanames, min.len = 1, any.missing = FALSE)

module(
label = label,
server = function(input, output, session, datasets) {
server = function(input, output, session, data) {
checkmate::assert_class(data, "tdata")

output$filter_calls <- renderText({
active_datanames <- datasets$handle_active_datanames(active_datanames)
teal.slice::get_filter_expr(datasets, datanames = active_datanames)
get_code(data)
})
},
ui = function(id, ...) {
Expand All @@ -56,6 +54,6 @@ filter_calls_module <- function(label = "Filter Calls Module", active_datanames
verbatimTextOutput(ns("filter_calls"))
)
},
filters = active_datanames
filters = "all"
)
}
131 changes: 131 additions & 0 deletions R/tdata.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
#' Create a new `tdata` object which contains
#'
#' - `data` a `reactive` list of data.frames (or `MultiAssayExperiment`) with attributes
#' i) `code` (`reactive`) containing code used to generate the data
#' and ii) join_keys (`JoinKeys`) containing the relationships between
#' the data iii) metadata (`named list`) containing any metadata associated with
#' the data frames
#'
#' @param data A `named list` of `data.frames` (or `MultiAssayExperiment`)
#' which optionally can be `reactive`.
#' Inside this object all of these items will be made `reactive`.
#' @param code A `character` (or `reactive` which evaluates to a `character`) containing
#' the code used to generate the data. This should be `reactive` if the code is changing
#' during a reactive context (e.g. if filtering changes the code). Inside this
#' object `code` will be made reactive
#' @param join_keys A `teal.data::JoinKeys` object containing relationships between the
#' datasets.
#' @param metadata A `named list` each element contains a list of metadata about the named data.frame
#' Each element of these list should be atomic and length one.
#' @return A `tdata` object
#' @examples
#'
#' data <- new_tdata(
#' data = list(iris = iris, mtcars = reactive(mtcars), dd = data.frame(x = 1:10)),
#' code = "iris <- iris
#' mtcars <- mtcars
#' dd <- data.frame(x = 1:10)",
#' metadata = list(dd = list(author = "NEST"), iris = list(version = 1))
#' )
#'
#' # Extract a data.frame
#' isolate(data[["iris"]]())
#'
#' @export
new_tdata <- function(data, code = "", join_keys = NULL, metadata = NULL) {
checkmate::assert_list(
data,
any.missing = FALSE, names = "unique",
types = c("data.frame", "reactive", "MultiAssayExperiment")
)
checkmate::assert_class(join_keys, "JoinKeys", null.ok = TRUE)
checkmate::assert_multi_class(code, c("character", "reactive"))

checkmate::assert_list(metadata, names = "unique", null.ok = TRUE)
checkmate::assert_subset(names(metadata), names(data))
for (m in metadata) teal.data::validate_metadata(m)

if (is.reactive(code)) {
isolate(checkmate::assert_class(code(), "character"))
}

#create reactive data.frames
for (x in names(data)) {
if (!is.reactive(data[[x]])) {
data[[x]] <- do.call(reactive, list(as.name(x)), envir = list2env(data[x]))
} else {
isolate(checkmate::assert_multi_class(data[[x]](), c("data.frame", "MultiAssayExperiment")))
}
}

# set attributes
attr(data, "code") <- if (is.reactive(code)) code else reactive(code)
attr(data, "join_keys") <- join_keys
attr(data, "metadata") <- metadata

# set class
class(data) <- c("tdata", class(data))
data
}

#' Function to convert a `tdata` object to an `environment`
#' Any `reactives` inside `tdata` are first evaluated
#' @param `data` a `tdata` object
#' @return an `environment`
#' @examples
#'
#' data <- new_tdata(
#' data = list(iris = iris, mtcars = reactive(mtcars)),
#' code = "iris <- iris
#' mtcars = mtcars"
#' )
#'
#' my_env <- isolate(tdata2env(data))
#'
#' @export
tdata2env <- function(data) { # nolint
checkmate::assert_class(data, "tdata")
list2env(lapply(data, function(x) if (is.reactive(x)) x() else x))
}

#' @export
get_code.tdata <- function(data) {
# note teal.data which teal depends on defines the get_code method
attr(data, "code")()
}

#' @export
get_join_keys <- function(data) {
UseMethod("get_join_keys", data)
}


#' @export
get_join_keys.tdata <- function(data) {
attr(data, "join_keys")
}

#' @export
get_join_keys.default <- function(data) {
stop("get_join_keys function not implemented for this object")
}

#' @export
get_metadata <- function(data, dataname) {
checkmate::assert_string(dataname)
UseMethod("get_metadata", data)
}

#' @export
get_metadata.tdata <- function(data, dataname) {
metadata <- attr(data, "metadata")
if (is.null(metadata)) {
return(NULL)
}
metadata[[dataname]]
}

#' @export
get_metadata.default <- function(data, dataname) {
stop("get_metadata function not implemented for this object")
}
4 changes: 2 additions & 2 deletions man/dot-datasets_to_data.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 3 additions & 6 deletions man/filter_calls_module.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

50 changes: 50 additions & 0 deletions man/new_tdata.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 30 additions & 0 deletions man/tdata2env.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion tests/testthat/test-module_nested_tabs.R
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ testthat::test_that(".datasets_to_data returns required attributes", {

# code
testthat::expect_equal(
attr(data, "code")[1],
isolate(attr(data, "code")()[1]),
"d1 <- data.frame(id = 1:5, pk = c(2, 3, 2, 1, 4), val = 1:5)\nd2 <- data.frame(id = 1:5, value = 1:5)\n\n"
)
})
Expand Down
Loading

0 comments on commit 0a5bbe0

Please sign in to comment.