1

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.

Skumin
  • 153
  • 8
  • Could you append or r/cbind the new table to the old table,and create an additional variable in the table indicating which model the output came from? You could, theoretically, have a bunch of UI datatables hidden if NULL, when a new table is generated, change the current table to one of the NULL tables, such that now it will show up. But you'd have to manually code the shifting of tables as new are generated and would only be able to have as many old results show up as you manually code into the UI, so it wouldn't go on forever. I like the first solution more. – Andrew Taylor Jan 11 '17 at 18:34

1 Answers1

2

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/>")
        })

    })
)
Benjamin
  • 16,897
  • 6
  • 45
  • 65