【问题标题】:R to Merge All Sheets From All Excel FilesR合并所有Excel文件中的所有工作表
【发布时间】:2018-07-14 14:47:50
【问题描述】:

我正在尝试合并文件夹中所有 Excel 文件中所有工作表的数据。所有工作表和所有文件都具有相同的标题和相同的数据集。我以为下面的代码会读取所有工作表,但它似乎只读取每个文件中的第一张工作表。

# This needs several other packages
# install.packages("XLConnect")
require(XLConnect)

setwd("C:/Users/Excel/Desktop/Coding/R Programming/Excel/Excel_Files/")

fpattern <- "File.*.xls*?"  # pattern for filenames
output.file <- "Test.xls"
lfiles <- list.files(pattern = fpattern)

# Read data from all sheets
lfiles %>% 
  excel_sheets() %>% 
  set_names() %>% 
  map(read_excel, lfiles = lfiles)

【问题讨论】:

  • 问题到底出在哪里?在您说问题所在之后,那里有很多代码。如果不需要,请尽量减少示例。
  • 嗯,我想我强调了这个问题,对。至少和我理解的一样。我认为就是这样: lfiles %>% excel_sheets() %>% set_names() %>% map(read_excel, lfiles = lfiles) 这似乎是从工作簿中的第一个工作表中提取数据,但不是工作簿中的所有工作表.
  • 与其他 QA 网站不同,在 SO 上,问题是可编辑的;请编辑您的问题以反映问题所在(并删除不需要的代码)。
  • 我只是想简化我的问题。
  • 好多了,谢谢。还有一个建议:readxl 包是读取 Excel 文件的“最新最好的”方式;如果你能切换到那个,你就更有可能获得帮助。

标签: r xlconnect readxl


【解决方案1】:

我认为以下内容可以满足您的需求。在此示例中,并非每个文件都具有相同的工作表或列; test2.xlsx 只有一张纸,而 test3.xlsx sheet1 没有 col3。它还标记每个文件的文件和工作表名称。

library(tidyverse)
library(readxl)

dir_path <- "~/test_dir/"         # target directory where the xlsx files are located. 
re_file <- "^test[0-9]\\.xlsx"    # regex pattern to match the file name format, in this case 'test1.xlsx', 'test2.xlsx' etc.

read_sheets <- function(dir_path, file){
  xlsx_file <- paste0(dir_path, file)
  xlsx_file %>%
    excel_sheets() %>%
    set_names() %>%
    map_df(read_excel, path = xlsx_file, .id = 'sheet_name') %>% 
    mutate(file_name = file) %>% 
    select(file_name, sheet_name, everything())
}

df <- list.files(dir_path, re_file) %>% 
  map_df(~ read_sheets(dir_path, .))

# A tibble: 15 x 5
   file_name  sheet_name  col1  col2  col3
   <chr>      <chr>      <dbl> <dbl> <dbl>
 1 test1.xlsx Sheet1         1     2     4
 2 test1.xlsx Sheet1         3     2     3
 3 test1.xlsx Sheet1         2     4     4
 4 test1.xlsx Sheet2         3     3     1
 5 test1.xlsx Sheet2         2     2     2
 6 test1.xlsx Sheet2         4     3     4
 7 test2.xlsx Sheet1         1     3     5
 8 test2.xlsx Sheet1         4     4     3
 9 test2.xlsx Sheet1         1     2     2
10 test3.xlsx Sheet1         3     9    NA
11 test3.xlsx Sheet1         4     7    NA
12 test3.xlsx Sheet1         5     3    NA
13 test3.xlsx Sheet2         1     3     4
14 test3.xlsx Sheet2         2     5     9
15 test3.xlsx Sheet2         4     3     1

【讨论】:

  • 你好。这看起来很接近,但我的设置中的某些内容必须与您的不同。我得到了这个结果: df # A tibble: 0 x 2 # ... with 2 variables: file_name , sheet_name 这是干什么用的? re_file
  • re_file 是正则表达式模式list.files() 用于获取目录中的 xlsx 文件名。在这个例子中,它匹配任何与命名格式“test[single digit].xlsx”匹配的文件,但看起来你可以只做re_pattern = 'File.*\\.xlsx'.id = 'sheet_name' 只是将工作表名称添加为一列。您可以将“sheet_name”替换为您想要的列。这是一个可选参数。
  • 我不断得到这个结果:# A tibble: 0 x 0 我猜它没有检测到任何文件。以前,我得到每个文件的第一张,但现在我什么都没有。呃。
  • 正则表达式匹配文件名格式可能有问题。只调用list.files(dir_path, re_file) 会列出您期望的文件吗?
  • 如果 list.files() 调用按预期工作,然后尝试使用只有一个文件名的 read_sheets() 函数:read_sheets('~/sample/path/', 'sample_file_name.xlsx') 看看是否按预期工作。
【解决方案2】:

这是一个仅使用 R 基函数和 XLConnect 的示例:

library(XLConnect)

testDir <- "Excel_Files"

re_file <- ".+\\.xls.?"
testFiles <- list.files(testDir, re_file, full.names = TRUE)

# This function rbinds in a single dataframe
# the content of multiple sheets in the same workbook
# (assuming that all the sheets have the same column types)
rbindAllSheets <- function(file) {
  wb <- loadWorkbook(file)
  sheets <- getSheets(wb)
  do.call(rbind,
          lapply(sheets, function(sheet) {
            readWorksheet(wb, sheet)
          })
  )
}

# Getting a single dataframe for all the Excel files
result <- do.call(rbind, lapply(testFiles, rbindAllSheets))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-06
    • 1970-01-01
    相关资源
    最近更新 更多