使用 Shiny 应用程序保存数据时出现问题
Problem when using Shiny app to save the data
我有一个闪亮的应用程序,它有很多文本输入。我无法正确保存数据部分,例如,无法保存到本地驱动器。有什么建议么?
server = function(input, output) {
values <- reactiveValues()
#Initial Dataframe
values$df <- data.frame(matrix(ncol=4,nrow=0, dimnames=list(NULL, c("Name", "date","Traning", "certificate"))))
FinalData =observe({
if(input$submit >0) {
isolate(values$df <- rbind(values$df,data.frame("name" = input$name,"date" = input$date,
"training" = input$training, "certificate" = input$certificate)))
# saveRDS(values$df)
# saveRDS(FinalData)
}})
#display the inputs
output$Combined_table = renderDataTable({values$df})
}
)
试试这个演示:
library(shiny)
.log <- function(...) message(format(Sys.time(), format = "[ %H:%M:%S ]"), " ", ...)
.read <- function(path) if (file.exists(path)) return(readRDS(path))
shinyApp(
ui = fluidPage(
textInput("txt", "Text: "),
actionButton("btn", "Submit"),
tableOutput("tbl")
),
server = function(input, output, session) {
.log("hello world")
rv <- reactiveValues()
rv$df <- data.frame(row = 0L, word = "a", stringsAsFactors = FALSE)[0,]
observeEvent(req(input$btn), {
.log("submit!")
rv$df <- rbind(rv$df,
data.frame(row = input$btn, word = input$txt,
stringsAsFactors = FALSE))
.log("saveRDS: ", nrow(rv$df))
saveRDS(rv$df, "local.rds")
})
filedata <- reactiveFileReader(1000, session, "local.rds", .read)
output$tbl <- renderTable(filedata())
}
)
此应用程序的工程:
- 我像你一样使用
reactiveValues
来保存内存中的数据。 (注意:在 long-运行 中迭代地向帧添加行是不好的。如果这是小批量添加,那么你可能没问题,但它的扩展性很差。每次添加一行时,它都会复制整个帧,内存消耗加倍。)
- 我用零行框预填充了
$df
,只是为了格式化。这里没什么特别的。
observe
和observeEvent
不要return你感兴趣的东西,应该完全由side-effect操作。它做了 return 一些事情,但实际上只对 shiny
内部有意义。
saveRDS
和你一样,没什么特别的,但它确实有效。
- 我添加了一个
shiny::reactiveFileReader
以证明该文件正在保存。当闪亮的 table 显示更新时,这是因为 (1) 数据已添加到底层框架; (2) 帧保存到"local.rds"
文件;然后 (3) reactiveFileReader
注意到基础文件存在并且已经改变,导致 (4) 它调用我的 .read
函数来读取内容,并且 return 它作为反应数据进入 filedata
。这个block在一般情况下是完全不需要的,这里只是为了演示。
- 我为此
reactiveFileReader
创建了一个函数 .read
,它可以适应首先不存在的文件。如果该文件不存在,它会无形地 returns NULL
。可能有更好的方法来做到这一点。
我有一个闪亮的应用程序,它有很多文本输入。我无法正确保存数据部分,例如,无法保存到本地驱动器。有什么建议么?
server = function(input, output) {
values <- reactiveValues()
#Initial Dataframe
values$df <- data.frame(matrix(ncol=4,nrow=0, dimnames=list(NULL, c("Name", "date","Traning", "certificate"))))
FinalData =observe({
if(input$submit >0) {
isolate(values$df <- rbind(values$df,data.frame("name" = input$name,"date" = input$date,
"training" = input$training, "certificate" = input$certificate)))
# saveRDS(values$df)
# saveRDS(FinalData)
}})
#display the inputs
output$Combined_table = renderDataTable({values$df})
}
)
试试这个演示:
library(shiny)
.log <- function(...) message(format(Sys.time(), format = "[ %H:%M:%S ]"), " ", ...)
.read <- function(path) if (file.exists(path)) return(readRDS(path))
shinyApp(
ui = fluidPage(
textInput("txt", "Text: "),
actionButton("btn", "Submit"),
tableOutput("tbl")
),
server = function(input, output, session) {
.log("hello world")
rv <- reactiveValues()
rv$df <- data.frame(row = 0L, word = "a", stringsAsFactors = FALSE)[0,]
observeEvent(req(input$btn), {
.log("submit!")
rv$df <- rbind(rv$df,
data.frame(row = input$btn, word = input$txt,
stringsAsFactors = FALSE))
.log("saveRDS: ", nrow(rv$df))
saveRDS(rv$df, "local.rds")
})
filedata <- reactiveFileReader(1000, session, "local.rds", .read)
output$tbl <- renderTable(filedata())
}
)
此应用程序的工程:
- 我像你一样使用
reactiveValues
来保存内存中的数据。 (注意:在 long-运行 中迭代地向帧添加行是不好的。如果这是小批量添加,那么你可能没问题,但它的扩展性很差。每次添加一行时,它都会复制整个帧,内存消耗加倍。) - 我用零行框预填充了
$df
,只是为了格式化。这里没什么特别的。 observe
和observeEvent
不要return你感兴趣的东西,应该完全由side-effect操作。它做了 return 一些事情,但实际上只对shiny
内部有意义。saveRDS
和你一样,没什么特别的,但它确实有效。- 我添加了一个
shiny::reactiveFileReader
以证明该文件正在保存。当闪亮的 table 显示更新时,这是因为 (1) 数据已添加到底层框架; (2) 帧保存到"local.rds"
文件;然后 (3)reactiveFileReader
注意到基础文件存在并且已经改变,导致 (4) 它调用我的.read
函数来读取内容,并且 return 它作为反应数据进入filedata
。这个block在一般情况下是完全不需要的,这里只是为了演示。 - 我为此
reactiveFileReader
创建了一个函数.read
,它可以适应首先不存在的文件。如果该文件不存在,它会无形地 returnsNULL
。可能有更好的方法来做到这一点。