Mengingat semakin banyaknya cara berbeda untuk membaca file Excel R
dan banyaknya jawaban di sini, saya pikir saya akan mencoba menjelaskan beberapa opsi yang disebutkan di sini yang berkinerja terbaik (dalam beberapa situasi sederhana).
Saya sendiri telah menggunakan xlsx
sejak saya mulai menggunakan R
, untuk inersia jika tidak ada yang lain, dan saya baru-baru ini menyadari bahwa sepertinya tidak ada informasi objektif tentang paket mana yang bekerja lebih baik.
Setiap latihan pembandingan penuh dengan kesulitan karena beberapa paket pasti menangani situasi tertentu lebih baik daripada yang lain, dan air terjun peringatan lainnya.
Karena itu, saya menggunakan kumpulan data (yang dapat direproduksi) yang menurut saya dalam format yang cukup umum (8 bidang string, 3 angka, 1 bilangan bulat, 3 tanggal):
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)
)
Saya kemudian menulis ini untuk csv dan dibuka di LibreOffice dan disimpan sebagai file .xlsx, maka mengacu 4 paket yang disebutkan di thread ini: xlsx
, openxlsx
, readxl
, dan gdata
, menggunakan pilihan default (Saya juga mencoba versi apakah saya tentukan jenis kolom, tetapi ini tidak mengubah peringkat).
Saya tidak termasuk RODBC
karena saya menggunakan Linux; XLConnect
karena tampaknya tujuan utamanya bukanlah membaca dalam satu lembar Excel tetapi mengimpor seluruh buku kerja Excel, jadi untuk menempatkan kudanya dalam perlombaan hanya pada kemampuan membaca tampaknya tidak adil; dan xlsReadWrite
karena tidak lagi kompatibel dengan versi saya R
(sepertinya telah dihapus).
Saya kemudian menjalankan benchmark dengan NN=1000L
dan NN=25000L
(mengatur ulang seed sebelum setiap deklarasi di data.frame
atas) untuk memungkinkan perbedaan sehubungan dengan ukuran file Excel. gc
terutama untuk xlsx
, yang saya temukan terkadang dapat membuat penyumbatan memori. Tanpa basa-basi lagi, berikut hasil yang saya temukan:
File Excel 1.000 Baris
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
Begitu readxl
pula pemenangnya, dengan openxlsx
kompetitif dan gdata
pecundang yang jelas. Mengambil setiap ukuran relatif terhadap minimum kolom:
# 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
Kami melihat favorit saya sendiri, xlsx
60% lebih lambat dari readxl
.
File Excel 25.000 Baris
Karena jumlah waktu yang dibutuhkan, saya hanya melakukan 20 pengulangan pada file yang lebih besar, jika tidak perintahnya identik. Berikut data mentahnya:
# 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
Berikut data relatifnya:
# 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
Begitu readxl
pula pemenangnya dalam hal kecepatan. gdata
lebih baik lakukan sesuatu yang lain untuk itu, karena sangat lambat dalam membaca file Excel, dan masalah ini hanya diperburuk untuk tabel yang lebih besar.
Dua kekurangannya openxlsx
adalah 1) metode lainnya yang ekstensif ( readxl
dirancang untuk melakukan hanya satu hal, yang mungkin merupakan bagian dari mengapa itu begitu cepat), terutama write.xlsx
fungsinya, dan 2) (lebih merupakan kelemahan untuk readxl
) col_types
argumen readxl
hanya (sebagai dari tulisan ini) menerima beberapa tidak standar R
: "text"
bukannya "character"
dan "date"
bukannya "Date"
.