Skumin
Skumin

Reputation: 195

R Shiny: keep old output

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

Answers (1)

Benjamin
Benjamin

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

Related Questions