Export All User Inputs in a Shiny App to File and Load Them Later

Export all user inputs in a Shiny app to file and load them later

If you look at the code of the shiny input update functions, they end by session$sendInputMessage(inputId, message). message is a list of attributes that need to be changed in the input, for ex, for a checkbox input: message <- dropNulls(list(label = label, value = value))

Since most of the input have the value attribute, you can just use the session$sendInputMessage function directly on all of them without the try.

Here's an example, I created dummy_data to update all the inputs when you click on the button, the structure should be similar to what you export:

ui.R

library(shiny)
shinyUI(fluidPage(
textInput("control_label",
"This controls some of the labels:",
"LABEL TEXT"),
numericInput("inNumber", "Number input:",
min = 1, max = 20, value = 5, step = 0.5),
radioButtons("inRadio", "Radio buttons:",
c("label 1" = "option1",
"label 2" = "option2",
"label 3" = "option3")),
actionButton("update_data", "Update")

))

server.R

library(shiny)

dummy_data <- c("inRadio=option2","inNumber=10","control_label=Updated TEXT" )

shinyServer(function(input, output,session) {
observeEvent(input$update_data,{
out <- lapply(dummy_data, function(l) unlist(strsplit(l, "=")))
for (inpt in out) {
session$sendInputMessage(inpt[1], list(value=inpt[2]))
}
})

})

All the update functions also preformat the value before calling session$sendInputMessage. I haven't tried all possible inputs but at least for these 3 you can pass a string to the function to change the numericInput and it still works fine.

