Angesichts der R
Vielzahl unterschiedlicher Möglichkeiten zum Einlesen einer Excel-Datei und der Vielzahl von Antworten hier dachte ich, ich würde versuchen, etwas Licht ins Dunkel zu bringen, welche der hier genannten Optionen (in einigen einfachen Situationen) die beste Leistung erbringt.
Ich selbst habe es verwendet, xlsx
seit ich angefangen habe R
, für Trägheit, wenn nichts anderes, und ich habe kürzlich bemerkt, dass es keine objektiven Informationen darüber zu geben scheint, welches Paket besser funktioniert.
Jede Benchmarking-Übung ist mit Schwierigkeiten behaftet, da einige Pakete bestimmte Situationen mit Sicherheit besser bewältigen als andere und ein Wasserfall mit anderen Einschränkungen.
Trotzdem verwende ich einen (reproduzierbaren) Datensatz, der meiner Meinung nach in einem ziemlich gebräuchlichen Format vorliegt (8 Zeichenfolgenfelder, 3 numerische, 1 Ganzzahl, 3 Datumsangaben):
set.seed(51423)
data.frame(
str1 = sample(sprintf("%010d", 1:NN)), #ID field 1
str2 = sample(sprintf("%09d", 1:NN)), #ID field 2
#varying length string field--think names/addresses, etc.
str3 =
replicate(NN, paste0(sample(LETTERS, sample(10:30, 1L), TRUE),
collapse = "")),
#factor-like string field with 50 "levels"
str4 = sprintf("%05d", sample(sample(1e5, 50L), NN, TRUE)),
#factor-like string field with 17 levels, varying length
str5 =
sample(replicate(17L, paste0(sample(LETTERS, sample(15:25, 1L), TRUE),
collapse = "")), NN, TRUE),
#lognormally distributed numeric
num1 = round(exp(rnorm(NN, mean = 6.5, sd = 1.5)), 2L),
#3 binary strings
str6 = sample(c("Y","N"), NN, TRUE),
str7 = sample(c("M","F"), NN, TRUE),
str8 = sample(c("B","W"), NN, TRUE),
#right-skewed integer
int1 = ceiling(rexp(NN)),
#dates by month
dat1 =
sample(seq(from = as.Date("2005-12-31"),
to = as.Date("2015-12-31"), by = "month"),
NN, TRUE),
dat2 =
sample(seq(from = as.Date("2005-12-31"),
to = as.Date("2015-12-31"), by = "month"),
NN, TRUE),
num2 = round(exp(rnorm(NN, mean = 6, sd = 1.5)), 2L),
#date by day
dat3 =
sample(seq(from = as.Date("2015-06-01"),
to = as.Date("2015-07-15"), by = "day"),
NN, TRUE),
#lognormal numeric that can be positive or negative
num3 =
(-1) ^ sample(2, NN, TRUE) * round(exp(rnorm(NN, mean = 6, sd = 1.5)), 2L)
)
Ich schrieb dann diese zu csv und eröffnen in Libreoffice und speicherte es als XLSX - Datei, dann gebenchmarkt 4 der in diesem Thread erwähnten Pakete: xlsx
, openxlsx
, readxl
, und gdata
, um die Standardoptionen (Ich habe auch versucht , eine Version von , ob ich Geben Sie die Spaltentypen an, dies hat jedoch die Rangfolge nicht geändert.
Ich schließe aus, RODBC
weil ich unter Linux bin. XLConnect
weil es den Anschein hat, dass sein Hauptzweck nicht darin besteht, einzelne Excel-Tabellen zu lesen, sondern ganze Excel-Arbeitsmappen zu importieren, scheint es unfair, sein Pferd nur mit seinen Lesefähigkeiten ins Rennen zu bringen; und xlsReadWrite
weil es nicht mehr mit meiner Version von kompatibel ist R
(scheint auslaufen).
Ich habe dann Benchmarks mit NN=1000L
und NN=25000L
(Zurücksetzen des Startwerts vor jeder Deklaration der data.frame
oben genannten) ausgeführt, um Unterschiede in Bezug auf die Größe der Excel-Datei zu berücksichtigen. gc
ist in erster Linie für xlsx
, die ich manchmal gefunden habe, kann Speicher Clogs erstellen. Hier sind ohne weiteres die Ergebnisse, die ich gefunden habe:
Excel-Datei mit 1.000 Zeilen
benchmark1k <-
microbenchmark(times = 100L,
xlsx = {xlsx::read.xlsx2(fl, sheetIndex=1); invisible(gc())},
openxlsx = {openxlsx::read.xlsx(fl); invisible(gc())},
readxl = {readxl::read_excel(fl); invisible(gc())},
gdata = {gdata::read.xls(fl); invisible(gc())})
# Unit: milliseconds
# expr min lq mean median uq max neval
# xlsx 194.1958 199.2662 214.1512 201.9063 212.7563 354.0327 100
# openxlsx 142.2074 142.9028 151.9127 143.7239 148.0940 255.0124 100
# readxl 122.0238 122.8448 132.4021 123.6964 130.2881 214.5138 100
# gdata 2004.4745 2042.0732 2087.8724 2062.5259 2116.7795 2425.6345 100
So readxl
ist der Gewinner, mit openxlsx
wettbewerbsfähigem und gdata
klarem Verlierer. Nehmen Sie jede Maßnahme relativ zum Spaltenminimum:
# expr min lq mean median uq max
# 1 xlsx 1.59 1.62 1.62 1.63 1.63 1.65
# 2 openxlsx 1.17 1.16 1.15 1.16 1.14 1.19
# 3 readxl 1.00 1.00 1.00 1.00 1.00 1.00
# 4 gdata 16.43 16.62 15.77 16.67 16.25 11.31
Wir sehen meinen eigenen Favoriten, xlsx
ist 60% langsamer als readxl
.
Excel-Datei mit 25.000 Zeilen
Aufgrund des Zeitaufwands habe ich nur 20 Wiederholungen für die größere Datei durchgeführt, ansonsten waren die Befehle identisch. Hier sind die Rohdaten:
# Unit: milliseconds
# expr min lq mean median uq max neval
# xlsx 4451.9553 4539.4599 4738.6366 4762.1768 4941.2331 5091.0057 20
# openxlsx 962.1579 981.0613 988.5006 986.1091 992.6017 1040.4158 20
# readxl 341.0006 344.8904 347.0779 346.4518 348.9273 360.1808 20
# gdata 43860.4013 44375.6340 44848.7797 44991.2208 45251.4441 45652.0826 20
Hier sind die relativen Daten:
# expr min lq mean median uq max
# 1 xlsx 13.06 13.16 13.65 13.75 14.16 14.13
# 2 openxlsx 2.82 2.84 2.85 2.85 2.84 2.89
# 3 readxl 1.00 1.00 1.00 1.00 1.00 1.00
# 4 gdata 128.62 128.67 129.22 129.86 129.69 126.75
So readxl
ist der klare Gewinner, wenn es um Geschwindigkeit geht. gdata
Es ist besser, etwas anderes zu tun, da das Lesen von Excel-Dateien schmerzhaft langsam ist und dieses Problem nur bei größeren Tabellen noch verstärkt wird.
Zwei Draws von openxlsx
sind 1) seine umfangreichen anderen Methoden ( readxl
ist darauf ausgelegt, nur eine Sache zu tun, was wahrscheinlich ein Teil dessen ist, warum es so schnell ist), insbesondere seine write.xlsx
Funktion, und 2) (eher ein Nachteil für readxl
) das col_types
Argument in readxl
nur (as dieses Schreibens) akzeptiert einige nicht standardmäßige R
: "text"
anstelle von "character"
und "date"
anstelle von "Date"
.