【问题标题】:Reload fileInput when actionButton is clicked单击 actionButton 时重新加载 fileInput
【发布时间】:2019-11-27 14:18:30
【问题描述】:

我编写了一个 Shiny 应用程序,该应用程序将几个用户定义的 csv 文件加载为 fileInput。该应用程序旨在绘制来自运行测量的数据,并且大约每五分钟将新数据点写入输入文件。我希望能够通过单击 actionButton 来重新加载所有输入。

我尝试将读取.csv 的函数定义为eventReactive

library(shiny)

ui <- fluidPage(
  actionButton(inputId = "update", label = "Reload input files"),
  fileInput(inputId = "file", label = "Choose file"),
  textOutput("test")
)

server <- function(input, output) {
  data <- eventReactive(input$update, {
    mydata <- read.delim(input$file$datapath)
    return(nrow(mydata))
    })
  output$test <- renderText(print(data()))
}

shinyApp(ui = ui, server = server)

当我选择输入文件并单击操作按钮时,输出会正确呈现。如果我现在打开 csv 文件,添加其他行并再次单击操作按钮,则输出不会更新。

【问题讨论】:

  • 问题是 input$file$datapath 链接到上传文件时创建的临时文件。因此按下更新按钮将再次读取临时文件,但该文件与您的原始文件不同。

标签: r shiny


【解决方案1】:

基于this answer,我能够为您的问题创建一个解决方法。 正如我在上面的评论中指出的那样,无法使用操作按钮更新fileInput 的原因显然是fileInput 在临时目录中创建了一个临时文件,Input$file$datapth 链接到这个临时目录文件。因此,您可以根据需要随时使用操作按钮重新加载文件,对原始文件的更改将不会反映,因为链接指向临时文件。我真的不知道为什么 inputFile 可以处理临时文件,但是使用 shinyFiles 包,您可以构建一个解决方法。您有一个按钮可以获取文件的真实链接并加载数据,另一个按钮可以重新加载数据。按下加载按钮将重新加载原始数据,并反映对它的所有更改。

library(shiny)
library(shinyFiles)


ui <- fluidPage(
    shinyFilesButton("GetFile", "Choose a file" ,
                     title = "Please select a file:", multiple = FALSE,
                     buttonType = "default", class = NULL),

    actionButton(inputId = "reload", label = "Reload data"),

    tableOutput("test")     
)


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

    volumes <- getVolumes()

    v = reactiveValues(path = NULL)

    observe({
        shinyFileChoose(input, "GetFile", roots = volumes, session = session)

        if (!is.null(input$GetFile)) {
            file_selected <- parseFilePaths(volumes, input$GetFile)
            v$path <- as.character(file_selected$datapath)
            req(v$path)
            v$data <- read.csv(v$path)
        }
    })

    observeEvent(input$reload, {
        req(v$path)
        v$data <- read.csv(v$path)

    })

    output$test <- renderTable({
        print(v$path)
        if (is.null(v$data)) return()
        v$data
    })

}

shinyApp(ui = ui, server = server)

更新

也可以将此方法与reactiveFileReader 结合使用,请参见下面的示例:

library(shiny)
library(shinyFiles)


ui <- fluidPage(
  shinyFilesButton("GetFile", "Choose a file" ,
                   title = "Please select a file:", multiple = FALSE,
                   buttonType = "default", class = NULL),


  tableOutput("test")     
)


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

  volumes <- getVolumes()

  v = reactiveValues(path = NULL)

  observe({

    shinyFileChoose(input, "GetFile", roots = volumes, session = session)

      req(input$GetFile)
      file_selected <- parseFilePaths(volumes, input$GetFile)
      v$path <- as.character(file_selected$datapath)
      req(v$path)
      v$data <- reactiveFileReader(1000, session, filePath = v$path, readFun = read.csv, sep = ";")

  })


  output$test <- renderTable({
    print(v$path)
    req(v$data)
    v$data()

  })

}

shinyApp(ui = ui, server = server)

【讨论】:

  • 谢谢,一切正常!但是,与此同时,我遇到了 reactiveFileInput 函数,如this answer 中所述。实际上,这会比在点击事件上重新加载更好。我只是试图用v$data &lt;- reactiveFileReader(intervalMillis = 60000, session = session, filePath = v$path, readFunc = read.csv) 替换你的行v$data &lt;- read.csv(v$path),但它抛出了Error: cannot coerce class "c("reactiveExpr", "reactive")" to a data.frame。有什么办法可以解决这个问题?
  • 我在回答的时候正准备建议reactiveFileReader,但是遇到了同样的错误。我会在接下来的几天里看看它。
  • 顺便问一下:我是否必须将自己的问题标记为与旧的question I linked above 重复?我想这是重复的,但第一个问题没有得到充分回答。
  • 您不需要将自己的问题标记为重复,其他人可能会这样做。由于第一个问题没有得到充分回答,我的看法是它不符合重复的条件,至少不再是。
  • 我想通了。你非常接近。诀窍是调用v$data 作为响应式在末尾添加括号,如v$data()。然后错误消息不显示,文件自动更新。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-17
  • 1970-01-01
  • 2019-07-20
  • 1970-01-01
  • 2013-03-08
  • 1970-01-01
相关资源
最近更新 更多