Dada la proliferación de diferentes formas de leer un archivo de Excel R
y la gran cantidad de respuestas aquí, pensé en intentar aclarar cuál de las opciones mencionadas aquí funciona mejor (en algunas situaciones simples).
Yo mismo he estado usando xlsx
desde que comencé a usar R
, por inercia al menos, y recientemente noté que no parece haber ninguna información objetiva sobre qué paquete funciona mejor.
Cualquier ejercicio de evaluación comparativa está plagado de dificultades, ya que algunos paquetes seguramente manejarán ciertas situaciones mejor que otros, y una cascada de otras advertencias.
Dicho esto, estoy usando un conjunto de datos (reproducible) que creo que está en un formato bastante común (8 campos de cadena, 3 numéricos, 1 entero, 3 fechas):
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)
)
Entonces escribí esto a csv y abierto en LibreOffice y se guarda como un archivo .xlsx, a continuación, comparó 4 de los paquetes mencionados en este hilo: xlsx
, openxlsx
, readxl
, y gdata
, usando las opciones por defecto (también probé una versión de si o no, especificar tipos de columna, pero esto no cambió la clasificación).
Estoy excluyendo RODBC
porque estoy en Linux; XLConnect
porque parece que su propósito principal no es leer en hojas individuales de Excel, sino importar libros de Excel completos, por lo que poner su caballo en la carrera solo con sus capacidades de lectura parece injusto; y xlsReadWrite
porque ya no es compatible con mi versión de R
(parece haber sido eliminado).
Luego ejecuté puntos de referencia con NN=1000L
y NN=25000L
(restableciendo la semilla antes de cada declaración de lo data.frame
anterior) para permitir diferencias con respecto al tamaño del archivo de Excel. gc
es principalmente para xlsx
lo que he descubierto que a veces puede crear obstrucciones en la memoria. Sin más preámbulos, aquí están los resultados que encontré:
Archivo Excel de 1000 filas
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
También lo readxl
es el ganador, con openxlsx
competitivo y gdata
un claro perdedor. Tomando cada medida relativa al mínimo de la columna:
# 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
Vemos mi propio favorito, xlsx
es 60% más lento que readxl
.
Archivo Excel de 25.000 filas
Debido a la cantidad de tiempo que lleva, solo hice 20 repeticiones en el archivo más grande; de lo contrario, los comandos eran idénticos. Aquí están los datos sin procesar:
# 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
Aquí están los datos relativos:
# 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
También lo readxl
es el claro ganador cuando se trata de velocidad. gdata
Es mejor tener algo más a su favor, ya que es dolorosamente lento leer archivos de Excel, y este problema solo se agrava para tablas más grandes.
Dos de las características openxlsx
son 1) sus otros métodos extensos ( readxl
está diseñado para hacer solo una cosa, que probablemente sea parte de por qué es tan rápido), especialmente su write.xlsx
función, y 2) (más un inconveniente para readxl
) el col_types
argumento en readxl
solo (como de este escrito) acepta algunos no estándar R
: en "text"
lugar de "character"
y en "date"
lugar de "Date"
.