If this is an issue for some of your inputs, you might want to save reactiveValuesToList(input) using save, and when you want to update your inputs, use load and run the list in the for loop (you'll have to adapt it to a named list).

Export all user inputs in a Shiny app to file and load them later

If you look at the code of the shiny input update functions, they end by session$sendInputMessage(inputId, message). message is a list of attributes that need to be changed in the input, for ex, for a checkbox input: message <- dropNulls(list(label = label, value = value))

Since most of the input have the value attribute, you can just use the session$sendInputMessage function directly on all of them without the try.

Here's an example, I created dummy_data to update all the inputs when you click on the button, the structure should be similar to what you export:

ui.R

library(shiny)
shinyUI(fluidPage(
textInput("control_label",
"This controls some of the labels:",
"LABEL TEXT"),
numericInput("inNumber", "Number input:",
min = 1, max = 20, value = 5, step = 0.5),
radioButtons("inRadio", "Radio buttons:",
c("label 1" = "option1",
"label 2" = "option2",
"label 3" = "option3")),
actionButton("update_data", "Update")

))

server.R

library(shiny)

dummy_data <- c("inRadio=option2","inNumber=10","control_label=Updated TEXT" )

shinyServer(function(input, output,session) {
observeEvent(input$update_data,{
out <- lapply(dummy_data, function(l) unlist(strsplit(l, "=")))
for (inpt in out) {
session$sendInputMessage(inpt[1], list(value=inpt[2]))
}
})

})

All the update functions also preformat the value before calling session$sendInputMessage. I haven't tried all possible inputs but at least for these 3 you can pass a string to the function to change the numericInput and it still works fine.

If this is an issue for some of your inputs, you might want to save reactiveValuesToList(input) using save, and when you want to update your inputs, use load and run the list in the for loop (you'll have to adapt it to a named list).

R Shiny App that saves inputs for later use

library(shiny)  

ui <- shinyUI(fluidPage(

textInput(inputId = 'inputsLocation', label = 'Inputs Location', value = "~/Desktop/user_inputs.csv"),
actionButton('load_inputs', 'Load inputs'),
br(),
br(),
numericInput("n", "Number",min = 1, value = 5),
numericInput("upper", "Upper",min = 0, max = 100, value = 15),
numericInput("lower", "Lower",min = 0, max = 100, value = 5),
actionButton('save_inputs', 'Save inputs')

))

server <- shinyServer(function(input, output,session) {

observeEvent(input$load_inputs, {
# Load inputs
uploaded_inputs <- read.csv(input$inputsLocation)
# Update each input
for(i in 1:nrow(uploaded_inputs)){
updateNumericInput(session,
inputId = uploaded_inputs$inputId[i],
value = uploaded_inputs$value[i])
}
})

observeEvent(input$save_inputs, {
# Define inputs to save
inputs_to_save <- c('n', 'upper', 'lower')
# Declare inputs
inputs <- NULL
# Append all inputs before saving to folder
for(input.i in inputs_to_save){
inputs <- append(inputs, input[[input.i]])
}
# Inputs data.frame
inputs_data_frame <- data.frame(inputId = inputs_to_save, value = inputs)
# Save Inputs
write.csv(inputs_data_frame, file = input$inputsLocation, row.names = FALSE)
})

})

shinyApp(ui=ui,server=server)

The data "user_inputs.csv" looks like this:

"inputId","value"
"n",5
"upper",7
"lower",4

I added column names "inputId" and "value" so the code can be more explicit.

The code is altered from your original post. To use a .csv file requires a different way of loading/saving inputs. I think this way is a simple way to do that is relatively easy to follow.

Note* When manually typing in the file path input, the user needs to either use double slashes "\\" or backslashes "/" in the file path (same as in R).

Shiny: How to export table with both selectInput and manual input

This is only a partial answer, because I've removed the selectizeInput() to try and condense the code per your request to simplify. Editing of the table can be done directly in the table. Additionally, I added the buttons extension to directly download the table as a csv. Hopefully this is helpful.

library(shiny)
library(shinydashboard)
library(DT)

ui <- dashboardPage(
dashboardHeader(title = "test"),
dashboardSidebar(),
dashboardBody(h6("Table is editable"),
DT::DTOutput("fruit", width = "400px"))
)

server <- function(input, output, session) {
fruit_df <- reactiveValues("df" = data.frame(fruit_name = c("apple","cherry","pineapple","pear"),
fruit_lbs = c(2,5,6,3)) )

output$fruit <- DT::renderDT({
DT::datatable(fruit_df$df, editable = T,
extensions = 'Buttons', #Extra functions for the table
options = list("dom" = 'T<"clear">lBfrtip',
buttons = "csv"
)
)
})

}

shinyApp(ui, server)

Shiny - importing and exporting without user interaction by only specifying one file and its path

Perhaps something like this:

library(shiny)
library(tidyverse)

ui <- fluidPage(
textInput('file_name', 'Path to filename', value = "C:/Users/Users/Project/000-0000/000-0000_NewData.csv"),
numericInput('parameterNum', 'Insert Parameter Number',value = 3, min = 0),
actionButton(inputId = 'save', label = 'Write csvs')
)

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

observe({
setwd(dirname(input$file_name))
})

projectID <- reactive({
str_extract(inpt$file_name, "[^_]+")
})

prev_result1 <- reactive({
read_csv(str_c(projectID(), "_result1"))
#some calculation
})

prev_result2 <- reactive({
read_csv(str_c(projectID(), "_result2"))
#some calculation
})

observeEvent(input$save, {
write_csv(prev_result1(), str_c(projectID(), "_result1"))
write_csv(prev_result2(), str_c(projectID(), "_result2"))
})

}

shinyApp(ui, server)

Export user input and table out put to one Excel file with Shiny

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

dataReactive <- reactive({
data.frame(text = c(input$text1, input$text2, input$text3))

})
data <- reactiveValues()
observeEvent(input$goButton,{
output$exampleTable <- DT::renderDataTable({
data$df <- somefunction()
})
})
output$downloadExcelSheet <- downloadHandler(
filename = function() {
paste("result",Sys.Date(), ".xlsx",sep="")
},
content = function(file) {
write.xlsx(list(dataReactive(),data$df), file)
})
}

It's better to move data$df <- somefunction() to observeEvent and move DT::renderDataTable outside observeEvent like so

observeEvent(input$goButton,{
data$df <- somefunction()
})
output$exampleTable <- DT::renderDataTable({data$df})

Use reactiveValues as an intermediate state to save variables and in order to reuse them later.



Related Topics



Leave a reply



Submit