Saving state of Shiny app to be restored later

2020-08-26 11:23发布

问题:

I have a shiny application with many tabs and many widgets on each tab. It is a data-driven application so the data is tied to every tab.

I can save the application using image.save() and create a .RData file for later use.

The issue I am having how can I get the state restored for the widgets?

If the user has checked boxes, selected radio buttons and specified base line values in list boxes can I set those within a load() step?

I have found libraries such as shinyURL and shinystore but is there a direct way to set the environment back to when the write.image was done?

I am not sure where to even start so I can't post code.

edit: this is a cross-post from the Shiny Google Group where other solutions have been suggested

回答1:

This is a bit hacky, but it works. It uses an "internal" function (session$sendInputMessage) which is not meant to be called explicitly, so there is no guarantee this will always work.

You want to save all the values of the input object. I'm getting all the widgets using reactiveValuesToList(input) (note that this will also save the state of buttons, which doesn't entirely make sense). An alternative approach would be to enumerate exactly which widgets to save, but that solution would be less generic and you'd have to update it every time you add/remove an input. In the code below I simply save the values to a list called values, you can save that to file however you'd like (RDS/text file/whatever). Then the load button looks at that list and updates every input based on the value in the list.

There is a similar idea in this thread

library(shiny)

shinyApp(
  ui = fluidPage(
    textInput("text", "text", ""),
    selectInput("select", "select", 1:5),
    uiOutput("ui"),
    actionButton("save", "Save"),
    actionButton("load", "Load")
  ),

  server = function(input, output, session) {

    output$ui <- renderUI({
      tagList(
        numericInput("num", "num", 7),
        checkboxGroupInput("chk", "chk", 1:5, c(2,4))
      )
    })

    observeEvent(input$save, {
      values <<- lapply(reactiveValuesToList(input), unclass)
    })

    observeEvent(input$load, {
      if (exists("values")) {
       lapply(names(values),
              function(x) session$sendInputMessage(x, list(value = values[[x]]))
              )
      }
    })
  }
)


回答2:

Now with bookmarking is possible to save the state of your shinyapp. You have to put the bookmarkButton on your app and also the enableBookmarking.



回答3:

The above example may not work if shiny UI involves date. Here is a minor change for date handling.

library(shiny)

shinyApp(
  ui = fluidPage(
    dateInput("date", "date", "2012-01-01"),
    selectInput("select", "select", 1:5),
    uiOutput("ui"),
    actionButton("save", "Save"),
    actionButton("load", "Load")
  ),

  server = function(input, output, session) {

    output$ui <- renderUI({
      tagList(
        numericInput("num", "num", 7),
        checkboxGroupInput("chk", "chk", 1:5, c(2,4))
      )
    })

    observeEvent(input$save, {
      values <<- lapply(reactiveValuesToList(input), unclass)
    })

    observeEvent(input$load, {
      if (exists("values")) {
        lapply(names(values),
               function(x) session$sendInputMessage(x, list(value = values[[x]]))
        )
        temp=as.character(as.Date(values$date, origin = "1970-01-01"))
        updateDateInput(session, inputId="date", label ="date", value = temp)
      }
    })
  }
)


标签: r shiny