优化性能 - Shiny 中的大文件输入

Optimizing Performance - Large File Input in Shiny

我在文件 CheckClawback.R 中定义了一个函数 (clawCheck),它将三个数据帧作为参数。在我的 Shiny 应用程序中,用户上传三个文件,然后将其读入内存并用作 ClawCheck 参数。为了节省时间,我希望 R 在文件上传后立即开始将文件读入内存,而不是仅在按下 "GO" 按钮之后,以便一旦按下按钮,ClawCheck 的参数是已在内存中并可以使用。

我想我必须在 renderTable 语句中使用 eventReactive 表达式,因为我不希望每次用户更改某些输入时都重新读取文件。为了避免进一步复杂化,我假设输入是按顺序填写的,即首先 "account",然后 "commpaid",然后 "termriders"。当我 运行 应用程序和第一个输入文件已上传时,没有出现进度条,这表明我的代码无法正常工作。这是我的(简化的)代码:

library('shiny')

source("CheckClawback.R")

ui <- fluidPage(

  sidebarLayout(

    sidebarPanel(

      fileInput("account", "Account File (.csv)"), 

      fileInput("commpaid", "CommPaid File (.txt)"), 

      fileInput("termriders", "TermRiders File (.txt)"), 

      actionButton("do", "GO!")),

    mainPanel(
      tableOutput("out_table"))
  )
)


server <- function(input, output) {


  func <- eventReactive(input$do, {

    req(acc)
    req(comm)
    req(term)

    datat <<- clawCheck(acc, comm, term)

  })


  output$out_table <- renderTable({

    eventReactive(input$account, {

      withProgress(message = "Preparing Account Data...Please Wait", {

      acc <<- read.csv(input$account$datapath, header = TRUE, sep = ",")

      })
    })

    eventReactive(input$commpaid, {

      withProgress(message = "Preparing CommPaid Data...Please Wait", {

        comm <<- read.table(input$commpaid$datapath, header = TRUE, sep = "\t")

      })
    })

    eventReactive(input$termriders, {

      withProgress(message = "Preparing TermRiders Data...Please Wait", {

        term <<- read.table(input$termriders$datapath, header = TRUE, sep = "\t")

      })
    })

    withProgress(func(), message = "Loading Output...Please Wait")

    datat
  })

}

shinyApp(ui = ui, server = server)

理想情况下,文件上传后,应该出现一个进度条,表示正在处理中。如果在此过程中上传了第二个文件,则应出现第二个进度条,表明正在处理第二个文件等。一旦实际函数调用发生,我希望输入文件准备就绪。

非常感谢您的帮助!

您对 <<-withProgress() 的使用是错误的。此外,在 render*() 中使用 eventReactive() 是错误的。我建议阅读 RStudio Shiny 教程,以帮助理解 reactivity 的工作原理。另请查看 showNotification() 而不是 withProgress()。现在,这就是您可能需要的 -

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

  acc <- reactive({
    validate(need(input$account), "acc not uploaded")
    # use showNotification(); use same approach for other files
    read.csv(input$account$datapath, header = TRUE, sep = ",")
    # use removeNotification() to remove mesg after file is uploaded
  })

  comm <- reactive({
    validate(need(input$commpaid), "comm not uploaded")
    read.table(input$commpaid$datapath, header = TRUE, sep = "\t")
  })

  term <- reactive({
    validate(need(input$termriders), "term not uploaded")
    read.table(input$termriders$datapath, header = TRUE, sep = "\t")
  })


  func <- eventReactive(input$do, {
    clawCheck(acc(), comm(), term())
  })


  output$out_table <- renderTable({
    func()
  })

}