Với sự gia tăng của nhiều cách khác nhau để đọc tệp Excel R
và vô số câu trả lời ở đây, tôi nghĩ tôi sẽ cố gắng làm sáng tỏ xem tùy chọn nào được đề cập ở đây hoạt động tốt nhất (trong một vài tình huống đơn giản).
Bản thân tôi đã sử dụng xlsx
kể từ khi bắt đầu sử dụng R
, vì quán tính nếu không có gì khác và gần đây tôi nhận thấy dường như không có bất kỳ thông tin khách quan nào về gói nào hoạt động tốt hơn.
Bất kỳ bài tập đo điểm chuẩn nào cũng chứa đầy khó khăn vì một số gói chắc chắn sẽ xử lý một số tình huống tốt hơn những gói khác và một loạt các cảnh báo khác.
Điều đó nói rằng, tôi đang sử dụng tập dữ liệu (có thể tái tạo) mà tôi nghĩ là ở định dạng khá phổ biến (8 trường chuỗi, 3 số, 1 số nguyên, 3 ngày):
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)
)
Sau đó tôi viết bài này cho csv và mở cửa vào LibreOffice và lưu nó như một tập tin .xlsx, sau đó làm chuẩn 4 của gói đề cập trong chủ đề này: xlsx
, openxlsx
, readxl
, và gdata
, bằng cách sử dụng tùy chọn mặc định (Tôi cũng đã thử một phiên bản hay không tôi chỉ định loại cột, nhưng điều này không thay đổi thứ hạng).
Tôi loại trừ RODBC
vì tôi đang sử dụng Linux; XLConnect
bởi vì có vẻ như mục đích chính của nó không phải là đọc trong các trang tính Excel đơn lẻ mà là nhập toàn bộ sổ làm việc Excel, vì vậy để đưa con ngựa của nó vào cuộc đua chỉ dựa vào khả năng đọc của nó có vẻ không công bằng; và xlsReadWrite
vì nó không còn tương thích với phiên bản của tôi R
(dường như đã bị loại bỏ dần).
Sau đó, tôi chạy các điểm chuẩn với NN=1000L
và NN=25000L
(đặt lại hạt giống trước mỗi khai báo data.frame
ở trên) để cho phép sự khác biệt đối với kích thước tệp Excel. gc
là chủ yếu xlsx
, mà tôi đã tìm thấy đôi khi có thể tạo ra tắc nghẽn bộ nhớ. Không cần quảng cáo thêm, đây là kết quả tôi tìm thấy:
Tệp Excel 1.000 hàng
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
Vì vậy, readxl
là người chiến thắng, với openxlsx
cạnh tranh và gdata
một kẻ thất bại rõ ràng. Tính từng số đo so với cột tối thiểu:
# 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
Chúng tôi thấy yêu thích của riêng tôi, xlsx
chậm hơn 60% so với readxl
.
Tệp Excel 25.000 hàng
Do tốn nhiều thời gian, tôi chỉ thực hiện 20 lần lặp lại trên tệp lớn hơn, nếu không các lệnh giống hệt nhau. Đây là dữ liệu thô:
# 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
Đây là dữ liệu tương đối:
# 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
Vì vậy, readxl
là người chiến thắng rõ ràng khi nói đến tốc độ. gdata
tốt hơn hết là có thứ gì đó khác xử lý nó, vì nó rất chậm khi đọc tệp Excel và vấn đề này chỉ trầm trọng hơn đối với các bảng lớn hơn.
Hai điểm rút ra openxlsx
là 1) các phương pháp khác mở rộng của nó ( readxl
được thiết kế để chỉ làm một việc, đó có thể là một phần lý do tại sao nó nhanh như vậy), đặc biệt là write.xlsx
chức năng của nó và 2) (nhiều nhược điểm hơn readxl
) col_types
đối số readxl
chỉ (như của văn bản này) chấp nhận một số không chuẩn R
: "text"
thay vì "character"
và "date"
thay vì "Date"
.