Чтение всех листов в книге Excel в список R с data.frames

Я понимаю, что XLConnect можно использовать для чтения листа Excel в R. Например, это будет читать первый рабочий лист в книге под названием test.xls в R.

library(XLConnect)
readWorksheetFromFile('test.xls', sheet = 1)

У меня есть книга Excel с несколькими листами.

Как все рабочие листы в книге можно импортировать в список в R, где каждый элемент списка является data.frame для данного листа, а имя каждого элемента соответствует имени рабочего листа в Excel?


person Jeromy Anglim    schedule 18.10.2012    source источник
comment
кроме xlconnect и readxl, пакет xlsx позволяет управлять файлами Excel в R (все листы или только некоторые)   -  person Cath    schedule 25.11.2016
comment
Очень хорошее руководство: dominicroye.github.io/en/2019 / импорт-Excel-листы-с-р   -  person Tung    schedule 14.09.2019


Ответы (10)


Обновленный ответ с использованием readxl (22 июня 2015 г.)

С момента публикации этого вопроса был выпущен пакет readxl. Он поддерживает формат xls и xlsx. Важно отметить, что в отличие от других пакетов импорта Excel, он работает в Windows, Mac и Linux, не требуя установки дополнительного программного обеспечения.

Таким образом, функция для импорта всех листов в книге Excel будет:

library(readxl)    
read_excel_allsheets <- function(filename, tibble = FALSE) {
    # I prefer straight data.frames
    # but if you like tidyverse tibbles (the default with read_excel)
    # then just pass tibble = TRUE
    sheets <- readxl::excel_sheets(filename)
    x <- lapply(sheets, function(X) readxl::read_excel(filename, sheet = X))
    if(!tibble) x <- lapply(x, as.data.frame)
    names(x) <- sheets
    x
}

Это можно вызвать с помощью:

mysheets <- read_excel_allsheets("foo.xls")

Старый ответ

Основываясь на ответе, предоставленном @mnel, вот простая функция, которая принимает файл Excel в качестве аргумента и возвращает каждый лист как data.frame в именованном списке.

library(XLConnect)

importWorksheets <- function(filename) {
    # filename: name of Excel file
    workbook <- loadWorkbook(filename)
    sheet_names <- getSheets(workbook)
    names(sheet_names) <- sheet_names
    sheet_list <- lapply(sheet_names, function(.sheet){
        readWorksheet(object=workbook, .sheet)})
}

Таким образом, его можно было вызвать с помощью:

importWorksheets('test.xls')
person Jeromy Anglim    schedule 18.10.2012
comment
отлично, только что узнал, что readxl имеет excel_sheets метод. чудесно. - person MichaelChirico; 06.01.2016
comment
Как лучше всего добавить путь к файлу в эту функцию? - person jesstme; 10.01.2017
comment
@ user7071759, если я вас понимаю, тогда вы можете просто указать путь в filename. Например, read_excel_allsheets (мой / путь / к / файлу / example.xls) - person Jeromy Anglim; 10.01.2017
comment
Спасибо! Ваше решение сработало лучше, чем другие, перечисленные на этой странице. - person Charles Santana; 26.07.2017
comment
Кажется, что этот новый ответ дает мне список в списке, а не фрейм данных в списке. - person Helen; 23.03.2018
comment
@Erosennin Я не уверен; это не делает этого для меня. Я добавил код, который по умолчанию удаляет класс tibble. Возможно, эти тибетные блюда давали удивительные результаты. - person Jeromy Anglim; 26.03.2018
comment
Я получаю списки, а не фреймы данных. - person J Walt; 02.04.2018
comment
Более простой вариант этой функции - lapply(excel_sheets(file.path), function(x) read_excel(file.path, x)). Если вы предпочитаете не тиббл, просто оберните read_excel в as.data.frame(). Имена должны быть присвоены после. - person glaucon; 11.10.2018
comment
Решение tidyverse более элегантно ссылка - person xhr489; 30.03.2019
comment
привет, я попытался использовать ваш код, но при использовании xlconnect я получаю сообщение об ошибке: ›библиотека (XLConnect) Загрузка необходимого пакета: XLConnectJars Ошибка: не удалось загрузить пакет или пространство имен для 'XLConnectJars': .onLoad не удалось загрузить в loadNamespace () для 'rJava', подробности : call: fun (libname, pkgname) error: JAVA_HOME не может быть определен из ошибки реестра: не удалось загрузить пакет XLConnectJars - person Eliza R; 18.11.2019
comment
Я использовал эту функцию здесь несколько раз. Однако это вызвало некоторые проблемы при rbinding результирующих листов, поскольку пакет readxl, кажется, вставляет случайные пустые строки, что вызывает небольшую головную боль. Я изменил вашу функцию, чтобы использовать пакет xlsx, в котором нет этой проблемы. read_xlsx_allsheets <- function(filename) { sheets <- openxlsx::getSheetNames(filename) x <- lapply(sheets, function(X) openxlsx::read.xlsx(filename, sheet = X)) names(x) <- sheets x } - person hisspott; 12.12.2019

Обратите внимание, что большинство функций XLConnect уже векторизованы. Это означает, что вы можете читать все листы с помощью одного вызова функции, не выполняя явную векторизацию:

require(XLConnect)
wb <- loadWorkbook(system.file("demoFiles/mtcars.xlsx", package = "XLConnect"))
lst = readWorksheet(wb, sheet = getSheets(wb))

С XLConnect 0.2-0 lst уже будет именованным списком.

