Reputation: 195
In a Shiny app, is there a way to keep old reactive output and display it in the app along with new reactive output? To provide an example: say I want to display the summary table of a linear model to which I gradually add more variables. I currently have a checkboxGroupInput
panel using which I select the explanatory variables to be included in the model, and then I render a table which contains the summary of the model estimated using the selected variables. Now when I decide to use a different set of variables, I'd like to keep the original summary table displayed but also add the new summary table below the old one. If possible, I'd like to display all past instances of the reactive table, i.e., the number of tables displayed in the app should be equal to the number of different sets of explanatory variables I have decided to use throughout the app. At the moment, the table is rendered with htmlOutput
in the ui
part and stargazer
package and renderText
in the server
part.
Upvotes: 1
Views: 944
Reputation: 17359
Here's an approach that works. It uses a reactiveValues
object, and each time you click the "Fit Model" button, it appends the new model to the end of the list. The numeric input controls how many models to display on the screen. This preserves every model you fit in the session.
I didn't do the stargazer
table because I'm not that familiar with it. But you should be able to adapt this pretty easily.
library(shiny)
library(broom)
shinyApp(
ui =
shinyUI(
fluidPage(
sidebarLayout(
sidebarPanel(
checkboxGroupInput(inputId = "indep",
label = "Independent Variables",
choices = names(mtcars)[-1],
selected = NULL),
actionButton(inputId = "fit_model",
label = "Fit Model"),
numericInput(inputId = "model_to_show",
label = "Show N most recent models",
value = 2)
),
mainPanel(
htmlOutput("model_record")
)
)
)
),
server =
shinyServer(function(input, output, session){
Model <- reactiveValues(
Record = list()
)
observeEvent(
input[["fit_model"]],
{
fit <-
lm(mpg ~ .,
data = mtcars[c("mpg", input[["indep"]])])
Model$Record <- c(Model$Record, list(fit))
}
)
output$model_record <-
renderText({
tail(Model$Record, input[["model_to_show"]]) %>%
lapply(tidy) %>%
lapply(knitr::kable,
format = "html") %>%
lapply(as.character) %>%
unlist() %>%
paste0(collapse = "<br/><br/>")
})
})
)
Upvotes: 2