Skip to content

Commit

Permalink
edit vignette
Browse files Browse the repository at this point in the history
  • Loading branch information
Aleksander Chlebowski committed Nov 9, 2023
1 parent 507fbc3 commit 0f7accd
Showing 1 changed file with 35 additions and 14 deletions.
49 changes: 35 additions & 14 deletions vignettes/data-as-shiny-module.Rmd
Original file line number Diff line number Diff line change
@@ -1,31 +1,42 @@
---
title: "Data as shiny module"
title: "Data as shiny Module"
author: "NEST CoreDev"
output:
rmarkdown::html_vignette:
toc: true
vignette: >
%\VignetteIndexEntry{Data as shiny module}
%\VignetteIndexEntry{Data as shiny Module}
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8}
---

## Introduction

For the proper functioning of any `teal` application, the presence of a `teal_data` object is essential. Usually, application developers provide the `teal_data` object created within the `.GlobalEnv` environment as an argument for the `data` parameter. This `teal_data` object should encompass the required elements necessary for successful execution of the application's modules. In certain scenarios, application developers may opt to defer specific data operations by assigning a shiny module to the data parameter, allowing `teal` to execute the module every time a new session starts.
Proper functioning of any `teal` application requires presence of a `teal_data` object.
Typically, a `teal_data` object created in the global environment will be passed to the `data` argument in `init`.
This `teal_data` object should contain all elements necessary for successful execution of the application's modules.
In some scenarios, however, application developers may opt to postpone some data operations until the application run time.
This can be done by passing a special _`shiny` module_ to the `data` argument.
The `teal_data_module` function is used to build such a module from the following components:

## Postponed data creation
- a `ui` function; accepts only one argument, `id`; defines user interface elements for the data module
- a `server` function: accepts only one argument, `id`; defines server logic for the data module, including data creation; must return a reactive expression containing a `teal_data` object

In scenarios where certain data must be created anew each time a user opens the app, such as when the data is dynamic and frequently changing, loading the data once in the `.GlobalEnv` is not suitable. Instead, teal can generate the necessary objects each time a new session begins by specifying the `teal_data_module` using the following components:
`teal` will run this module when the application starts and the resulting `teal_data` object that will be used throughout all `teal` (analytic) modules.

- `ui` Function: This function should accept an `id` argument and define the user interface elements for the data module.
## Creating Data In-App

- `server` Function: Similarly, the server function should accept an `id` argument and define the server logic for the data module. `moduleServer` should return a reactive `teal_data` object, which will be used by the application to ensure the availability of up-to-date data upon each session start.
One case for postponing data operations are data sets that are dynamic, frequently updated.
Such data cannot be created once and kept in the global environment.
Using `teal_data_module` allows to create a data set from scratch every time the user starts the application.
This the user will always have access to the most recent version of the data.

```{r, message = FALSE, warning = FALSE}
library(teal)
```

By following these requirements, teal can efficiently handle dynamic data updates and create the necessary objects for a seamless user experience.

```{r}
library(teal)
data_mod <- teal_data_module(
ui = function(id) div(),
server = function(id) {
Expand Down Expand Up @@ -57,11 +68,12 @@ if (interactive()) {
```


## Postponed data modification
## Modification Data In-App

In certain scenarios, app developers may want to pre-create a `data` object before a `teal` session initializes, allowing app users to interact with this `data` from the session's start. This can be achieved by using the `teal_data_module` function to efficiently modify the existing data object.
Another reason to postpone data operations is to allow the application user to act the preprocessing stage.
An initial, constant form of the data can be created in the global environment and then modified once the app starts.

The following code snippet illustrates how teal_data_module can be utilized to subset the `dataset1` based on the selected `Species` from the `input$species` variable:
The following example illustrates how `teal_data_module` can be utilized to subset data based on the user inputs:

```{r}
data <- within(teal_data(), {
Expand All @@ -74,7 +86,8 @@ data_mod <- teal_data_module(
ui = function(id) {
ns <- NS(id)
div(
selectInput(ns("species"), "Select species to filter", choices = unique(iris$Species), multiple = TRUE),
selectInput(ns("species"), "Select species to filter",

Check warning on line 89 in vignettes/data-as-shiny-module.Rmd

View workflow job for this annotation

GitHub Actions / SuperLinter 🦸‍♀️ / Lint R code 🧶

file=vignettes/data-as-shiny-module.Rmd,line=89,col=61,[trailing_whitespace_linter] Trailing whitespace is superfluous.
choices = unique(iris$Species), multiple = TRUE),
actionButton(ns("submit"), "Submit")
)
},
Expand Down Expand Up @@ -102,4 +115,12 @@ if (interactive()) {
}
```

It's important to note that this approach reduces app loading time as `data` creation in the `.GlobalEnv` only involves data transformation. However, it's crucial to ensure that the initial server function is defined in the same environment as the data object to enable this functionality. This requirement ensures that data exists in the same environment as the calling environment of the `server` function, allowing for efficient data modification and interaction.
_See `?within.qenv` for a detailed explanation of how to use the `within` method._

Note that running preprocessing code in a module as opposed to the global environment will increase app loading times.
It is recommended to keep the constant code in the global environment and to move only the dynamic parts to a data module.

###### WARNING

When using `teal_data_moduel` to modify a pre-existing `teal_data` object it is crucial that the server function and the data object are defined in the same environment as otherwise the server function will not be able to access the data object.
This means server functions defined in packages cannot be used.

0 comments on commit 0f7accd

Please sign in to comment.