【问题标题】:Read Excel Tables, not simple named ranges阅读 Excel 表格,而不是简单的命名范围
【发布时间】:2013-07-14 07:46:27
【问题描述】:

为避免“重复”关闭请求:我知道如何读取 Excel 命名范围;下面的代码中给出了示例。这是关于 Excel 中的“真实”表格。

Excel2007及更高版本有表格的有用概念:可以将范围转换为表格,避免排序和重新排列时的麻烦。当您在 Excel 范围内创建表格时,它会获得一个默认名称(德文版为Tabelle1,以下示例中为TableName),但您还可以简单地命名表格的范围(TableAsRangeName);如 Excel 范围名称编辑器中的图标所示,这两者的处理方式似乎不同。

我无法从 R 中读取这些表(严格意义上的)。唯一已知的解决方法是使用 CSV 中间,或者将表转换为正常的命名范围,当您使​​用列时,这会产生令人讨厌的不可逆转的副作用单元格引用中的名称;这些将转换为 A1 表示法。

下面的例子显示了这个问题。您的里程可能会因 32/64 位 ODBC 驱动程序和 32/64 位 Java 的不同组合而有所不同

# Read Excel Tables (not simply named ranges)
# Test Computer: 64 Bit Windows 7, R 32 bit  
# My ODBC drivers are 32 bit
library(RODBC)
# Test file has three ranges
# NonTable Simple named range
# TableName Name of table 
# TableAsRangeName Named Range covering the above table
sampleFile = "ExcelTables.xlsx"
if (!file.exists(sampleFile)){
  download.file("http://www.menne-biomed.de/uni/ExcelTables.xlsx",sampleFile)
  # Or do it manually, if this fails
}
# ODBC
channel = odbcConnectExcel2007(sampleFile)
sqlQuery(channel, "SELECT * from NonTable") # Ok
sqlQuery(channel, "SELECT * from TableName") # Could not find range
sqlQuery(channel, "SELECT * from TableAsRangeName") # Could not find range
close(channel)

# gdata has read.xls, but seems not to support named regions

library(xlsx)
wb = loadWorkbook(sampleFile)
getRanges(wb) # This one fails already with "TableName" does not exist
ws = getSheets(wb)[[1]]
readRange("NonTable",ws) # Invalid range address
readRange("TableName",ws) # Invalid range address
readRange("TableAsRangeName",ws) # Invalid range address

# my machine requires 64 bit for this one; depends on your Java installation
sampleFile = "ExcelTables.xlsx"
library(XLConnect) # requires Java
readNamedRegionFromFile(sampleFile,"NonTable") # OK
readNamedRegionFromFile(sampleFile,"TableName") # "TableName" does not exist
readNamedRegionFromFile(sampleFile,"TableAsRangeName") # NullPointerException

wb <- loadWorkbook(sampleFile)
readNamedRegion(wb,"NonTable") # Ok
readNamedRegion(wb,"TableName") # does not exist
readNamedRegion(wb,"TableAsRangeName") # Null Pointer

【问题讨论】:

  • 我敢打赌,最简单的方法是返回 Excel 工作簿并创建一个新工作表,其中包含一组指向命名表单元格的简单链接(或公式)。然后告诉R 从该工作表中读取。
  • XLConnect 尚不支持 Excel 表格。此外,还不支持基于表格公式的命名范围。不过,我会对此进行调查,看看在这方面可以做些什么。
  • 感谢 Martin Studer(XLConnect 的作者)。我昨天在 XML 中进行了一些挖掘,发现表被映射到一个额外目录中的 Ranges。请在此处发布以防万一。
  • 给定链接上的 excel 文件已损坏。请检查您这边是否正常。
  • 以防万一其他人尝试这样做:您必须使用 IF(ISBLANK.. 构造来避免空单元格。

标签: r excel import


【解决方案1】:

表定义存储在 XML 中是正确的。

sampleFile = "ExcelTables.xlsx"
unzip(sampleFile, exdir = 'test')
library(XML)
tData <- xmlParse('test/xl/tables/table1.xml')
tables <- xpathApply(tData, "//*[local-name() = 'table']", xmlAttrs)
[[1]]
            id           name    displayName            ref totalsRowShown 
           "1"    "TableName"    "TableName"        "G1:I4"            "0" 
library(XLConnect)

readWorksheetFromFile(sampleFile, sheet = "ExcelTable", region = tables[[1]]['ref'], header = TRUE)
    Name Age AgeGroup
1  Anton  44        4
2 Bertha  33        3
3  Cäsar  21        2

根据您的情况,您可以在 XML 文件中搜索合适的数量。

【讨论】:

  • 我刚刚实现了与您的解决方案类似的东西,还有来自housesofstones.com/blog/2013/06/20/… 的一些额外内容,因为我担心 readWorksheetFromFile 会因为我的太大的真实文件而绊倒。
  • 一个有趣的博客。以前可以通过对底层xml文件进行一些修改来取消excel文件的密码保护。
  • 很抱歉将信用转移给马丁。我给了你一个 +1。
  • @user1609452,您的回答为我节省了很多时间。如果您的 Excel 工作簿有多个工作表怎么办?有没有办法确定您的表格存储在哪个工作表中?
【解决方案2】:

我在 XLConnect 中添加了一些对 Excel 表格的初始支持。请在https://github.com/miraisolutions/xlconnecthttps://github.com/miraisolutions/xlconnect找到github上的最新更改

下面是一个小样本:

require(XLConnect)
sampleFile = "ExcelTables.xlsx"
wb = loadWorkbook(sampleFile)
readTable(wb, sheet = "ExcelTable", table = "TableName")

请注意,Excel 表格与工作表相关联。据我所知,可以将多个具有相同名称的表关联到不同的工作表。出于这个原因,sheet-argument 到 readTable

【讨论】:

  • 看起来 RJava 存在令人讨厌的 64/32 位依赖性问题之一。我安装了工具链并定期使用它,但无法构建 xlconnect;尝试了 32 位和 64 位 R。错误:无法加载共享对象 'D:/R/R/library/rJava/libs/i386/rJava.dll':LoadLibrary 失败:%1 ist keine zulässige Win32-Anwendung。明天检查。
  • 这太好了,能够刷新和写回(/追加)到 Excel 表格有多困难?似乎无法让它工作,尝试了 writeNamedRegion()。
【解决方案3】:

后期添加:

readxl::readxl 可以读取“真实”表,当您想要读取数据帧/小标题时,这可能是最不麻烦的解决方案。

** 在@Jamzy 评论之后** 我再次尝试,无法读取命名范围。那时是假阳性还是现在是假阴性???

【讨论】:

  • 您能详细说明一下吗?我在文档中找不到任何提及。
  • 不,我没有在文档中找到,只是尝试过。另一方面,大多数其他读者不支持“真实”表的事实也没有记录。你有没有尝试过?还有其他经验吗?
猜你喜欢
  • 2021-08-01
  • 2019-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-23
  • 1970-01-01
  • 1970-01-01
  • 2017-12-31
相关资源
最近更新 更多