Прочитайте все листы в книге Excel в список R с data.frames

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

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

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

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

12 ответов

Обновленный ответ с использованием 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')

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

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

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

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

Ты можешь использовать rio импортировать все листы Excel только с одной строкой кода.

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

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

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

От официального 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

Так как это вопрос номер один, прочитайте Excel на листе:

здесь openxlsx решение:

filename <-"myFilePath"

sheets <- openxlsx::getSheetNames(filename)
SheetList <- lapply(sheets,openxlsx::read.xlsx,xlsxFile=filename)
names(SheetList) <- sheets

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

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")

Вы можете загрузить рабочую книгу, а затем использовать 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)})

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

library(readxl)
library(dplyr)

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

Здесь bind_row (dplyr) поместит все строки данных со всех листов в один фрейм данных, а path_to_workbook будет "dir/of/the/data/workbook".

Просто для упрощения очень полезного ответа @Jeromy Anglim:

      allsheets <- sapply(readxl::excel_sheets("your_file.xlsx"), simplify = F, USE.NAMES = T,
            function(X) readxl::read_excel("your_file.xlsx", sheet = X))

Excel.link сделает работу.

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

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

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

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

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

Вот еще один подход, основанный на RDCOMClient:

      library(RDCOMClient)

dir_Path <- "D:\\Dropbox\\Reponses_Stackoverflow\\stackoverflow_294\\"
excel_File <- "test_File.xlsx"
path_Excel_File <- paste0(dir_Path, excel_File)

xlApp <- COMCreate("Excel.Application")
xlApp[["Visible"]] <- TRUE
xlWbk <- xlApp$Workbooks()$Open(path_Excel_File)
Sheets <- xlWbk$Sheets() 
nb_Sheets <- Sheets$count() 

list_DF_By_Sheet <- list()

for(l in 1 : nb_Sheets)
{
  obj_Range <- Sheets[[l]]$Range("A:B")
  val <- obj_Range$value()
  nb_Val <- length(val)
  list_Vector <- list()
  
  for(i in 1 : nb_Val)
  {
    list_Vector[[i]] <- unlist(val[[i]])
  }
  
  df_Sheet <- do.call("cbind", list_Vector)
  list_DF_By_Sheet[[l]] <- df_Sheet
}

list_DF_By_Sheet
Другие вопросы по тегам