I have seen other posts that detail how to import multiple sheets from a single excel file into R, and also how to import a series of excel files that have a single sheet in each, but not the two at the same time.
I am able to make the following code work in pieces at an individual file level, but I think I may be screwing up the loop somehow in some simple way.
When I execute the loop, I only get output from the first member of the list (files[1]) instead of output from all iterations of the loop appended in the all_data list object.
Here's my code:
# name filepath of excel files to import
file_path ="..."
# load names of excel files
files = list.files(path = file_path, pattern = ".xlsx", )
# create list to store data
all_data = list()
# create function to read multiple sheets per excel file
read_excel_allsheets <- function(filename, tibble = FALSE) {
sheets <- readxl::excel_sheets(filename)
x <- lapply(sheets, function(X) readxl::read_excel(filename, sheet = X))
x <- lapply(x, as.data.frame)
names(x) <- sheets
}
# execute function for all excel files in "files"
for (i in length(files)){
filename = paste0(file_path,"/", files[i])
read_excel_allsheets(filename)
all_data = c(all_data, x)
}
I suspect I'm just making a fundamental loop mistake, but have searched around and can't find out how to fix. any help is really appreciated!
Here's an option that returns a data frame with columns for file and sheet names for each file. In this example, not every file has the same sheets or columns; test2.xlsx has only one sheet and test3.xlsx sheet1 does not have col3.
For multiple sheets within multiple Excel files, you need nested looping. Consider nested
lapply
calls. Specifically, return the appropriate object as right now it returns sheets for every call of function. Then, convertfor
tolapply
for a list of objects:Even name you all_data list by each file's basename:
Alternatively, shorten your function and use
sapply(..., ..., simplify = FALSE
) which by default names list by supplied character vector:see if something like this works for you: