将RData文件读入Shiny Application

时间:2016-06-27 22:14:01

标签: r shiny

我正在制作一个闪亮的应用程序,它将读取一些RData文件并显示包含内容的表格。这些文件由脚本生成,最终将数据转换为数据帧。然后使用save()函数保存它们。

在闪亮的应用程序中,我有三个文件:

ui.R,server.R和global.R

我希望在一段时间内读取文件,以便在文件更新时更新它们,因此我正在使用:

reactiveFileReader() 

我已经按照我在网上找到的一些说明进行了操作,但是我一直收到错误"错误:缺少需要TRUE / FALSE的值"。我试图简化这个,所以我没有使用:

reactiveFileReader() 

功能,只需在server.R中加载文件(也在global.R文件中尝试过)。

load()

语句正在数据框中读取。我通过在文件中加载,然后将文件分配给变量并执行" as.data.table"来实现这一点,但这不应该重要,这应该在数据帧格式就好了。我认为这是一个范围问题,但我不确定。有帮助吗?我的代码在:

http://pastebin.com/V01Uw0se

非常感谢!

2 个答案:

答案 0 :(得分:8)

这是受此帖http://www.r-bloggers.com/safe-loading-of-rdata-files/启发的可能解决方案。 Rdata文件被加载到一个新环境中,以确保它不会产生意外的副作用(覆盖现有的变量等)。单击该按钮时,将生成一个新的随机数据框,然后将其保存到文件中。然后,reactiveFileReader将文件读入新环境。最后,我们访问新环境中的第一个项目(假设Rdata文件只包含一个作为数据框的变量)并将其打印到表格中。

library(shiny)

# This function, borrowed from http://www.r-bloggers.com/safe-loading-of-rdata-files/, load the Rdata into a new environment to avoid side effects
LoadToEnvironment <- function(RData, env=new.env()) {
  load(RData, env)
  return(env)
}

ui <- shinyUI(fluidPage(

  titlePanel("Example"),

  sidebarLayout(
    sidebarPanel(
      actionButton("generate", "Click to generate an Rdata file")
    ),

    mainPanel(
      tableOutput("table")
    )
  )
))

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

  # Click the button to generate a new random data frame and write to file
  observeEvent(input$generate, {
    sample_dataframe <- data.frame(a=runif(10), b=rnorm(10))
    save(sample_dataframe, file="test.Rdata")
    rm(sample_dataframe)
  })

  output$table <- renderTable({
    # Use a reactiveFileReader to read the file on change, and load the content into a new environment
    env <- reactiveFileReader(1000, session, "test.Rdata", LoadToEnvironment)
    # Access the first item in the new environment, assuming that the Rdata contains only 1 item which is a data frame
    env()[[names(env())[1]]]
  })

})

shinyApp(ui = ui, server = server)

答案 1 :(得分:1)

好的 - 我想出了如何做我需要做的事情。对于我的第一个问题,我想要'renderDataTable'的外观和感觉,但我想拉入一个数据框(renderDataTable / dataTableOutput不允许这样,它必须是表格式)。为了做到这一点,我发现了一个方便的ReportingTools(来自Bioconductor)以及它们是如何做到的。这允许您直接使用数据框,并且仍然具有HTML表,包括排序,搜索,分页等。信息可以在这里找到:

https://bioconductor.org/packages/release/bioc/html/ReportingTools.html

现在,对于我的第二个问题 - 定期更新数据和表而不重新启动应用程序。事实证明这很简单,只花了我一些时间来弄明白,对Shiny来说是新手。有一点需要指出,为了保持这个例子的简单,我使用了renderTable而不是上面使用ReportingTools包的解决方案。我只是想让这个例子变得简单。我做的第一件事是在observe({})中包装我的所有server.R代码(在shinyServer()函数内)。然后我使用invalidateLater()告诉它每5秒刷新一次。这是代码:

## server.R ##
library(shiny)
library(shinydashboard)
library(DT)

shinyServer(function(input, output, session) {

  observe({

    invalidateLater(5000,session)

    output$PRI1LastPeriodTable <- renderTable({
      prioirtyOneIncidentsLastPeriod <- updateILP()
    })
  })
})

现在,对于renderTable()部分来说,我只是调用了加载的.Rdata文件的对象名,但我希望每次都能读取它,所以我在我的global.R文件中创建了一个函数(这个本来可以在server.R)加载文件。那段代码在这里:

updateILP <- function() {
  load(file = "W:/Projects/R/Scripts/ITPOD/itpod/data/prioirtyOneIncidentsLastPeriod.RData", envir = .GlobalEnv)
  return(prioirtyOneIncidentsLastPeriod)
}

就是这样,global.R文件中没有其他内容。然而,您的ui.R将是您设置,调用tableOutout,dataTableOutput或UI中的任何渲染方法。因此,每5秒读取一次renderTable()代码会发生什么,这反过来会调用实际读取文件的函数。我通过更改数据文件测试了这一点,并且更新了闪亮的应用程序而没有与我进行任何交互。奇迹般有效。

如果这不优雅或效率不高,请告诉我是否可以改进,这是我能想到的最直接的方式。感谢大家的帮助和评论!