Data extract
NEST coreDev
2022-05-03
data-extract.Rmd
There are times when an app developer wants to showcase more than
just one fixed slice of their dataset in their custom module.
Relinquishing control of the application to a user demands the developer
gives their users a degree of freedom. In case of analyzing data,
teal
allows app developers to open up their applications to
users, letting them decide exactly what app data to analyze in the
module.
A lot of teal
modules use data_extract_spec
objects and modules to tackle user input. You can find many examples in
e.g. teal.modules.general
and
teal.modules.clinical
.
data_extract_spec
data_extract_spec
’s task is two-fold: create a UI
component in a shiny
application and pass the user input
from the UI to the module itself. Having that formulated, let’s have a
look at how it supports both its responsibilities.
Example module
In order to showcase different initialization options of
data_extract_spec
, first we define a shiny
module which uses data_extract_ui
and
data_extract_srv
designed to handle
data_extract_spec
objects. The module creates a UI
component for a single data_extract_spec
and prints a list
of values returned from data_extract_srv
module. Please see
package documentation for more information about
data_extract_ui
and data_extract_srv
.
library(teal.transform)
#> Loading required package: magrittr
library(shiny)
extract_ui <- function(id, data_extract) {
ns <- NS(id)
teal.widgets::standard_layout(
output = teal.widgets::white_small_well(verbatimTextOutput(ns("output"))),
encoding = data_extract_ui(ns("data_extract"), label = "variable", data_extract)
)
}
extract_srv <- function(id, datasets, data_extract, join_keys) {
moduleServer(id, function(input, output, session) {
reactive_extract_input <- data_extract_srv("data_extract", datasets, data_extract, join_keys)
s <- reactive({
format_data_extract(reactive_extract_input())
})
output$output <- renderPrint({
cat(s())
})
})
}
Example data
data_extract_srv
module depends on either a list of
reactive or non-reactive data.frame
objects. Here, we show
the usage of a list of data.frame
objects as input to
datasets
where a list of necessary join keys per
data.frame
object is required:
# Define data.frame objects
ADSL <- scda::synthetic_cdisc_data("latest")$adsl # nolint
ADTTE <- scda::synthetic_cdisc_data("latest")$adtte # nolint
# create a list of data.frame objects
datasets <- list(ADSL = ADSL, ADTTE = ADTTE)
# create join_keys
join_keys <- teal.data::join_keys(
teal.data::join_key("ADSL", "ADSL", c("STUDYID", "USUBJID")),
teal.data::join_key("ADSL", "ADTTE", c("STUDYID", "USUBJID")),
teal.data::join_key("ADTTE", "ADTTE", c("STUDYID", "USUBJID", "PARAMCD"))
)
Consider the following example, where we create two UI elements, one
to filter on a specific level from SEX
variable, and a
second one to select a variable from c("BMRKR1", "AGE")
.
data_extract_spec
object is handed over to the shiny app
and gives instructions to generate UI components.
simple_des <- data_extract_spec(
dataname = "ADSL",
filter = filter_spec(vars = "SEX", choices = c("F", "M")),
select = select_spec(choices = c("BMRKR1", "AGE"))
)