楚新元 | All in R

Welcome to R Square

用 R 批量汇总 Excel 文件里的数据

楚新元 / 2021-08-23


工作中常常遇到需要从 n 个工作簿(Workbook)中汇总数据,或者从一个工作簿中的 n 个工作表(Worksheet)中汇总数据到一张表中,而每个工作簿或工作表中的数据结构相同。如果 n 超过 3,那么我绝对不会考虑 Ctrl + CCtrl + V,一来这种方式会有操作风险,二来重复性的干同一件事一点儿也不优雅,像个机器人。下面给出优雅的实现方式,相信 n 很大的时候你会深刻体会到什么叫优雅。

加载相关 R 包

library(readxl)
library(purrr)

汇总 n 个 Excel 文件的一个 Sheet 里的数据

path = "path/to/"
path %>% 
  list.files(
    pattern = "\\.xlsx$",  # 匹配以 .xlsx 结尾的文件
    full.names = TRUE
  ) %>% 
  set_names(.) %>%
  map(
    \(x) read_excel(x, skip = 0)  # 如表头上面有 m 行是空行,则将 0 改为 m 即可
  ) %>% 
  list_rbind(
    names_to = "src"
  ) -> df

汇总一个 Excel 文件的 n 个 Sheet 里的数据

file_path = "path/to/file.xlsx"  # 这里也可以是 .xls 文件
file_path %>% 
  excel_sheets() %>% 
  set_names() %>% 
  map(
    \(x) read_excel(file_path, sheet = x)
  ) %>% 
  list_rbind(
    names_to = "src"  # 汇总数据后加入一列数据来源
  ) -> df

汇总 n 个 Excel 文件的 n 个 Sheet 里的数据

# 编写汇总 1 个 Excel 文件的 n 个 Sheet 的函数
read_xlfile = \(file_path) {
  file_path %>% 
    excel_sheets() %>% 
    set_names() %>% 
    map(
      \(x) read_excel(file_path, sheet = x)
    ) %>% 
    list_rbind(
      names_to = "sheet"  # 汇总数据后加入一列数据来源
    )
}

# 将 read_xlfile 函数作用到指定路径下的所有 Excel 文件上
path = "path/to/"
path %>%  
  list.files(
    pattern = "\\.xlsx$",  # 匹配以 .xlsx 结尾的文件
    full.names = TRUE
  ) %>% 
  set_names() %>% 
  map(read_xlfile) %>% 
  list_rbind(
    names_to = "file"  # 汇总数据后加入一列文件来源
  ) -> df

注:若文件夹里面还有子文件夹,list.files() 增加参数 recursive = TRUE

文章参考了张敬信老师的知乎博文,在此向张老师表示感谢。