我正在制作一个闪亮的应用程序,它将读取一些RData文件并显示包含内容的表格。这些文件由脚本生成,最终将数据转换为数据帧。然后使用save()函数保存它们。
在闪亮的应用程序中,我有三个文件:
ui.R,server.R和global.R
我希望在一段时间内读取文件,以便在文件更新时更新它们,因此我正在使用:
reactiveFileReader()
我已经按照我在网上找到的一些说明进行了操作,但是我一直收到错误"错误:缺少需要TRUE / FALSE的值"。我试图简化这个,所以我没有使用:
reactiveFileReader()
功能,只需在server.R中加载文件(也在global.R文件中尝试过)。
load()
语句正在数据框中读取。我通过在文件中加载,然后将文件分配给变量并执行" as.data.table"来实现这一点,但这不应该重要,这应该在数据帧格式就好了。我认为这是一个范围问题,但我不确定。有帮助吗?我的代码在:
非常感谢!
答案 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()代码会发生什么,这反过来会调用实际读取文件的函数。我通过更改数据文件测试了这一点,并且更新了闪亮的应用程序而没有与我进行任何交互。奇迹般有效。
如果这不优雅或效率不高,请告诉我是否可以改进,这是我能想到的最直接的方式。感谢大家的帮助和评论!