如果输入之前已经写入RDS文件,那么在闪亮的应用程序中本地恢复会话是可能的吗? [英] It is possible to restore a session, locally, in a Shiny app if the inputs have been previously written in a RDS file?
本文介绍了如果输入之前已经写入RDS文件,那么在闪亮的应用程序中本地恢复会话是可能的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我正在开发一个闪亮的应用程序,供本地使用。我正在尝试开发一个系统,使用户能够还原以前的会话。
为此,我从这个入口获取了代码:Saving state of Shiny app to be restored later,它确实起作用了,但是我希望能够还原不同会话中的输入,所以我向代码添加了fileInput(还原会话)和downloadButton(保存会话),但不幸的是我无法使其起作用。
我的代码如下:
library(shiny)
ui <- 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")),
fileInput("load_inputs", "Restore Session", multiple = FALSE),
downloadButton("save_inputs", 'Save Session')
)
server <- function(input, output,session) {
# SAVE SESSION
output$save_inputs <- downloadHandler(
filename = function() {
paste("session", ".RDS", sep = "")
},
content = function(file) {
saveRDS( reactiveValuesToList(input), file)
})
# LOAD SESSION
load_sesion <- reactive({
req(input$load_inputs)
load_session <- readRDS( input$load_inputs$datapath )
})
observeEvent(input$load_inputs,{
if(is.null(input$load_inputs)) {return(NULL)}
savedInputs <- load_sesion()
inputIDs <- names(savedInputs)
inputvalues <- unlist(savedInputs)
for (i in 1:length(inputvalues)) {
session$sendInputMessage(inputIDs[i], list(value=inputvalues[[i]]) )
}
})}
shinyApp(ui, server)
使用此代码,我可以保存会话的输入,并且可以在下一个会话中读取它们,但是我无法将存储在RDS上的那些值用作另一个会话中的输入。
非常感谢,
瑞秋
推荐答案
正如我在上面的评论中所建议的那样,以下应用程序使用SHINY的内置功能来创建书签,而不是使用自定义函数来保存输入的当前状态。
单击"下载"按钮后,书签将存储在服务器端,重命名并复制到downloadHandler。
如果用户上载书签文件,则会根据文件名创建所需的路径,并将用户重定向到较早的会话。(另请参阅注释掉的替代方案,它要求用户主动切换会话)。当然,您可以实现一个模式,让用户输入会话名称,以避免将相当隐晦的书签散列用作文件名。
编辑: 实现了允许用户提供自定义会话名称(限于字母数字字符)的模式
library(shiny)
library(shinyjs)
library(utils)
library(tools)
library(stringi)
ui <- function(request) {
fluidPage(
useShinyjs(),
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")),
fileInput("restore_bookmark", "Restore Session", multiple = FALSE, accept = ".rds"),
actionButton("save_inputs", 'Save Session', icon = icon("download"))
)
}
server <- function(input, output, session) {
latestBookmarkURL <- reactiveVal()
onBookmarked(
fun = function(url) {
latestBookmarkURL(parseQueryString(url))
}
)
onRestored(function(state) {
showNotification(paste("Restored session:", basename(state$dir)), duration = 10, type = "message")
})
observeEvent(input$save_inputs, {
showModal(modalDialog(
title = "Session Name",
textInput("session_name", "Please enter a session name (optional):"),
footer = tagList(
modalButton("Cancel"),
downloadButton("download_inputs", "OK")
)
))
}, ignoreInit = TRUE)
# SAVE SESSION
output$download_inputs <- downloadHandler(
filename = function() {
removeModal()
session$doBookmark()
if (input$session_name != "") {
tmp_session_name <- sub("\.rds$", "", input$session_name)
# "Error: Invalid state id" when using special characters - removing them:
tmp_session_name <- stri_replace_all(tmp_session_name, "", regex = "[^[:alnum:]]")
# TODO: check if a valid filename is provided (e.g. via library(shinyvalidate)) for better user feedback
tmp_session_name <- paste0(tmp_session_name, ".rds")
} else {
paste(req(latestBookmarkURL()), "rds", sep = ".")
}
},
content = function(file) {
file.copy(from = file.path(
".",
"shiny_bookmarks",
req(latestBookmarkURL()),
"input.rds"
),
to = file)
}
)
# LOAD SESSION
observeEvent(input$restore_bookmark, {
sessionName <- file_path_sans_ext(input$restore_bookmark$name)
targetPath <- file.path(".", "shiny_bookmarks", sessionName, "input.rds")
if (!dir.exists(dirname(targetPath))) {
dir.create(dirname(targetPath), recursive = TRUE)
}
file.copy(
from = input$restore_bookmark$datapath,
to = targetPath,
overwrite = TRUE
)
restoreURL <- paste0(session$clientData$url_protocol, "//", session$clientData$url_hostname, ":", session$clientData$url_port, session$clientData$url_pathname, "?_state_id_=", sessionName)
# redirect user to restoreURL
runjs(sprintf("window.location = '%s';", restoreURL))
# showModal instead of redirecting the user
# showModal(modalDialog(
# title = "Restore Session",
# "The session data was uploaded to the server. Please visit:",
# tags$a(restoreURL),
# "to restore the session"
# ))
})
}
shinyApp(ui, server, enableBookmarking = "server")
这篇关于如果输入之前已经写入RDS文件,那么在闪亮的应用程序中本地恢复会话是可能的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文