【问题标题】:readxl::read_xls returns "libxls error: Unable to open file"readxl::read_xls 返回“libxls 错误:无法打开文件”
【发布时间】:2019-12-06 17:51:18
【问题描述】:

我有多个 .xls (~100MB) 文件,我想将多个工作表(从每个工作表)加载到 R 作为数据框。我尝试了各种功能,例如xlsx::xlsx2XLConnect::readWorksheetFromFile,它们总是运行很长时间(>15 分钟)并且永远无法完成,我必须强制退出 RStudio 才能继续工作。

我还尝试了gdata::read.xls,它确实完成了,但每张纸需要超过 3 分钟,并且它不能像XLConnect::loadWorkbook 一样一次提取多张纸(这对加快我的管道非常有帮助)可以。

执行这些函数所需的时间(我什至不确定如果我让它们运行更长时间,前两个函数是否会完成)对于我需要同时处理多个文件的管道来说太长了。有没有办法让这些更快/完成?

在几个地方,我看到了使用函数readxl::read_xls 的建议,它似乎被广泛推荐用于此任务,并且每张纸应该更快。但是,这给了我一个错误:

> # Minimal reproducible example:
> setwd("/Users/USER/Desktop")
> library(readxl)
> data <- read_xls(path="test_file.xls")
Error: 
  filepath: /Users/USER/Desktop/test_file.xls
  libxls error: Unable to open file

我还进行了一些基本测试以确保文件存在并且格式正确:

> # Testing existence & format of the file
> file.exists("test_file.xls")
[1] TRUE
> format_from_ext("test_file.xls")
[1] "xls"
> format_from_signature("test_file.xls")
[1] "xls"

上面使用的test_file.xls 可用here。 在使第一个函数运行得更快或read_xls 运行方面的任何建议将不胜感激 - 谢谢!

更新:

似乎有些用户能够使用readxl::read_xls 函数打开上述文件,而其他用户则不能,无论是在Mac 还是Windows 上,使用最新版本的RRstudioreadxlissue has been posted on the readxl GitHub 尚未解决。

