【问题标题】:Using Shiny fileInput to get path only使用 Shiny fileInput 仅获取路径
【发布时间】:2018-02-17 11:48:00
【问题描述】:

我有一个非常大的固定宽度文件,需要使用我的 Shiny 应用程序读取。我的程序目前的结构方式是 ui.R 包含一个 fileInput 允许用户使用浏览器定位文件。

在服务器端,我只捕获文件的路径,如下所示:

path2file <- reactive({
    infile <- input$path2file
    if (is.null(infile)) return(NULL)    
    infile$datapath  
}) 

后续函数将该路径作为输入,然后根据其布局规范读取文件。这一切都很好;但是,在处理非常大的 fwf 文件时,我的程序会大大减慢速度,并且需要数小时才能使用 fileInput 读取文件的路径名

我怀疑 fileInput 实际上是在读取整个文件,然后我的函数只返回数据路径,即使我没有在函数中明确读取任何文件格式类型。

我的目标是继续使用我现在构建的程序,并使用我的 fileInput 仅获取此文件的路径。我在 SO 上找到了这个主题,并认为这是一个可能的选择。

Getting file path from Shiny UI (Not just directory) using browse button without uploading the file

但是,我的目标也是尽量减少我拥有的包依赖项的数量;这已成为一个大问题,因此如果我必须使用额外的软件包,我会这样做,但我想不惜一切代价避免这种情况。

我尝试了这个便宜的技巧:

path2file <- reactive({
    infile <- input$path2file
    if (is.null(infile)) return(NULL)    
    scan(infile$datapath, n = 1)
    infile$datapath  
}) 

认为这将是一个快速的解决方法,但它也非常非常慢,所以我怀疑它也不是只读取 n = 1。所以,我的问题是任何人都可以找到一种方法来使用 fileInput 允许用户定位文件并让服务器端函数仅捕获路径而不读取文件或尝试以任何方式解析它?更重要的是,这可以单独使用 base R 和 Shiny 中的函数来完成,而不必从其他扩展包中获取函数吗?

以上是server.R文件中的相关部分代码,ui.R文件中的相关部分代码是

fileInput('path2dor', 'Choose the DOR .txt file to format',
        accept=c('text/csv', 
        'text/comma-separated-values,text/plain', '.csv')), 

感谢您的建议。

【问题讨论】:

  • 你能不能请一个小的可复制的例子
  • 添加了上面 ui.R 中的相关代码块。您需要一个最小的工作示例还是我提供的足够?
  • 如果您还没有意识到,您获得的路径将是您临时文件夹中的某个路径,而不是您的实际路径。也许您已经知道这一点,但只是说以防万一您还没有意识到。如果您有兴趣获取实际路径而不是临时路径,可以关注this 链接。
  • @HaroldDoran 你得到这个问题的答案了吗?

标签: r shiny


【解决方案1】:

fileInput 无法实现此功能。原因是“fileInput”出于安全原因不向服务器提供本地路径信息。 使用fileInput,用户在他的本地计算机上浏览浏览器,服务器端的结果文件是所选本地一次的上传副本。

作为替代方案,您可以使用shinyFiles 包,它可以在服务器端导航。这意味着,您可以获得本地计算机上的所有路径。

第二种选择可能是简单的文本输入,它允许用户手动添加路径(确保检查服务器端的路径以免遇到任何问题)。

【讨论】:

    【解决方案2】:

    正如其他人所指出的,由于安全问题,shiny 创建了一个 tmp 文件夹,其中所有加载的文件都使用fileinput 调用 因此,您需要选择文件夹中所有感兴趣的文件,然后使用...$datapath 调用此 tmp 文件 但是请注意,datapath 的每个元素都将包括目录信息和相应的文件名。因此,您需要修剪这些路径以仅考虑 tmp 目录。这可以通过以下方式实现... 假设您将创建一个名为 phu 的对象,该对象仅包含您使用 fileInput("upload", NULL, buttonLabel = "Upload...", multiple = TRUE) 调用的文件夹中的第一个文件(使用 input$upload$datapath[1]

    phu<-as.character(input$upload$datapath[1])
    phu<-substr(phu,1,nchar(phu)-5)
    

    第二行删除字符串中的最后五个字符。这些字符是0.txt 或您在输入中调用的任何其他扩展名。提供的代码仅适用于 .txt 文件并且需要 tm 包。您现在可以使用对象phu 作为感兴趣的输入目录。 最后,您需要使用output 对象调用此输出并将其打印到您的ui 中,如下面的textOutput("Pdiretory") 所示。

    下面的例子展示了整个过程。请注意,没有安全问题,因为此临时文件及其内容将在关闭时被删除。同样,输入文件是.txt 文件。

     library(shiny)
     library(tm)
        ui <- fluidPage(
                  fileInput("upload", NULL, buttonLabel = "Upload...", multiple = TRUE),
                  textOutput("Pdiretory")
                )
        
    server <- function(input, output, session) {
        
          listdir <- eventReactive(input$upload, {
            phu<-as.character(input$upload$datapath[1])
            phu<-substr(phu,1,nchar(phu)-5)
            txt<-Corpus(DirSource(phu),readerControl = list(language = "en"))
            print(txt)
          })
          
          output$Pdiretory <- renderPrint ({
            listdir()
          })
          
        }
        shinyApp(ui = ui, server = server)
    

    【讨论】:

      猜你喜欢
      • 2019-12-26
      • 1970-01-01
      • 2020-10-19
      • 2016-04-15
      • 2015-11-25
      • 1970-01-01
      • 2019-10-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多