2013-07-16 31 views
5

Um "doppelte" schließen Anfrage zu vermeiden: Ich weiß, wie Excel benannte Bereiche lesen; Beispiele finden Sie im folgenden Code. Hier geht es um "echte" Tabellen in Excel.Lesen Sie Excel-Tabellen, nicht einfach benannte Bereiche

Excel2007 und später haben das nützliche Konzept von Tabellen: Sie können Bereiche in Tabellen umwandeln und Ärger beim Sortieren und Umordnen vermeiden. Wenn Sie eine Tabelle in einem Excel-Bereich erstellen, erhält sie einen Standardnamen (Tabelle1 in der deutschen Version, TableName im folgenden Beispiel), Sie können aber auch einfach den Bereich der Tabelle benennen (TableAsRangeName); Wie durch die Symbole im Excel-Bereichsnamen-Editor angezeigt, scheinen diese beiden Elemente unterschiedlich behandelt zu werden.

Ich konnte diese Tabellen (im engeren Sinne) nicht von R lesen. Die einzige bekannte Problemumgehung ist die Verwendung von CSV-Zwischenspeicher oder das Konvertieren der Tabelle in einen normalen benannten Bereich, der bei der Verwendung unangenehme irreversible Nebenwirkungen hat Spaltennamen in Zellbezügen; Diese werden in die A1-Notation konvertiert.

Das folgende Beispiel zeigt das Problem. Sie Meilenzahl kann mit verschiedenen Kombinationen von 32/64 Bit ODBC-Treiber und 32/64 bit 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 
+0

Meine Wette ist, dass der einfachste Weg ist, zurück zur Excel-Arbeitsmappe zu gehen und ein neues Blatt zu erstellen, das einen einfachen Satz von Verknüpfungen (oder Formeln) zu den Zellen der benannten Tabelle enthält. Dann sagen Sie 'R', um von diesem Arbeitsblatt zu lesen. –

+0

XLConnect unterstützt noch keine Excel-Tabellen. Darüber hinaus werden benannte Bereiche basierend auf Tabellenformeln noch nicht unterstützt. Ich werde jedoch darauf eingehen, um zu sehen, was an dieser Front getan werden kann. –

+0

Danke, Martin Studer (Autor von XLConnect). Gestern habe ich etwas in XML gegraben und festgestellt, dass Tabellen in einem extra Verzeichnis Bereichen zugeordnet sind. Bitte posten Sie hier, falls Sie es zur Arbeit bringen. –

Antwort

1

Ich habe eine erste Unterstützung für Excel-Tabellen in XLConnect hinzugefügt. Hier finden Sie die neuesten Änderungen auf Github bei https://github.com/miraisolutions/xlconnect

Im Folgenden wird eine kleine Probe:

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

Beachten Sie, dass Excel-Tabellen auf einem Blatt zugeordnet sind. Soweit ich sehen kann, ist es möglich, mehrere Tabellen mit demselben Namen für verschiedene Blätter zu verwenden. Aus diesem Grund gibt es ein sheet -argument zu readTable.

+0

Sieht aus, als gäbe es eines der bösen 64/32 Bit Abhängigkeitsprobleme mit RJava. Ich habe die Toolchain installiert und benutze sie regelmäßig, konnte aber keinen xlconnect bauen; versuchte sowohl 32 Bit als auch 64 Bit R. Fehler: Laden des gemeinsam genutzten Objekts 'D: /R/R/library/rJava/libs/i386/rJava.dll' fehlgeschlagen: LoadLibrary fehlgeschlagen:% 1 ist keine zulässige Win32-Anwendung. Wird morgen überprüfen. –

+0

Fast funktioniert. Wird Details zu Github melden. –

+0

Siehe https://github.com/miraisolutions/xlconnect/issues/21 und https://github.com/miraisolutions/xlconnect/issues/20 –

2

Sie sind richtig variiert, dass die Tabellendefinitionen in XML gespeichert sind.

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 

Je nach Situation, die Sie in den XML-Dateien für die entsprechenden Mengen suchen könnten.

+0

Ich hatte gerade etwas ähnliches zu deiner Lösung, mit etwas zusätzlichen Sachen von http://housesofstones.com/blog/2013/06/20/ schnell-lesen-Excel-xlsx-Arbeitsblätter-in-r-auf-jeder-Plattform/#. UeaP6417IzY weil ich befürchtete, readWorksheetFromFile stolperte über meine zu große reale Datei. –

+0

Ein interessanter Blog. Früher war das, dass Sie das Passwort entfernen konnten Schutz bei Excel-Dateien durch einige Änderungen an den zugrunde liegenden XML-Dateien – user1609452

+0

Entschuldigung für die Übertragung der Gutschrift an Martin. Ich gab Ihnen eine +1. –

0

Später Zusatz:

readxl::readxl können „echte“ Tabellen lesen und wahrscheinlich ist die am wenigsten störende Lösung, wenn Sie Datenrahmen/Tibbles lesen möchten.

** Nach @Jamzy Kommentar ** Ich versuchte es erneut und konnte nicht benannte Bereiche lesen. Falsch positiv dann oder falsch negativ jetzt ???

+0

Könnten Sie bitte näher ausführen? Ich kann in der Dokumentation keine Erwähnung finden. – Jamzy

+0

Nein, ich habe nicht in der Dokumentation gefunden, nur versucht. Auf der anderen Seite wurde die Tatsache, dass die meisten anderen Leser keine "echten" Tabellen unterstützten, ebenfalls nicht dokumentiert. Hast du es versucht? Irgendeine andere Erfahrung? –

Verwandte Themen