.RData中的reactiveFileReader

.RData中的reactiveFileReader,r,shiny,R,Shiny,我目前在一个闪亮的应用程序中的工作流程是定期运行一个R脚本作为cron作业,从多个数据库中提取各种表,以及从一些API下载数据。然后将它们保存为.Rdata文件,保存在名为data的文件夹中 在我的global.R文件中,我使用load(“data/workingdata.Rdata”)加载数据。这将导致所有数据帧(大约30个)加载到环境中。我知道我可以使用reactiveFileReader()函数来刷新数据,但显然,由于与该函数关联的会话,它必须在server.R文件中使用。另外,我不确定r

我目前在一个闪亮的应用程序中的工作流程是定期运行一个R脚本作为cron作业,从多个数据库中提取各种表,以及从一些API下载数据。然后将它们保存为.Rdata文件,保存在名为
data
的文件夹中

在我的
global.R
文件中,我使用
load(“data/workingdata.Rdata”)
加载数据。这将导致所有数据帧(大约30个)加载到环境中。我知道我可以使用
reactiveFileReader()
函数来刷新数据,但显然,由于与该函数关联的会话,它必须在server.R文件中使用。另外,我不确定
reactiveFileReader()
中的
load
是否被接受为
readFunc
。对于这种情况,最好的策略是什么?

您可以在server.R的顶部使用
load(“data/workingdata.Rdata”)
。然后,任何时候任何人启动一个新的闪亮会话,数据都将是最新的。可能的缺点是:

  • 如果在新会话加载数据的同时写入数据,则可能会出现问题
  • 如果在新数据可用之前和之后打开会话,则数据将过时
我想第一个可能出现的问题不足以成为问题。第二个可能的问题更可能发生,但除非你处于一个非常危急的情况下,否则我看不出这是一个值得担心的重大问题


这对你有用吗?

关于你的工作流程的一些想法:

最后,使用RData方法,您将设置另一个与数据库/API并行的数据源

处理文件时,总是会有一些内务管理开销(例如,读取.RData文件时是否已完成?)。在我看来,这(部分)就是DBMS的用途——负责管理。他们中的大多数人都有复杂的解决方案,以确保您能够非常快速地获得所查询的内容;那么为什么要重新发明轮子呢

与使用reactiveFileReader()函数连续创建.RData文件和轮询数据不同,您可以使用reactivePoll直接查询数据库中的更改(请参见 例如使用sqlite)。如果您的查询是长时间运行的(我想这就是您的工作流的原因),您可以在将来将它们包装起来,并异步运行它们(参见此) 获得一些灵感)。 或者,许多DBM提供类似物化视图的功能,以避免长时间的等待(根据假定的用户权限)


当然,所有这些都是基于假设的,因为我不知道您的生态系统,但根据我的经验,减少接口意味着减少错误源。

此示例使用带有
observe
invalidaterater的
reactiveVal
对象。数据将加载到新环境中,并每2秒分配给reactiveVal

library(shiny)

ui <- fluidPage(
  actionButton("generate", "Click to generate an Rdata file"),
  tableOutput("table")
)

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

  ## Use reactiveVal with observe/invalidateLater to load Rdata
  data <- reactiveVal(value = NULL)
  observe({
    invalidateLater(2000, session)
    n <- new.env()
    print("load data")
    env <- load("workingdata.Rdata", envir = n)
    data(n[[names(n)]])
  })


  ## Click the button to generate a new random data frame and write to file
  observeEvent(input$generate, {
    sample_dataframe <- iris[sample(1:nrow(iris), 10, F),]
    save(sample_dataframe, file="workingdata.Rdata")
    rm(sample_dataframe)
  })

  ## Table output
  output$table <- renderTable({
    req(data())
    data()
  })
})


shinyApp(ui = ui, server = server)
库(闪亮)

你看到什么了?也许
reactivePoll
invalidaterater
在这里也可能很有趣。@SeGa谢谢,这正是我用来找出某种解决方案的帖子!谢谢你的评论。正如您正确猜测的那样,从用户体验的角度来看,执行查询需要的时间太长(在某些情况下需要7到8分钟)。我已经在使用异步编程了,但是对于查询来说,这么长的时间是不可接受的。因此采用了.Rdata方法。轮询每4小时进行一次。如果您继续使用
load()
作为
readFunc
reactiveFileReader()
readFunc()
,您应该将其包装在
tryCatch()
中,以获得全天候可用的应用程序。感谢您的回答,但不幸的是,这不是一个选项。该应用程序全天候可用(几乎是关键任务),用户不会开始新的会话。