1
votes

Please run the app and would request to put something in the respective inputs. Then please save the object. You would find a .Rdata file saved in your working directory. Here is my problem which I am unable to figure out.

In the below application can shiny input (e.g. input$name, input$age, input$location etc) read the values saved in .Rdata?

I can save the inputs in a .Rdata file in my working directory. However when I load the file back is there any way I can replace the input boxes with the values stored in .Rdata file, otherwise there is no point in saving them right? This is a desktop app which we would run locally. So it is important to save the user inputs at each point. However the challenge when we load the .Rdata file which has previously selected inputs, we are unable to replace the shiny inputs with those values. Hence I have to make those selections again from shiny input. Thus the saved file is of no use.

library(shiny)
library(pryr)

ui <- function(request){
  fluidPage(
    titlePanel("Put title of the application"),
    sidebarLayout(
      sidebarPanel(
        textInput("name", "Type your name", ""),
        textInput("age", "Type your age", ""),
        radioButtons("gender", "Select your gender", list("Male", "Female"), ""),
        sliderInput("height", "Select your height", min =  5.0, max = 8.0, value = 5.2, step = 0.1),
        selectInput("location", "Select your location", choices = c("","Gurgaon", "Bangalore", "Mumbai")),
        actionButton("save_objs", "Save Objects"),
        actionButton("load_objs", "Load Objects"),
        bookmarkButton()
      ),

      mainPanel(
        textOutput("username"),
        textOutput("userage"),
        textOutput("usergender"),
        textOutput("userheight"),
        textOutput("userlocation"),
        textOutput("userload")
      )
    )
  )
}


server <- function(input, output, session) {
vals <- reactiveValues(name = NULL)
  output$username <- renderText(input$name)
  output$userage <- renderText(input$age)
  output$usergender <- renderText(input$gender)
  output$userheight <- renderText(input$height)
  output$userlocation <- renderText(input$location)

  observeEvent(input$save_objs, {
    # Run whenever save_objs button is pressed

    print("** saving objects! **")

    ## Print the objects being saved
    print(rls())
    # ## Put  objects into current environment
    for(obj in unlist(rls())) {
      if(class(get(obj, pos =  -1))[1] == "reactive"){
        ## execute the reactive objects and put them in to this 
        ## environment i.e. into the environment of this function
        assign(obj, value = eval(call(obj)))
      } else {
        ## grab the global variables and put them into this 
        ## environment
        assign(obj, value = get(obj, pos =  -1))
      }
    }

    input_copy <- list()
    for(nm in names(input)){
      # assign(paste0("input_copy$", nm), value <- input[[nm]])
      input_copy[[nm]] <- input[[nm]]
    }

    ## save objects in current environment
    save(list = ls(), file = "shiny_env.Rdata", envir = environment())

    print("** done saving     **")
  })


        observeEvent(input$load_objs, {
    # Run whenever load_objs button is pressed
    ## Load the objects
    f.loaddata <- function()
    {
      myenv <- new.env()
      load(file = file.choose(), envir = myenv)
      myenv
    }

    print("** About to load objects! **")
    # ## Put  objects into current environment
    some <- f.loaddata()
    #print(some$input_copy$name)
    vals$name <- some$input_copy$name
    vals$name <- input$name
    print("** done loading     **")
  })



}

shinyApp(ui, server, enableBookmarking = "server")
1
Because the variable in loaded RData file will be in the global environment, and shiny input is not global variable.Jim Chen
Thanks @JimChen, Is there any way this objective can be achieved at all or is it something working in a black box? What do you suggest? I have been trying to get some suggestion on this. How can users save their selected inputs, files in a project and then access them back to continue working? An example would really help me from this grave.ARIMITRA MAITI
@JimChen Need your help in some guidance please. Based on your suggestion I did add vals <- and edited the vals$name. When I save the .Rdata the name input is saved in some$input_copy$name. But when I assign this to global vals$name I cannot see the vaue in UI (name). I am not able to correct this.ARIMITRA MAITI
I update your code in the answer, see if this is what you want.Jim Chen

