【问题标题】:Setting up data refreshing in Shiny app connected to PostgreSQL在连接到 PostgreSQL 的 Shiny 应用程序中设置数据刷新
【发布时间】:2015-10-09 20:16:00
【问题描述】:

我查看了 thisthis 线程以及其他一些线程,但无法找出我的解决方案。

我已经使用 R 和 Shiny 构建了一个仪表板,并且说仪表板使用 RPostgreSQL 包从 Postgres 数据库中提取数据。目前,所有数据提取和分析的代码都在shinyServer函数之外完成,只有显示部分(outputrender函数)在shinyServer部分。我想对其进行设置,以便定期刷新仪表板数据并更新图表。我已经研究了reactivePollinvalidateLater 并理解了它们,但不能完全弄清楚如何在我的代码中实现它。

这是一个简化的示例server.R 代码:

library(RPostgreSQL)

drv <- dbDriver("PostgreSQL")
con <- dbConnect(drv, host='host', port='12345', dbname='mydb',
                 user='me', password='mypass')

myQuery <- "select * from table"
myTable <- dbGetQuery(con, myQuery)

foo <- nrow(myTable)
bar <- foo * 2

shinyServer(
  function(input, output, session) {
    output$foo <- renderText(foo)
    output$bar <- renderText(bar)

    session$onSessionEnded(function(){
      dbDisconnect(con)
      dbDisconnect(con2)
      dbUnloadDriver(drv)
    })
  }
)

现在,如果我希望 foo 定期更新,这需要我刷新我也有的 dbGetQuery 命令,但我不知道如何让它们一起工作。我是否需要重新格式化并将所有内容放入 shinyServer 函数中?我有大约 250 行代码,将它们全部放在那里感觉不对,并且仅仅将数据提取部分放在那里可能会打乱事物的顺序。任何帮助表示赞赏。

【问题讨论】:

  • 查看invalidateLater,您将其与时间参数一起使用。我们使用它来自动更新地块。
  • @Thomas K 的解决方案对您的问题有效吗?我有同样的问题,并且会很高兴有一些工作代码示例。提前致谢!
  • @Blind0ne 这个问题是两年前提出的,老实说,我真的不记得任何细节,但我将其标记为正确,所以它必须至少部分有效。

标签: r postgresql shiny reactive-programming rpostgresql


【解决方案1】:

我会使用reactivePoll 而不是invalidateLater,因为它只会在有新数据的情况下重新获取整个数据。

但是,没有办法将代码放在shinyServer 中获取数据,因为您的后续计算取决于(反应性)数据。

免责声明:我没有任何 SQL 经验,由于缺少合适的数据库,我无法测试我的代码,但根据我对shiny 的理解,以下代码应该可以工作.

library(RPostgreSQL)

drv <- dbDriver("PostgreSQL")
con <- dbConnect(drv, host='host', port='12345', dbname='mydb',
                 user='me', password='mypass')

check_for_update <- function() {
  dbGetQuery(con, "SELECT MAX(timestamp) FROM table") # edit this part in case
  # the syntax is wrong. the goal is to create an identifier which changes
  # when the underlying data changes
}
get_data <- function() {
  dbGetQuery(con, "select * from table")
}
close_connection <- function() {
  dbDisconnect(con)
  dbUnloadDriver(drv)
}

shinyServer(
  function(input, output, session) {
    # checks for new data every 10 seconds
    data <- reactivePoll(10000, session,
                         checkFunc = check_for_update,
                         valueFunc = get_data)

    # the outputs will only be refreshed in case the data changed
    output$foo <- renderText({
      nrow(data())
    })
    output$bar <- renderText({
      bar <- data() * 2
    })

    session$onSessionEnded(close_connection)
  }
)

根据您应用的结构,将计算封装到单独的 reactive 中可能会有所帮助,您可以在多个地方重复使用它。

可以在tutorial 中找到有关使用 shinyApps 执行代码的一些说明。

如果您遇到任何问题,请发表评论,我会尝试相应地更新我的帖子。

【讨论】:

  • 谢谢 Thomas,我觉得你的代码可以工作,但我担心的是,如果我在里面刷新它,它将如何影响我对 shinyServer 之外的数据进行的计算.我编辑了我的示例以包含“bar”行以使其更好。在这种情况下,数据在函数内部被刷新,但是为我们提供 bar 值的计算只在函数外部发生一次。那么每次刷新数据时我是否必须将所有内容移到里面并让它运行?
  • @NeonBlueHair 我认为没有办法将计算拉入shinyServer。我不知道您在“计算”中做了什么,但显然如果数据本身发生变化,您需要重新运行对数据所做的任何转换。
猜你喜欢
  • 2019-08-02
  • 2017-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-03
  • 1970-01-01
  • 1970-01-01
  • 2016-08-18
相关资源
最近更新 更多