| import_xlsx | R Documentation |
A high-performance function for importing data from one or multiple Excel
files into data.table format, with fine-grained control over source
tracking columns, sheet selection, row skipping, multi-row headers, and
optional parallel reading across (file, sheet) pairs.
Performance characteristics:
excel_sheets() called exactly once per file (cached).
The real cost of an Excel import is read_excel() parsing,
which is single-threaded C++ and not affected by the
data.table thread pool. The flat (file x sheet) task list is
therefore read in parallel across processes when
workers > 1: a fork pool on Unix/macOS, a PSOCK cluster on
Windows. The cluster / fork pool is always torn down on exit.
setDT() converts tibbles in-place — zero vector copies.
Tracking columns injected via := on small per-sheet tables
before the single final rbindlist.
The final rbindlist uses the ambient data.table thread
pool; tune it globally with setDTthreads if
needed. Workers are pinned to a single thread during the read phase
so parallel processes do not oversubscribe cores.
import_xlsx(
file,
combine = TRUE,
sheet = NULL,
skip = 0L,
header_rows = 1L,
header_sep = "_",
header_fill = "auto",
file_col = "excel_name",
sheet_col = "sheet_name",
workers = 1L,
verbose = FALSE,
on_error = "stop",
...
)
file |
Non-empty |
combine |
|
sheet |
Positive |
skip |
Non-negative |
header_rows |
Positive |
header_sep |
|
header_fill |
How merged header cells are resolved when
|
file_col |
|
sheet_col |
|
workers |
|
verbose |
|
on_error |
|
... |
Additional arguments forwarded to
|
Multi-row headers. Many hand-made workbooks have a title row and a header spread over several rows with merged cells, e.g.
row 1 Growth test records row 2 ID | Breed | Weight (kg) | Backfat (mm) row 3 | | Start | End | P2 | Loin row 4 A001 | Duroc | 28.5 | 102.3 | 11.2 | 56.1
import_xlsx(f, skip = 1, header_rows = 2) returns the columns
ID, Breed, Weight (kg)_Start, Weight (kg)_End,
Backfat (mm)_P2, Backfat (mm)_Loin. The rules are:
Merged cells only store their value in their top-left cell. With
header_fill = "auto" the merged ranges are read from the
workbook itself (<mergeCell> entries of the sheet XML), and each
range is filled with its value, horizontally and vertically. Header
cells that are genuinely empty stay empty, so a column whose upper
cell is blank gets only its lower label.
Without merge information (.xls files, or
header_fill = "right"), every level except the last is filled to
the right, restarting wherever a higher level starts a new label.
Per column, empty parts and repeated parts (vertically merged
cells) are dropped and the remaining parts joined with
header_sep; line breaks inside a cell become spaces.
Columns without any header become col_<j>; duplicates are
made unique.
The header block is read as text, but the data block is read
separately, so numbers and dates keep their types (reading the whole
sheet as text would turn dates into serial numbers such as
"45296").
Completely empty data rows (spacer or trailing rows) are dropped.
Labels that are only visually spread over several columns with
"Center Across Selection" (instead of real merging) are not merges; use
header_fill = "right" for such sheets. Reading the merge
information re-scans the sheet XML once, which costs a fraction of the
import time and only happens when header_rows > 1.
combine = TRUEA data.table. Tracking columns
excel_name and/or sheet_name are prepended when their
respective file_col / sheet_col are not NULL.
combine = FALSEA named list of data.tables,
each element named "<filename>_<sheetname>". The list carries a
"source_files" attribute with the original file paths.
Files that share the same base name in different folders cannot be told
apart by file_col; a warning is issued and the labels are made
unique, so a later export_xlsx() round trip does not merge them.
# Example: Excel file import demonstrations
# Setup test files
xlsx_files <- mintyr_example(
mintyr_examples("xlsx_test") # Get example Excel files
)
# Example 1: Import and combine all sheets from all files
import_xlsx(
xlsx_files, # Input Excel file paths
combine = TRUE # Combine all sheets into one data.table
)
# Example 2: Import specific sheets separately
import_xlsx(
xlsx_files, # Input Excel file paths
combine = FALSE, # Keep sheets as separate data.tables
sheet = 2 # Only import the second sheet
)
# Example 3: Multi-row header with merged cells and a title row
# (row 1 = title, rows 2-3 = header, data from row 4)
mh_file <- mintyr_example("multiheader_test.xlsx")
import_xlsx(
mh_file,
skip = 1, # Skip the title row
header_rows = 2 # Combine two header rows into one name
)
# The last column has an empty, unmerged upper cell: it is named "Note".
# The heuristic fill would wrongly call it "Backfat (mm)_Note":
names(import_xlsx(mh_file, sheet = 1, skip = 1, header_rows = 2,
header_fill = "right"))
# Example 4: Batch import that skips unreadable files instead of stopping
bad_file <- tempfile(fileext = ".xlsx")
writeLines("not a workbook", bad_file)
res <- suppressWarnings(
import_xlsx(c(mh_file, bad_file), skip = 1, header_rows = 2, on_error = "warn")
)
unique(res$excel_name)
unlink(bad_file)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.