teal
teal copied to clipboard
round 2 - transform in a teal_module's ui/srv
Simplest solution
teal_modulepassesteal_transform_moduleto theuiandsrvthroughui_argsandserver_args.- In ui and server of
teal_module"transformers" are executed byui/srv_teal_data_moduleanddatais modified
See the code below and transformers argument, then see example_module to see how the settings are utilized.
options(teal.log_level = "TRACE", teal.show_js_log = TRUE)
pkgload::load_all("teal")
library(teal.modules.general)
library(dplyr)
options(shiny.bookmarkStore = "server")
nest_logo <- "https://raw.githubusercontent.com/insightsengineering/hex-stickers/main/PNG/nest.png"
datasets <- c("IRIS", "MTCARS", "CO2", "AIRMILES", "TITANIC", "ADSL", "ADRS", "ADTTE", "ADLB", "ADQS")
data <- teal.data::teal_data() |> within({
IRIS <- iris
MTCARS <- mtcars
CO2 <- CO2
AIRMILES <- airmiles
TITANIC <- Titanic
ADSL <- teal.modules.general::rADSL %>%
mutate(TRTDUR = round(as.numeric(TRTEDTM - TRTSDTM), 1))
ADRS <- teal.modules.general::rADRS
ADTTE <- teal.modules.general::rADTTE
ADLB <- teal.modules.general::rADLB %>%
mutate(CHGC = as.factor(case_when(
CHG < 1 ~ "N",
CHG > 1 ~ "P",
TRUE ~ "-"
)))
ADQS <- teal.modules.clinical::tmc_ex_adqs %>%
dplyr::filter(ABLFL != "Y" & ABLFL2 != "Y") %>%
dplyr::mutate(
AVISIT = as.factor(AVISIT),
AVISITN = rank(AVISITN) %>%
as.factor() %>%
as.numeric() %>%
as.factor(),
AVALBIN = AVAL < 50 # Just as an example to get a binary endpoint.
) %>%
droplevels()
})
teal.data::datanames(data) <- datasets
teal.data::join_keys(data) <- teal.data::default_cdisc_join_keys[datanames(data)]
data
transform_iris_ui <- function(id) {
ns <- NS(id)
bslib::card(
bslib::card_body(
selectInput(
ns("species"),
"Select iris species",
choices = c("setosa", "versicolor", "virginica"),
selected = c("setosa", "versicolor", "virginica"),
multiple = TRUE
)
)
)
}
transform_iris_srv <- function(id, data) {
moduleServer(id, function(input, output, session) {
reactive({
message("Filtering iris data")
data() |> within(
IRIS <- dplyr::filter(IRIS, Species %in% species),
species = input$species
)
})
})
}
transform_adrs_ui <- function(id) {
ns <- NS(id)
bslib::card(
bslib::card_body(
selectInput(
ns("paramcd"),
"Select Parameter",
choices = c("BESRPSI", "INVET", "OVRINV"),
selected = "OVRINV",
multiple = TRUE
),
selectInput(
ns("avisit"),
"Select a visit",
choices = c(
"SCREENING", "BASELINE", "CYCLE 2 DAY 1", "CYCLE 4 DAY 1",
"END OF INDUCTION", "FOLLOW UP"
),
selected = "SCREENING",
multiple = TRUE
)
)
)
}
transform_adrs_srv <- function(id, data) {
moduleServer(id, function(input, output, session) {
reactive({
message("Filtering adrs data")
data() |> within(
ADRS <- dplyr::filter(ADRS, PARAMCD %in% paramcd, AVISIT %in% avisit),
paramcd = input$paramcd,
avisit = input$avisit
)
})
})
}
transform_adtte_ui <- function(id) {
ns <- NS(id)
bslib::card(
bslib::card_body(
selectInput(
ns("paramcd"),
"Select Parameter",
choices = c("CRSD", "EFS", "OS", "PFS", "TNE"),
selected = "OS",
multiple = TRUE
)
)
)
}
transform_adtte_srv <- function(id, data) {
moduleServer(id, function(input, output, session) {
reactive({
message("Filtering adtte data")
data() |> within(
ADTTE <- dplyr::filter(ADTTE, PARAMCD %in% paramcd),
paramcd = input$paramcd
)
})
})
}
app <- init(
data = data,
filter = teal_slices(
teal_slice(dataname = "IRIS", varname = "Species", multiple = FALSE)
),
modules = modules(
example_module(
label = "transform by arg",
datanames = "all",
transformers = list(
teal_transform_module(
ui = transform_iris_ui,
server = transform_iris_srv,
label = "transform iris"
),
teal_transform_module(
ui = transform_adrs_ui,
server = transform_adrs_srv,
label = "transform adrs"
),
teal_transform_module(
ui = transform_adtte_ui,
server = transform_adtte_srv,
label = "transform adtte"
)
)
)
)
)
shinyApp(app$ui, app$server)
Spent some time today reviewing https://github.com/insightsengineering/teal/pull/1209 and I found this approach a lot easier and handier than what we've seen so far. Just a quick reply. Will come up with something bigger
As I wrote in here https://github.com/insightsengineering/teal/pull/1209#issuecomment-2100147645, with this PR we are very flexible and can allow the whole module to be changed/transformed - not only the data