Search code examples
rshinylocal-storagerhandsontableshinystoreplus

How to save reactive dataframe from one R session to the next?


I've begun working with package shinyStorePlus to save user inputs from one R session to the next. I've come across a scenario where it doesn't work: a reactive dataframe rendered with package rhandsontable, per the example code below. Using rhandsontable the user can add columns with click of a mouse, and manually edit column data like an XLS. Can shinyStorePlus work with this more complicated inputs mechanism, where the table/dataframe is saved from one session to the next? Are there better solutions without using shinyStorePlus? Using rhandsontable is a must.

Again, the idea is that the totality of user inputs, in generating the table or dataframe, is saved from one R session to the next. I will later incorporate action buttons to clear/reset the dataframe back to its default settings.

Example code:

library(rhandsontable)
library(shiny)
library(shinyStorePlus)

myDF <- data.frame(x = c(1, 2, 3))

ui <- fluidPage(
  initStore(), # added to enable shinyStorePlus
  br(),fluidRow(column(6,actionButton('addCol','Add'))),br(),
  rHandsontableOutput('hottable')
)

server <- function(input, output, session) {
  
  ### added the following to enable session-to-session saving with shinyStorePlus:
  appid <- "application002" 
  setupStorage(
    appId = appid,
    inputs = TRUE
  )
  ####
  
  EmptyTbl <- reactiveVal(myDF)
  
  observeEvent(input$hottable, {
    EmptyTbl(hot_to_r(input$hottable))
  })
  
  output$hottable <- renderRHandsontable({
    rhandsontable(EmptyTbl(),useTypes = FALSE)
  })
  
  observeEvent(input$addCol, {
    newCol <- data.frame(c(1, 2, 3))
    names(newCol) <- paste("Col", ncol(hot_to_r(input$hottable)) + 1)
    EmptyTbl(cbind(EmptyTbl(), newCol))
  })
  
}

shinyApp(ui, server)

Solution added: based on ismirsehregal's and rguru12's inputs, here is ismirsehregal's generous solution posted in question How to implement shinyStore when using a table generated by the rhandsontable R package? where we switch from shinyStorePlus to shinyStore package in order to get this done:

# If not installed already, un-comment and run the below 3 lines to install shinyStore package:
# install.packages("devtools")
# library(devtools)
# install_github("trestletech/shinyStore")

library(rhandsontable)
library(shiny)
library(shinyStore)

myDF <- data.frame(x = c(1, 2, 3))

ui <- fluidPage(
  initStore("store", "shinyStore-ex1"),
  br(),
  fluidRow(column(
    6,
    actionButton('addCol', 'Add column'),
    actionButton("save", "Save", icon("save")),
    actionButton("clear", "Clear", icon("stop")) # add
  )),
  br(),
  rHandsontableOutput('hottable')
)

server <- function(input, output, session) {
  uiTable <- reactiveVal(myDF)
  
  output$hottable <- renderRHandsontable({
    rhandsontable(uiTable(), useTypes = FALSE)
  })
  
  observeEvent(input$hottable, {
    uiTable(hot_to_r(input$hottable))
  })
  
  observeEvent(input$addCol, {
    newCol <- data.frame(c(1, 2, 3))
    names(newCol) <-
      paste("Col", ncol(hot_to_r(input$hottable)) + 1)
    uiTable(cbind(uiTable(), newCol))
  })
  
  observeEvent(input$save, {
    updateStore(session, name = "uiTable", uiTable())
  }, ignoreInit = TRUE)
  
  observeEvent(input$clear, {
    # clear tracking table:
    uiTable(myDF)
    
    # clear shinyStore:
    updateStore(session, name = "uiTable", myDF)
  }, ignoreInit = TRUE)
  
  observeEvent(input$store$uiTable, {
    uiTable(as.data.frame(input$store$uiTable))
  })
}

shinyApp(ui, server)

Solution

  • it appears that the current version of shinyStorePlus R package only tracks Shiny inputs and not outputs