person Martin Studer    schedule 18.10.2012
comment
Для меня это работает require(XLConnect) wb <- loadWorkbook("excel.xlsx") lst = readWorksheet(wb, sheet = getSheets(wb)) - person Kim Stacks; 09.04.2014
comment
Я тоже. Ответ на решение не сработал для меня, мне не удалось найти файл, даже если он существует - person Z_D; 06.04.2015
comment
Звонок с system.file() у меня тоже не работал. - person Nikos Alexandris; 17.02.2016
comment
вместо использования loadWorkbook (system.file (demoFiles / mtcars.xlsx, package = XLConnect)) напрямую используйте loadWorkbook (demoFiles / mtcars.xlsx) для загрузки книги. Оно работает. - person Qazi; 15.04.2017
comment
Это лучший ответ для защищенного паролем xlsx - person its.me.adam; 09.07.2021

Я наткнулся на этот старый вопрос и думаю, что самый простой подход все еще отсутствует.

Вы можете использовать rio для импорта всех листов Excel с помощью всего одной строчки кода.

library(rio)
data_list <- import_list("test.xls")

Если вы поклонник tidyverse, вы можете легко импортировать их как тибблы, добавив аргумент setclass к вызову функции.

data_list <- import_list("test.xls", setclass = "tbl")

Предположим, они имеют одинаковый формат, вы можете легко связать их по строкам, установив для аргумента rbind значение TRUE.

data_list <- import_list("test.xls", setclass = "tbl", rbind = TRUE)
person j3ypi    schedule 23.03.2018
comment
rio::import_list - отличный вариант. Он также может импортировать подмножество листов, например. import_list("test.xls", which = c(1, 2)), что может быть действительно полезно. Согласен, здесь самый простой вариант. - person Danny; 15.02.2019
comment
@ Дэнни, я не знал об аргументе which. Это действительно могло пригодиться. - person j3ypi; 16.02.2019

Из официальной документации readxl (tidyverse) (изменение первой строки):

path <- "data/datasets.xlsx"

path %>% 
  excel_sheets() %>% 
  set_names() %>% 
  map(read_excel, path = path)

Подробности на: http://readxl.tidyverse.org/articles/articles/readxl-workflows.html#iterate-over-multiple-worksheets-in-a-workbook

person Paul    schedule 23.03.2018
comment
Чтобы сохранить имена листов, df <- path %>% excel_sheets() %>% set_names() %>% map_dfr(read_excel, path = path, .id = "SheetName") - person Tung; 15.05.2020

Поскольку это ответ номер один на вопрос: Прочитать многостраничный Excel, чтобы перечислить:

вот решение openxlsx:

filename <-"myFilePath"

sheets <- openxlsx::getSheetNames(filename)
SheetList <- lapply(sheets,openxlsx::read.xlsx,xlsxFile=filename)
names(SheetList) <- sheets
person Andre Elrico    schedule 18.01.2018

Вы можете загрузить рабочую книгу, а затем использовать lapply, getSheets и readWorksheet и сделать что-то вроде этого.

wb.mtcars <- loadWorkbook(system.file("demoFiles/mtcars.xlsx", 
                          package = "XLConnect"))
sheet_names <- getSheets(wb.mtcars)
names(sheet_names) <- sheet_names

sheet_list <- lapply(sheet_names, function(.sheet){
    readWorksheet(object=wb.mtcars, .sheet)})
person mnel    schedule 18.10.2012
comment
Хороший Мартин !! - person ASH; 08.09.2017

Добавление к ответу Пола. Листы также можно объединить, используя что-то вроде этого:

data = path %>% 
excel_sheets() %>% 
set_names() %>% 
map_df(~ read_excel(path = path, sheet = .x), .id = "Sheet")

Необходимые библиотеки:

if(!require(pacman))install.packages("pacman")
pacman::p_load("tidyverse","readxl","purrr")
person Nikhil Gupta    schedule 30.07.2019
comment
Хорошая деталь - добавление нового столбца с использованием имени листа! - person Cristhian; 16.05.2021
comment
Я согласен. Очень хороший побочный эффект наличия нового столбца на основе имени листа. - person KIM; 12.06.2021

Чтобы прочитать несколько листов из книги, используйте пакет readxl следующим образом:

library(readxl)
library(dplyr)

final_dataFrame <- bind_rows(path_to_workbook %>%
                              excel_sheets() %>%
                              set_names() %>%
                              map(read_excel, path = path_to_workbook))

Здесь bind_rows (dplyr) поместит все строки данных со всех листов в один фрейм данных, а path_to_workbook - это расположение ваших данных: dir / of / the / data / workbook.

person TheMI    schedule 25.05.2018

excel.link выполнит свою работу.

На самом деле мне показалось, что его проще использовать по сравнению с XLConnect (не то чтобы любой из этих пакетов так уж и сложен в использовании). Время обучения для обоих составляло около 5 минут.

Кроме того, вы можете легко найти все пакеты R, в которых упоминается слово «Excel», перейдя по адресу http://cran.r-project.org/web/packages/available_packages_by_name.html

person Contango    schedule 02.04.2014

Я попробовал описанное выше, и у меня возникли проблемы с объемом данных, из которых мне нужно было преобразовать 20 МБ Excel; поэтому вышеупомянутое не сработало для меня.

После дополнительных исследований я наткнулся на openxlsx, и этот наконец помог (и быстро) Импортировать большой файл xlsx в R?

https://cran.r-project.org/web/packages/openxlsx/openxlsx.pdf

person windyvation    schedule 23.01.2017