Учитывая распространение различных способов чтения файла Excel в R
и множество ответов здесь, я подумал, что попытаюсь пролить свет на то, какие из упомянутых здесь вариантов работают лучше всего (в нескольких простыхситуации).
Я сам использовал xlsx
с тех пор, как начал использовать R
, для инерции, если ничего другого, и недавно я заметил, что нет никакой объективной информации о том, какой пакет работает лучше.
Любое упражнение по сравнительному анализу сопряжено с трудностями, поскольку некоторые пакеты наверняка справятся с определенными ситуациями лучше, чем другие, и с водопадом других предостережений.
Тем не менее, я использую (воспроизводимо) набор данных, который, как мне кажется, имеет довольно распространенный формат (8 строковых полей, 3 числовых, 1 целое, 3 даты):
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)
)
Затем я записал это в csv, открыл в LibreOffice и сохранил какфайл .xlsx, а затем протестировал 4 пакета, упомянутых в этой теме: xlsx
, openxlsx
, readxl
и gdata
, используя параметры по умолчанию (Я также попробовал версию о том, указывать ли я типы столбцов или нет, но это не изменило рейтинг).
Я исключаю RODBC
, потому что я нахожусь в Linux;XLConnect
, поскольку кажется, что его основная цель - не чтение в отдельных листах Excel, а импорт целых рабочих книг Excel, поэтому несправедливо ставить своего гонщика в гонку только на его способности к чтению;и xlsReadWrite
, потому что он больше не совместим с моей версией R
(кажется, она была прекращена).
Затем я провел тесты с NN=1000L
и NN=25000L
(сбрасывая начальное число перед каждымобъявление data.frame
выше) для учета различий в размере файла Excel.gc
в первую очередь для xlsx
, который я иногда обнаруживал, может создавать засорения памяти.Без лишних слов, вот результаты, которые я нашел:
1000-рядный файл Excel
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
Итак, readxl
- победитель, с openxlsx
конкурентоспособным и gdata
чистымнеудачник.Взяв каждую меру относительно минимума столбца:
# 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
Мы видим мой собственный фаворит, xlsx
на 60% медленнее, чем readxl
.
Файл Excel с 25 000 строками
В связи с тем, что это занимает много времени, я сделал только 20 повторений для файла большего размера, в противном случае команды были идентичны.Вот необработанные данные:
# 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
Вот относительные данные:
# 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
Так что readxl
- явный победитель, когда дело касается скорости.gdata
лучше, если у вас что-то другое, потому что чтение файлов Excel мучительно медленно, и эта проблема только усугубляется для больших таблиц.
Два ничьих openxlsx
- это 1) его обширные другие методы (readxl
предназначен для выполнения только одной вещи, что, вероятно, является частью того, почему это так быстро), особенно его функция write.xlsx
, и 2) (больше недостаток для readxl
) col_types
аргумент только в readxl
(на момент написания этой статьи) принимает некоторые нестандартные R
: "text"
вместо "character"
и "date"
вместо "Date"
.