R 将闪亮应用程序中的所有用户输入导出到文件,并在以后加载

R 将闪亮应用程序中的所有用户输入导出到文件,并在以后加载,r,shiny,R,Shiny,我的闪亮应用程序有几个输入,用于定义生成绘图的几个参数。用户很可能会花几分钟的时间浏览所有可能的选项,直到对输出感到满意为止。很明显,绘图可以以不同的格式导出,但用户可能希望稍后使用不同的数据重新创建相同的绘图,或者可能只是更改一个小细节 因此,我需要为用户提供一种方法来导出其所有设置,并保留该文件以供以后使用。我已经开发了一种方法,但效果不好。我正在使用reactiveValuesToList获取所有输入元素的名称,并以inputname=inputvalue格式保存为一个简单的文本文件。这是

我的闪亮应用程序有几个输入,用于定义生成绘图的几个参数。用户很可能会花几分钟的时间浏览所有可能的选项,直到对输出感到满意为止。很明显,绘图可以以不同的格式导出,但用户可能希望稍后使用不同的数据重新创建相同的绘图,或者可能只是更改一个小细节

因此,我需要为用户提供一种方法来导出其所有设置,并保留该文件以供以后使用。我已经开发了一种方法,但效果不好。我正在使用
reactiveValuesToList
获取所有输入元素的名称,并以
inputname=inputvalue
格式保存为一个简单的文本文件。这是
服务器上的
下载处理程序。R

output$bt_export <- downloadHandler(
  filename = function() {
    "export.txt"
  },
  content = function(file) {
    inputsList <- names(reactiveValuesToList(input))
    exportVars <- paste0(inputsList, "=", sapply(inputsList, function(inpt) input[[inpt]]))
    write(exportVars, file)
  })

output$bt_export除非您正在执行大量高度灵活的类型输入(
renderUI
块,可以是任何类型的输入),否则您可以创建一个存储所有当前值的列表,使用
dput
将它们保存到一个文件中,并使用相应的
dget
进行读取

在我的一个应用程序中,我允许用户下载一个文件,其中存储了所有上传的数据和所有选项

output$saveData <- downloadHandler(
  filename = function() { 
    paste0('Export_',Sys.Date(),'.sprout')
  },
  content = function(file) {
    dataToExport = list()
    #User specified options
    dataToExport$sproutData$transformations=sproutData$transformations  #user specified transformations
    dataToExport$sproutData$processing=sproutData$processing  #user specified text processing rules
    dataToExport$sproutData$sc=sproutData$sc  #user specified option to spell check
    dataToExport$sproutData$scOptions=sproutData$scOptions  #user specified spell check options (only used if spell check is turned on)
    dataToExport$sproutData$scLength=sproutData$scLength  #user specified min word lenght for spell check (only used if spell check is turned on)
    dataToExport$sproutData$stopwords=sproutData$stopwords  #user specified stopwords
    dataToExport$sproutData$stopwordsLastChoice=sproutData$stopwordsLastChoice #last pre-built list selected
    dput(dataToExport,file=file)
  }
)

实际输出是一个表,详细说明它发现了什么和设置了什么。但是,因为我知道所有输入,并且它们不会更改,所以我可以显式地存储它们(默认值或更改的值),然后在上载保存文件时显式地更新它们。

如果查看闪亮的输入更新函数的代码,它们以
会话$sendInputMessage(inputId,message)
结束<代码>消息
是需要在输入中更改的属性列表,例如,对于复选框输入:
消息这有点旧,但我认为可以发布一个完整的示例,保存和加载用户输入

library(shiny)  

ui <- 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("load_inputs", "Load inputs"), 
  actionButton('save_inputs', 'Save inputs')

)) 

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

  observeEvent(input$load_inputs,{   

    if(!file.exists('inputs.RDS')) {return(NULL)}

    savedInputs <- readRDS('inputs.RDS')

    inputIDs      <- names(savedInputs) 
    inputvalues   <- unlist(savedInputs) 
    for (i in 1:length(savedInputs)) { 
      session$sendInputMessage(inputIDs[i],  list(value=inputvalues[[i]]) )
    }
  })

  observeEvent(input$save_inputs,{ 
    saveRDS( reactiveValuesToList(input) , file = 'inputs.RDS')
  })  
})
库(闪亮)