1 Answers

1
votes

You can use reactiveValues to store your input$*** and save the reactiveValues object into RData.

If you want to load the RData file, just read it and names it as same as your reactiveValues variable names.

You can see this shiny app, it save people chatting log into RDS file (similar as RData file). That is how it work in server.R :

vars <- reactiveValues(chat=NULL, users=NULL)

# Restore the chat log from the last session.

if (file.exists("chat.Rds")){
  vars$chat <- readRDS("chat.Rds")
} else {
  vars$chat <- "Welcome to Shiny Chat!"
}

Your code

I make an example only on input$name and input$age.

library(shiny)
library(pryr)

ui <- function(request){
  fluidPage(
    titlePanel("Put title of the application"),
    sidebarLayout(
      sidebarPanel(
        textInput("name", "Type your name", ""),
        textInput("age", "Type your age", ""),
        radioButtons("gender", "Select your gender", list("Male", "Female"), ""),
        sliderInput("height", "Select your height", min =  5.0, max = 8.0, value = 5.2, step = 0.1),
        selectInput("location", "Select your location", choices = c("","Gurgaon", "Bangalore", "Mumbai")),
        actionButton("save_objs", "Save Objects"),
        actionButton("load_objs", "Load Objects"),
        bookmarkButton()
      ),

      mainPanel(
        textOutput("username"),
        textOutput("userage"),
        textOutput("usergender"),
        textOutput("userheight"),
        textOutput("userlocation"),
        textOutput("userload")
      )
    )
  )
}


server <- function(input, output, session) {
  vals <- reactiveValues()

  output$username <- renderText(input$name)
  output$userage <- renderText(input$age)
  output$usergender <- renderText(input$gender)
  output$userheight <- renderText(input$height)
  output$userlocation <- renderText(input$location)

  isolate({
    vals$name=input$name
    vals$age=input$age
  })

  observeEvent(c(vals$name,vals$age),{
    updateTextInput(session,"name",label="Type your name",value=vals$name)
    updateTextInput(session,"age",label="Type your age",value=vals$name)
  })

  observeEvent(input$save_objs, {
    # Run whenever save_objs button is pressed
    vals$username<-input$name
    vals$userage<-input$age
    vals$usergender<-input$gender
    vals$userheight<-input$height
    vals$userlocation<-input$location
    print("** saving objects! **")

    ## Print the objects being saved
    print(rls())
    # ## Put  objects into current environment
    for(obj in unlist(rls())) {
      if(class(get(obj, pos =  -1))[1] == "reactive"){
        ## execute the reactive objects and put them in to this 
        ## environment i.e. into the environment of this function
        assign(obj, value = eval(call(obj)))
      } else {
        ## grab the global variables and put them into this 
        ## environment
        assign(obj, value = get(obj, pos =  -1))
      }
    }

    input_copy <- list()
    for(nm in names(input)){
      # assign(paste0("input_copy$", nm), value <- input[[nm]])
      input_copy[[nm]] <- input[[nm]]
    }

    ## save objects in current environment
    save(list = ls(), file = "shiny_env.Rdata", envir = environment())

    print("** done saving     **")
  })


  observeEvent(input$load_objs, {
    # Run whenever load_objs button is pressed
    ## Load the objects
    f.loaddata <- function()
    {
      myenv <- new.env()
      load(file = file.choose(), envir = myenv)
      myenv
    }

    print("** About to load objects! **")
    # ## Put  objects into current environment
    some <- f.loaddata()
    #print(some$input_copy$name)
    vals$name <- some$input_copy$name
    vals$age <- some$input_copy$age
    # vals$name <- input$name
    print("** done loading     **")
  })

}

shinyApp(ui, server, enableBookmarking = "server")