将Excel工作簿中的所有工作表读入R列表中,其中包含数据框。

111

我了解到可以使用XLConnect将Excel工作簿读入R中。例如,以下代码可将名为test.xls的工作簿的第一个工作表读入R中。

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

我有一个包含多个工作表的Excel工作簿。

如何将工作簿中的所有工作表导入到R的列表中,其中列表的每个元素都是给定工作表的数据框,每个元素的名称对应于Excel工作表的名称?


除了 xlconnectreadxl 包外,xlsx 包允许在 R 中操作 Excel 文件(所有工作表或仅某些工作表)。 - Cath
非常好的教程:https://dominicroye.github.io/en/2019/import-excel-sheets-with-r/ - Tung
12个回答

156

使用readxl更新的答案(2015年6月22日)

自发布此问题以来,已发布了readxl软件包。它支持xlsxlsx格式。重要的是,与其他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文件为参数,并将每个工作表作为数据框架返回到命名列表中。

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

2
太棒了,刚刚了解到readxl有一个excel_sheets方法。太好了。 - MichaelChirico
1
@user7071759 如果我理解正确的话,你只需要在“文件名”中包含路径即可。例如,read_excel_allsheets("my/path/to/file/example.xls")。 - Jeromy Anglim
2
似乎这个新的答案给了我一个列表中嵌套了一个列表,而不是一个列表中嵌套了一个数据框。 - Helen
6
我得到的是列表而不是数据框。 - J Walt
2
这个函数的简化版本如下:lapply(excel_sheets(file.path), function(x) read_excel(file.path, x))。如果您喜欢非tibble,则可以在read_excel中包装as.data.frame()。名称需要分配给它们。 - glaucon
显示剩余6条评论

46

请注意,大多数XLConnect的函数已经向量化。这意味着您可以使用一个函数调用读取所有工作表,而无需进行显式向量化:

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

使用XLConnect 0.2-0版本,lst将自动成为一个具有名称的列表。


11
对我来说,这很有效。需要(XLConnect) wb <- loadWorkbook(“excel.xlsx”) lst = readWorksheet(wb,sheet = getSheets(wb)) - Kim Stacks
3
我也是。那个解决方案对我没用,即使文件存在,我也无法找到它。 - Z_D
2
system.file() 的调用对我也没有起作用。 - Nikos Alexandris
直接使用loadWorkbook("demoFiles/mtcars.xlsx")加载工作簿,而不是使用loadWorkbook(system.file("demoFiles/mtcars.xlsx", package = "XLConnect"))。它可以正常工作。 - Qazi
这是一个密码保护的xlsx文件的最佳答案。 - its.me.adam

41

我偶然发现了这个老问题,我认为最简单的方法仍然缺失。

您可以使用rio仅用一行代码导入所有Excel工作表。

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

如果您是 tidyverse 的粉丝,可以通过在函数调用中添加 setclass 参数轻松将它们导入为 tibbles。

data_list <- import_list("test.xls", setclass = "tbl")
假设它们有相同的格式,您可以通过将rbind参数设置为TRUE来轻松地进行行绑定。
data_list <- import_list("test.xls", setclass = "tbl", rbind = TRUE)

2
rio::import_list 是一个很好的选择。它还可以导入工作簿的子集,例如 import_list("test.xls", which = c(1, 2)),这非常有用。我同意这是在这里最简单的选择。 - Danny

39

3
为保留表格名称,可以使用以下代码:df <- path %>% excel_sheets() %>% set_names() %>% map_dfr(read_excel, path = path, .id = "SheetName") - Tung
excel_sheets()不存在。 - Julien

18

由于这是阅读多个工作表的最热门问题,以下是openxlsx的解决方案:

filename <-"myFilePath"

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

11

补充Paul的回答。也可以使用以下方式连接这些表格:

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

4
使用工作表名称添加新列的细节很好! - Cristhian
我同意。根据工作表名称添加新列,具有非常好的副作用。 - KIM

8

您可以加载工作簿,然后使用lapplygetSheetsreadWorksheet来执行以下操作。

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

马丁,干得好! - ASH

6
使用readxl包来从工作簿中读取多个表格的内容,具体操作如下:
library(readxl)
library(dplyr)

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

在这里,dplyr中的bind_rows将把所有工作表中的数据行放入一个数据框中,而path_to_workbook则是您的数据所在位置:"dir/of/the/data/workbook"。


4

为了简化 @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))

3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接