ui您的应用程序是否具有高度依赖的输入?是大量的
renderUI
块还是大量的
numericInput
-esque输入?@标记它们都是“静态”输入,没有一个是使用
renderUI
@Molx创建的。如果您找不到满意的解决方案,请与我联系。如果这里有一个解决方案有效,那就太好了:)(很高兴看到我的colorInput被使用!)@daattali你不知道当我找到
colorInput
时我有多高兴,没有它我的应用程序就不会那么有用了<代码>shinyjs::reset
也非常整洁。我不得不说,我刚刚发现这里的主要问题是,
shinyjs resetable settings
也被导出和加载,这对输入值造成了混乱,因为它是一个充满
“input=value”
的列表。但现在问题解决了。:)@Molx我不完全理解正在发生的问题,你介意更详细地解释一下吗?如果我的代码有什么问题,我想知道,这样人们就不会在将来遇到问题。我也考虑过“手动”更新每个代码,但这会增加太多行(目前为117行),这将很难维护。这个应用程序几乎完成了,但我想说它是alpha版本的,可能会被修改,可能会收到更多的输入,可能会改变其中的一些。虽然这是一个相当简单的更改,但是删除丑陋的
try()
和良好的知识非常有用。最终,它帮助我找到了该方法的最大问题,即导出了一些不希望的和意外的反应值,并对加载函数进行了注入攻击。在出现空值(例如使用复选框时)之前,该方法工作良好。加载输入时,
unlist
命令无法输入任何具有空值的内容,这会导致下标错误,因为
inputvalues
的长度小于
savesinput
的长度。
output$loadStatusIndicator = renderUI({
  worked = T
  a = tryCatch(dget(input$loadSavedData$datapath),error=function(x){worked<<-F})
  if(worked){
    #User specified options
    a$sproutData$transformations->sproutData$transformations  #user specified transformations
    a$sproutData$processing->sproutData$processing  #user specified text processing rules
    updateCheckboxGroupInput(session,"processingOptions",selected=sproutData$processing)
    a$sproutData$sc->sproutData$sc  #user specified option to spell check
    updateCheckboxInput(session,"spellCheck",value = sproutData$sc)
    a$sproutData$scOptions->sproutData$scOptions  #user specified spell check options (only used if spell check is turned on)
    updateCheckboxGroupInput(session,"spellCheckOptions",selected=sproutData$scOptions)
    a$sproutData$scLength->sproutData$scLength  #user specified min word lenght for spell check (only used if spell check is turned on)
    updateNumericInput(session,"spellCheckMinLength",value=sproutData$scLength)
    a$sproutData$stopwords->sproutData$stopwords  #user specified stopwords
    a$sproutData$stopwordsLastChoice->sproutData$stopwordsLastChoice
    if(sproutData$stopwordsLastChoice[1] == ""){
      updateSelectInput(session,"stopwordsChoice",selected="none")
    } else if(all(sproutData$stopwordsLastChoice == stopwords('en'))){
      updateSelectInput(session,"stopwordsChoice",selected="en")
    } else if(all(sproutData$stopwordsLastChoice == stopwords('SMART'))){
      updateSelectInput(session,"stopwordsChoice",selected="SMART")
    }
    HTML("<strong>Loaded data!</strong>")
  } else if (!is.null(input$loadSavedData$datapath)) {
    HTML(paste("<strong>Not a valid save file</strong>"))
  }
})
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")

  ))
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]))
    }
   })

})
library(shiny)  

ui <- 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("load_inputs", "Load inputs"), 
  actionButton('save_inputs', 'Save inputs')

)) 

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

  observeEvent(input$load_inputs,{   

    if(!file.exists('inputs.RDS')) {return(NULL)}

    savedInputs <- readRDS('inputs.RDS')

    inputIDs      <- names(savedInputs) 
    inputvalues   <- unlist(savedInputs) 
    for (i in 1:length(savedInputs)) { 
      session$sendInputMessage(inputIDs[i],  list(value=inputvalues[[i]]) )
    }
  })

  observeEvent(input$save_inputs,{ 
    saveRDS( reactiveValuesToList(input) , file = 'inputs.RDS')
  })  
})