З огляду на поширення різних способів читання файлу 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
, який, як я часом виявляв, може створювати засмічення в пам'яті. Без зайвих сумнівів, ось результати, які я знайшов:
Файл Excel із 1000 рядків
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
.
25 000-рядковий файл Excel
Через кількість часу я зробив лише 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"
.