I have a working shiny module that allows the user to input certain parameters then run a forecasting model which then returns a single dataframe to the main app.
I'm trying to setup the app to allow the user to launch as many of these modules as they want to model several different 'scenarios' and then be able to compare the results of each.
I'm trying to achieve this by dynamically launching each scenario module using insertTab
inside an observer that looks out for a button click and then store the data the module produces inside a reactiveValues
list. I then plan to combine all the data returned and chart the differences of each scenario the user has run.
Relevant code:
rv <- reactiveValues()
observeEvent(input$add_scenario, {
num <- as.numeric(input$add_scenario)
id <- paste0("s", num)
label <- paste("Scenario", num)
insertTab(
inputId = "tabs",
target = paste("Scenario", num - 1),
position = "after",
tabPanel(label, model_UI(id)),
select = FALSE
)
rv[[id]] <- callModule(model, id)
})
The data from the module is passed back as a reactive reactive({ module_output() })
but this value will initially be NULL
until the user inputs their parameters and hits 'run' on an actionButton
inside the module.
I'm having difficulty trying to access the data returned to the reactiveValues
list. I want to bind_rows()
on the items in rv
that are not NULL
i.e. data returned from any modules where the user has run a model.
The module adds a unique identifier column to indicate which scenario the data came from so if I bind_rows()
on all non NULL
data I can then chart the differences by grouping by scenario.
If anyone has a solution to this or can suggest a better method I'd be very appreciative!
Thanks.
EDIT purrr
to the rescue.
It looks like the following code does the trick of combining the non-NULL
items in the reactiveValues
list into a single df:
scenario_outputs <- reactive({
so <- reactiveValuesToList(rv)
map_df(so, ~ .x())
})