Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

904 teal_data in teal_module #924

Merged
merged 50 commits into from
Nov 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
b6daace
ddl
gogonzo Aug 14, 2023
c3527ff
ddl to teal.data
gogonzo Aug 15, 2023
885a5f2
Merge remote-tracking branch 'origin/main' into refactor
gogonzo Aug 15, 2023
2e66246
fix
gogonzo Aug 15, 2023
e54a865
fix
gogonzo Aug 16, 2023
ef7e7f6
Merge remote-tracking branch 'origin/main' into refactor
gogonzo Sep 4, 2023
8d01b4e
Merge branch 'main' into refactor
donyunardi Sep 20, 2023
275117a
add functions to switch between tdata classes
Sep 25, 2023
ebd834d
upgrade tdata object in module_nested_tabs
Sep 25, 2023
5ae64d7
modify .datasets_to_data)
Sep 25, 2023
15156fe
format code in .tdata_downgrade
Sep 25, 2023
b5ef5d5
improve .tdata_upgrade
Sep 26, 2023
f89e0e1
roll back formatting code in .tdata_downgrade
Sep 26, 2023
2fecd12
add unit tests
Sep 26, 2023
58dd3f0
ddl alternative (#922)
chlebowa Sep 29, 2023
c3adcbf
Merge remote-tracking branch 'origin/main' into refactor
gogonzo Sep 29, 2023
b1de788
data is teal_data
gogonzo Oct 2, 2023
9082b5d
restore trigger_data
Oct 2, 2023
4981bb6
Merge branch 'refactor' into 904_tdata_in_modules@refactor
Oct 2, 2023
7953148
adapt to new teal_data class
Oct 2, 2023
6216e5c
update argument checks
Oct 2, 2023
06801ea
update unit tests
Oct 2, 2023
5444ce7
remove trigger_data from .datasets_to_data
Oct 3, 2023
c1b2ba8
Merge branch 'main' into 904_tdata_in_modules@refactor
Nov 20, 2023
7d371d3
amend docs
Nov 20, 2023
5cf1549
Merge 7d371d3b81c9d03718587674718ae2cbb9d3ae08 into d4bab67906e124a9c…
chlebowa Nov 20, 2023
82d40b6
[skip actions] Restyle files
github-actions[bot] Nov 20, 2023
39a8db4
Merge branch 'main' into 904_tdata_in_modules@refactor
Nov 20, 2023
fc8c690
changes post teal_data refactor
Nov 20, 2023
1146f0d
handle reactive expressions in upgrade/downgrade
Nov 20, 2023
8ae9eee
Merge branch 'main' into 904_tdata_in_modules@refactor
Nov 20, 2023
b7b6b3a
fix example_module, remove deprecated `teal_data()` calls
gogonzo Nov 20, 2023
797da16
make changes to example_module
Nov 20, 2023
8dc9516
add isolate and subsetting data in .datasets_to_data
Nov 20, 2023
67f28c0
fix .tdata_upgrade
Nov 20, 2023
b0844c1
fix unit tests
Nov 20, 2023
c5cd680
Merge branch '904_tdata_in_modules@refactor' of github.com:insightsen…
Nov 20, 2023
1b1eda4
Merge c5cd680d432d04c4e14803c67c915b49cb68e57b into 50bbab6d74a1a0e80…
chlebowa Nov 20, 2023
7678f8a
[skip actions] Restyle files
github-actions[bot] Nov 20, 2023
179d410
post-merge clean up
Nov 21, 2023
429720a
remove isolations
Nov 21, 2023
a29c33c
downgrade
gogonzo Nov 21, 2023
a085f88
rename ans export as_tdata
Nov 21, 2023
6b6ad10
update pkgdown
Nov 21, 2023
e1b2915
adjust example_module
Nov 21, 2023
da41a68
fix unit tests
Nov 21, 2023
f18f116
fix docs
Nov 21, 2023
959eddd
amend NEWS
Nov 21, 2023
d3d4a37
fix docs
Nov 21, 2023
a1c199b
fix version in NEWS
Nov 21, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ S3method(ui_nested_tabs,teal_modules)
export("%>%")
export(TealReportCard)
export(as.teal_slices)
export(as_tdata)
export(example_module)
export(get_code_tdata)
export(get_metadata)
Expand Down
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* `data` argument in `init` now accepts `teal_data` and `teal_data_module`.
* Added `landing_popup_module` function which creates a module that will display a popup when the app starts. The popup will block access to the app until it is dismissed.
* Filter state snapshots can now be uploaded from file. See `?snapshot`.
* Added `as_tdata` function to facilitate migration of modules to the new `teal_data` class.

### Miscellaneous

Expand Down
12 changes: 6 additions & 6 deletions R/dummy_functions.R
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ example_datasets <- function() { # nolint
#' @examples
#' app <- init(
#' data = teal_data(
#' dataset("IRIS", iris),
#' dataset("MTCARS", mtcars)
#' IRIS = iris,
#' MTCARS = mtcars
#' ),
#' modules = example_module()
#' )
Expand All @@ -93,12 +93,12 @@ example_module <- function(label = "example teal module", datanames = "all") {
module(
label,
server = function(id, data) {
checkmate::assert_class(data, "tdata")
checkmate::assert_class(data(), "teal_data")
moduleServer(id, function(input, output, session) {
output$text <- renderPrint(data[[input$dataname]]())
output$text <- renderPrint(data()[[input$dataname]])
teal.widgets::verbatim_popup_srv(
id = "rcode",
verbatim_content = attr(data, "code")(),
verbatim_content = reactive(teal.code::get_code(data())),
title = "Association Plot"
)
})
Expand All @@ -108,7 +108,7 @@ example_module <- function(label = "example teal module", datanames = "all") {
teal.widgets::standard_layout(
output = verbatimTextOutput(ns("text")),
encoding = div(
selectInput(ns("dataname"), "Choose a dataset", choices = names(data)),
selectInput(ns("dataname"), "Choose a dataset", choices = teal.data::datanames(data)),
teal.widgets::verbatim_popup_ui(ns("rcode"), "Show R code")
)
)
Expand Down
9 changes: 3 additions & 6 deletions R/init.R
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,10 @@
#' @include modules.R
#'
#' @examples
#' new_iris <- transform(iris, id = seq_len(nrow(iris)))
#' new_mtcars <- transform(mtcars, id = seq_len(nrow(mtcars)))
#'
#' app <- init(
#' data = teal_data(
#' dataset("new_iris", new_iris),
#' dataset("new_mtcars", new_mtcars),
#' new_iris = transform(iris, id = seq_len(nrow(iris))),
#' new_mtcars = transform(mtcars, id = seq_len(nrow(mtcars))),
#' code = "
#' new_iris <- transform(iris, id = seq_len(nrow(iris)))
#' new_mtcars <- transform(mtcars, id = seq_len(nrow(mtcars)))
Expand All @@ -78,7 +75,7 @@
#' "Iris Sepal.Length histogram",
#' server = function(input, output, session, data) {
#' output$hist <- renderPlot(
#' hist(data[["new_iris"]]()$Sepal.Length)
#' hist(data()[["new_iris"]]$Sepal.Length)
#' )
#' },
#' ui = function(id, ...) {
Expand Down
46 changes: 15 additions & 31 deletions R/module_nested_tabs.R
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ srv_nested_tabs.teal_module <- function(id, datasets, modules, is_module_specifi
}

if (is_arg_used(modules$server, "data")) {
data <- .datasets_to_data(modules, datasets, trigger_data)
data <- eventReactive(trigger_data(), .datasets_to_data(modules, datasets))
args <- c(args, data = list(data))
}

Expand Down Expand Up @@ -285,17 +285,12 @@ srv_nested_tabs.teal_module <- function(id, datasets, modules, is_module_specifi
#'
#' @param module (`teal_module`) module where needed filters are taken from
#' @param datasets (`FilteredData`) object where needed data are taken from
#' @param trigger_data (`reactiveVal`) to trigger getting the filtered data
#' @return list of reactive datasets with following attributes:
#' - `code` (`character`) containing datasets reproducible code.
#' - `join_keys` (`join_keys`) containing relationships between datasets.
#' - `metadata` (`list`) containing metadata of datasets.
#' @return A `tdata` object.
#'
#' @keywords internal
.datasets_to_data <- function(module, datasets, trigger_data = reactiveVal(1L)) {
.datasets_to_data <- function(module, datasets) {
checkmate::assert_class(module, "teal_module")
checkmate::assert_class(datasets, "FilteredData")
checkmate::assert_class(trigger_data, "reactiveVal")

datanames <- if (is.null(module$datanames) || identical(module$datanames, "all")) {
datasets$datanames()
Expand All @@ -304,31 +299,20 @@ srv_nested_tabs.teal_module <- function(id, datasets, modules, is_module_specifi
}

# list of reactive filtered data
data <- sapply(
datanames,
function(x) eventReactive(trigger_data(), datasets$get_data(x, filtered = TRUE)),
simplify = FALSE
)
data <- sapply(datanames, function(x) datasets$get_data(x, filtered = TRUE), simplify = FALSE)

hashes <- calculate_hashes(datanames, datasets)
metadata <- lapply(datanames, datasets$get_metadata)
names(metadata) <- datanames

new_tdata(
data,
eventReactive(
trigger_data(),
{
c(
get_rcode_str_install(),
get_rcode_libraries(),
get_datasets_code(datanames, datasets, hashes),
teal.slice::get_filter_expr(datasets, datanames)
)
}
),
datasets$get_join_keys(),
metadata

code <- c(
get_rcode_str_install(),
get_rcode_libraries(),
get_datasets_code(datanames, datasets, hashes),
teal.slice::get_filter_expr(datasets, datanames)
)

do.call(
teal.data::teal_data,
args = c(data, code = list(code), join_keys = list(datasets$get_join_keys()[datanames]))
)
}

Expand Down
1 change: 0 additions & 1 deletion R/module_teal_with_splash.R
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ ui_teal_with_splash <- function(id,
# We use delayed loading in all cases, even when the data does not need to be fetched.
# This has the benefit that when filtering the data takes a lot of time initially, the
# Shiny app does not time out.

splash_ui <- if (inherits(data, "teal_data_module")) {
data$ui(ns("teal_data_module"))
} else if (inherits(data, "teal_data")) {
Expand Down
4 changes: 2 additions & 2 deletions R/modules.R
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
#' library(shiny)
#'
#' app <- init(
#' data = teal_data(dataset("iris", iris)),
#' data = teal_data(iris = iris),
#' modules = modules(
#' label = "Modules",
#' modules(
Expand Down Expand Up @@ -199,7 +199,7 @@ is_arg_used <- function(modules, arg) {
#' library(shiny)
#'
#' app <- init(
#' data = teal_data(dataset("iris", iris)),
#' data = teal_data(iris = iris),
#' modules = list(
#' module(
#' label = "Module",
Expand Down
48 changes: 48 additions & 0 deletions R/tdata.R
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
#' @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
#'
#' @seealso `as_tdata`
#'
#' @examples
#'
#' data <- new_tdata(
Expand Down Expand Up @@ -157,3 +160,48 @@ get_metadata.tdata <- function(data, dataname) {
get_metadata.default <- function(data, dataname) {
stop("get_metadata function not implemented for this object")
}


#' Downgrade `teal_data` objects in modules for compatibility.
#'
#' Convert `teal_data` to `tdata` in `teal` modules.
#'
#' Recent changes in `teal` cause modules to fail because modules expect a `tdata` object
#' to be passed to the `data` argument but instead they receive a `teal_data` object,
#' which is additionally wrapped in a reactive expression in the server functions.
#' In order to easily adapt such modules without a proper refactor,
#' use this function to downgrade the `data` argument.
#'
#' @param x data object, either `tdata` or `teal_data`, the latter possibly in a reactive expression
#'
#' @return Object of class `tdata`.
#'
#' @examples
#' td <- teal_data()
#' td <- within(td, iris <- iris) %>% within(mtcars <- mtcars)
#' td
#' as_tdata(td)
#' as_tdata(reactive(td))
#'
#' @export
#' @rdname tdata_deprecation
#'
as_tdata <- function(x) {
if (inherits(x, "tdata")) {
return(x)
}
if (is.reactive(x)) {
checkmate::assert_class(isolate(x()), "teal_data")
datanames <- isolate(teal.data::datanames(x()))
datasets <- sapply(datanames, function(dataname) reactive(x()[[dataname]]), simplify = FALSE)
code <- reactive(teal.code::get_code(x()))
join_keys <- isolate(teal.data::join_keys(x()))
} else if (inherits(x, "teal_data")) {
datanames <- teal.data::datanames(x)
datasets <- sapply(datanames, function(dataname) reactive(x[[dataname]]), simplify = FALSE)
code <- reactive(teal.code::get_code(x))
join_keys <- isolate(teal.data::join_keys(x))
}

new_tdata(data = datasets, code = code, join_keys = join_keys)
}
1 change: 1 addition & 0 deletions _pkgdown.yml
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ reference:
- landing_popup_module
- title: Functions for Module Developers
contents:
- as_tdata
- tdata
- get_code_tdata
- get_metadata
Expand Down
11 changes: 2 additions & 9 deletions man/dot-datasets_to_data.Rd

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

4 changes: 2 additions & 2 deletions man/example_module.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/init.Rd

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

2 changes: 1 addition & 1 deletion man/module.Rd

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

2 changes: 1 addition & 1 deletion man/modules.Rd

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

3 changes: 3 additions & 0 deletions man/tdata.Rd

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

32 changes: 32 additions & 0 deletions man/tdata_deprecation.Rd

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

Loading