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