在连接到PostgreSQL的Shiny应用程序中设置数据刷新

时间:2015-10-09 20:16:01

标签: r postgresql shiny reactive-programming rpostgresql

我查看了thisthis帖子以及其他一些帖子,但未能找到我的解决方案。

我使用R和Shiny构建了一个仪表板,并且表示仪表板使用RPostgreSQL包从Postgres数据库中提取数据。现在,所有数据提取和分析的代码都在shinyServer函数之外完成,只有显示部分(outputrender函数)在{{1部分。我想对其进行设置,以便定期刷新仪表板数据并更新图表。我查看过shinyServerreactivePoll并了解它们,但无法弄清楚如何在我的代码中实现它。

以下是一个简化示例invalidateLater代码:

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函数中?我有大约250行代码,将它们全部放在那里感觉不对,只是将数据拉入其中就可能搞乱事情的顺序。任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:3)

我会使用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中可能会有所帮助,您可以在多个位置重复使用。

有关使用shinyApps执行代码的一些注意事项,请参阅此tutorial

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