【问题讨论】:

    标签: r excel macos xls readxl


    【解决方案1】:

    我下载了您的数据集并以这种方式读取了每个 excel 表(例如,对于表“Overall”和“Area”):

    install.packages("readxl")
    library(readxl)
    library(data.table)
    
    dt_overall <- as.data.table(read_excel("test_file.xls", sheet = "Overall"))
    area_sheet <- as.data.table(read_excel("test_file.xls", sheet = "Area"))
    

    最后,我得到了这样的 dt(例如,“区域”表只有部分数据集):

    同样,您可以使用read_xls 函数代替read_excel

    我检查了一下,它也可以正常工作,甚至更快一些,因为read_excelread_xlsread_xlsx 函数的包装器,来自readxl 包。

    此外,您可以使用 readxl 包中的 excel_sheets 函数来读取您的 Excel 文件的所有工作表。

    更新

    使用microbenchmark 包对以下包/功能进行基准测试:gdata::read.xlsXLConnect::readWorksheetFromFilereadxl::read_excel

    XLConnect 是基于 Java 的解决方案,因此需要大量 RAM。

    【讨论】:

    • 尝试卸载readxl包,重启RStudio并重新安装readxl。还可以尝试将 R 和 RStudio 更新到最新版本(如果您有过时的版本)。
    • 哦,这很有趣。我希望他们能帮助您找到解决问题的方法。同时,我还有两个建议,可能对您有所帮助: 1. 尝试直接安装 Rcpp 包,这又需要 Xcode(对于 OSX),这是 R 外部的依赖项。
    • 2.尝试使用旧版本的 readxl 软件包打开您的 excel 文件(例如,v.1.3.0、1.2.0、1.1.0. 等;所有存档版本都可在此处获得:cran.r-project.org/src/contrib/Archive/readxl)。你可以这样安装它(例如):if(!require(readxl)) { install.packages("https://cran.r-project.org/src/contrib/Archive/readxl/readxl_1.2.0.tar.gz", repos = NULL, type="source"); suppressPackageStartupMessages(require(readxl))} P.S.在链接中您可以指定任何版本的存档包
    • 当然,不。在使用 readxl 包加载它之前,我没有更改或打开 excel 文件。我在 Windows 10 Enterprise(RAM 16 GB,64 位)上运行代码。但!当我尝试使用 RStudio Server (Ubuntu) 读取您的 excel 文件时,我得到同样的错误:libxls error: Unable to open file.
    • 哦,很奇怪(我有&gt; sessionInfo() R version 3.6.1 (2019-07-05) Platform: x86_64-w64-mingw32/x64 (64-bit) Running under: Windows &gt;= 8 x64 (build 9200)(Windows:Windows 10 Enterprise,版本 1803,操作系统版本 17134.1006。过程:英特尔酷睿 i7-8550U,64 位操作系统)。RStudio -版本 1.1.456(2018 年 7 月 19 日)
    【解决方案2】:

    我将提出不同的工作流程。如果您碰巧安装了 LibreOffice,那么您可以通过编程方式将您的 excel 文件转换为 csv。我有 Linux,所以我用 bash 做,但我确信它可以在 macOS 中实现。

    所以打开一个终端并导航到包含您的 excel 文件的文件夹并在终端中运行:

    for i in *.xls
        do soffice --headless --convert-to csv "$i" 
    done
    

    现在在 R 中,您可以使用 data.table::fread 循环读取文件:

    场景一:文件结构不同

    如果文件的结构不同,那么您不会想将它们rbind 放在一起。你可以在 R 中运行:

    files <- dir("path/to/files", pattern = ".csv")
    all_files <- list()
    for (i in 1:length(files)){
      fileName <- gsub("(^.*/)(.*)(.csv$)", "\\2", files[i])
      all_files[[fileName]] <- fread(files[i])
    }
    

    如果您想将列表中的命名元素提取到全局环境中,以便将它们转换为对象,可以使用list2env

    list2env(all_files, envir = .GlobalEnv)
    

    请注意两点:第一,在gsub 调用中,斜线的方向。其次,list2env 可能会覆盖全局环境中的对象,前提是它们与列表中的命名元素同名。

    场景二:文件结构相同

    在这种情况下,您可能想将它们一起rbind。你可以在 R 中运行:

    files <- dir("path/to/files", pattern = ".csv")
    joined <- list()
    for (i in 1:length(files)){
      joined <- rbindlist(joined, fread(files[i]), fill = TRUE)
    }
    

    【讨论】:

    • 感谢您的回复!我更喜欢完全在 R 中完成的解决方案,因为我正在为一个不那么精通编码的朋友开发这个工作流程,所以我想把一个工作脚本交给她,而不是不得不转到终端。
    【解决方案3】:

    我发现我下载后无法立即用read_xl打开文件,但是如果我在Excel中打开文件,保存并再次关闭它,那么read_xl可以毫无问题地打开它.

    我建议的处理数百个文件的解决方法是构建一个小的 C# 命令行实用程序来打开、保存和关闭 Excel 文件。源码如下,可以用visual studio社区版编译。

    using System.IO;
    using Excel = Microsoft.Office.Interop.Excel;
    
    namespace resaver
    {
      class Program
      {
        static void Main(string[] args)
        {
          string srcFile = Path.GetFullPath(args[0]);
          Excel.Application excelApplication = new Excel.Application();
          excelApplication.Application.DisplayAlerts = false;
          Excel.Workbook srcworkBook = excelApplication.Workbooks.Open(srcFile);
          srcworkBook.Save();
          srcworkBook.Close();
          excelApplication.Quit();
        }
      }
    }
    

    编译后,可以从 R 中调用该实用程序,例如system2().

    【讨论】:

      【解决方案4】:

      在我的系统上,我必须使用path.expand

      R> file = "~/blah.xls"
      R> read_xls(file)
      
      Error: 
        filepath: ~/Dropbox/signal/aud/rba/balsheet/data/a03.xls
        libxls error: Unable to open file
      
      R> read_xls(path.expand(file)) # fixed
      

      【讨论】:

        【解决方案5】:

        重新保存您的文件,您可以轻松解决问题。

        我以前也发现过这个问题,但我从你的讨论中得到了答案。

        我使用read_excel() 打开这些文件。

        【讨论】:

        • 您的意思是用 Excel 重新保存文件吗?是的,这已经被建议了,但是在处理数百个文件时它并不能解决问题(您可以想象在 Microsoft Excel 中打开和重新保存每个文件需要很长时间)。
        • 无论使用read_xls()还是read_excel()都没有区别-根据read_excel() documentationread_xls()实际上更好:“read_excel()调用excel_format()来确定路径是 xls 还是 xlsx,取决于文件扩展名和文件本身,按此顺序排列。如果您更了解并希望防止此类猜测,请直接使用 read_xls()read_xlsx()。"
        【解决方案6】:

        我看到了类似的错误,想分享一个短期解决方案。

        library(readxl)
        download.file("https://mjwebster.github.io/DataJ/spreadsheets/MLBpayrolls.xls", "MLBPayrolls.xls")
        MLBpayrolls <- read_excel("MLBpayrolls.xls", sheet = "MLB Payrolls", na = "n/a")
        

        产量(在我教室的某些系统上,但在其他系统上):

        错误:文件路径:MLBPayrolls.xls libxls 错误:无法打开文件

        临时的解决办法是将xls文件的URL粘贴到Firefox中,然后通过浏览器下载。完成此操作后,我们可以运行read_excel 行而不会出错。

        这发生在今天的 Windows 10 上,带有 R 3.6.2 和 R Studio 1.2.5033。

        【讨论】:

        • 谢谢,@Ryan!就像我在 GitHub 上提到的,OP 中描述的问题是文件已经在本地下载,所以这可能是另一回事。
        【解决方案7】:

        如果你是从网上下载的.xls数据,即使你在Ms.Excel中打开它,它也会先打开一个提示,询问你是否信任来源,看下面的截图,我猜这是R (read_xls) 也无法打开它的原因,因为它被认为是不安全的。将其保存为 .xlsx 文件,然后使用 read_xlsx()read_excel()

        【讨论】:

          【解决方案8】:

          即使认为这不是基于代码的解决方案,我只是更改了类型文件。例如,我保存为csvxlsx 而不是xls。然后我像普通一样打开它。
          我为我工作,因为当我打开我的xlsfile 时,我弹出消息:“'file.xls''的文件格式和扩展名不匹配。文件可能已损坏或不安全...”

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-12-13
            • 1970-01-01
            • 1970-01-01
            • 2021-08-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多