My questions are:
What is the fastest way to read large(ish) .xlsx Excel files into R? 10 to 200 MB xlsx files, with multiple sheets.
Can some kind of parallel processing be used, e.g. each core reading a separate sheet of a multi-sheet Excel file?
Is there any other kind of optimisation that can be performed?
What I have understood (and what I haven't) so far:
- if reading from spinning disks, as I will, parallel processing may actually slow down the reading as multiple processes try to read from the same file. However, parallel process may help with things like converting and inferring data types? Not sure how much readxl spends reading from disk (which I assume is IO bound) vs converting data types (which I guess is CPU bound).
- This may be different with SSD drives. I might copy data to an SSD drive and read from there if there's a massive improvement.
- data.table::fread speeds up the reading of text files (although I don't fully understand why) but it cannot be used for excel files - or can it?
- I understand from this answer that
readxl
tends to be faster thanopenxlsx
I am interested in tabular data only; I am not interested in the Excel formatting, nor in charts, text labels or any other kind of data.
I am possibly looking to import into tidyverse tibbles, but not necessarily. I will then need to export the tables into a Microsoft SQL Server.
Some background: I mostly use Python and am totally new to R. Reading large Excel files in Python is painfully slow. I have already seen that R's readxl
is much faster than Python's pandas
(on a 15-sheet xlsx, each sheet with 10,000 rows and 32 columns: 5.6 seconds for readxl vs 33 seconds for pandas), so that's great! I would, however, still like to understand if there is any way to make the import even faster. I can read the files with R, export them to SQL, then continue the rest of my workflow with Python reading from SQL.
I don't think converting to CSV is the best option, especially not when readxl is so much faster than Python anyway; basically converting to csv may easily take longer than the time I'd save by reading from csv rather than excel. Plus, at least with Python (I don't really know enough R to have tested this thoroughly with readxl), inferring data types works much better with xlsx than with csv.
My code (any critique or suggestion is more than welcome):
library(readxl)
library(tidyverse)
library(tictoc)
this.dir <- dirname(parent.frame(2)$ofile)
setwd(this.dir)
tic("readxl")
path <- "myfile.xlsx"
sheetnames <- excel_sheets(path)
mylist <- lapply(excel_sheets(path), read_excel, path = path)
names(mylist) <- sheetnames
toc()