【发布时间】:2015-09-08 14:31:28
【问题描述】:
我的 Shiny 应用程序有几个输入,用于定义生成图的多个参数。用户很可能会花几分钟时间浏览所有可能的选项,直到他对输出感到满意为止。显然,绘图可以以不同的格式导出,但用户可能希望稍后使用不同的数据重新创建相同的绘图,或者只是更改一个小细节。
因此,我需要为用户提供一种方法来导出他的所有设置并保留该文件以供以后使用。我开发了一种方法,但效果不佳。我使用reactiveValuesToList 来获取所有输入元素的名称,并以inputname=inputvalue 的格式保存为一个简单的文本文件。这是server.R上的downloadHandler:
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)
})
这工作正常,但加载并不顺利。由于我不(也不知道如何)保存输入类型,我必须盲目地更新这些值。我就是这样做的:
importFile <- reactive({
inFile <- input$fileImport
if (is.null(inFile))
return(NULL)
lines <- readLines(inFile$datapath)
out <- lapply(lines, function(l) unlist(strsplit(l, "=")))
return(out)
})
observe({
imp <- importFile()
for (inpt in imp) {
if (substr(inpt[2], 0, 1) == "#") {
shinyjs::updateColourInput(session, inputId = inpt[1], value = inpt[2])
} else {
try({
updateTextInput(session, inputId = inpt[1], value = inpt[2])
updateNumericInput(session, inputId = inpt[1], value = inpt[2])
updateSelectInput(session, inputId = inpt[1], selected = inpt[2])
})
}
}
})
除了shinyjs::colorInput可以通过#开头识别,其他的我都得用try()。这部分可行,但某些输入未更新。手动检查导出的文件显示没有更新的输入在那里,所以我认为一次更新 100 多个输入不是一个好主意。此外,try() 部分看起来不太好,可能不是一个好主意。
应用程序即将完成,但将来可能会更新,添加/更改一些输入。如果这甚至使某些“旧”导出的输入无效,这是可以接受的,因为我将尝试保持向后兼容性。但我正在寻找一种方法,而不仅仅是编写数百行来逐一更新输入。
我曾考虑过使用save.image(),但仅使用load() 不会恢复应用输入。我还考虑了一种以某种方式一次更新所有输入的方法,而不是一个一个地更新,但没有想出任何东西。有没有更好的方法将所有用户输入导出到文件然后全部加载?不管是对这个效果更好的调整还是完全不同的方法。
【问题讨论】:
-
您的应用程序是否具有高度依赖的输入?是很多
renderUI块还是很多numericInput-esque 输入? -
@Mark 它们都是“静态”输入,没有一个是使用
renderUI创建的。 -
@Molx 如果您没有找到满意的解决方案,请与我联系。如果这里的解决方案之一有效,那就太好了:)(很高兴看到我的 colourInput 被使用了!)
-
@daattali 你不知道当我找到
colourInput时我有多高兴,没有它我的应用程序就不会那么有用。shinyjs::reset也很整洁。我不得不说,我刚刚发现这里的主要问题是shinyjs-resettable-settings也在被导出和加载,这使得输入值变得一团糟,因为它是一个充满"input = value"的列表。但现在已经解决了。 :) -
@Molx 我不完全理解正在发生的问题,您介意更详细地解释一下吗?如果我的代码有任何问题,我想知道,这样人们将来就不会遇到问题