You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R语言:按列值导出多数据框列表至Excel的报错解决

按公司拆分多数据表并导出Excel(兼容缺失数据场景)

场景与问题

现有三个DataFrame(DF、DF2、DF3),需要按Company列的值导出独立Excel文件:每个文件对应一家公司,包含该公司在SpreadsheetA、SpreadsheetB、SpreadsheetC三个源表中的数据。但部分公司未在所有源表中出现,原代码因数据结构不匹配报错,需实现缺失数据的源表不生成对应工作表的效果。

示例数据

DF <- data.frame(Company=c('Alpha', 'Alpha', 'Alpha', 'Beta', 'Beta', 'Gamma', 'Epsilon'),
                 Location=c('NY', 'NY', 'CHI', 'LA', 'CHI','LA', 'LA' ),
                 ID=c('1234', '1234', '1234', '5678', '5678', '2468', '2468'),
                 Charge=c(25,25,51, 60,60, 15, 15))

DF2 <- data.frame(Company=c('Alpha', 'Alpha', 'Beta', 'Beta', 'Delta', 'Delta', 'Delta'),
                  Location=c('NY', 'NY', 'CHI', 'LA', 'CHI','LA', 'LA' ),
                  ID=c('1234', '1234', '1234', '5678', '4567', '4567', '4567'),
                  Charge=c(25,25,51, 60,60, 15, 15))

DF3 <- data.frame(Company=c('Alpha', 'Alpha', 'Beta', 'Delta', 'Delta','Delta','Delta'),
                  Location=c('NY', 'NY', 'CHI', 'LA', 'CHI','LA', 'LA' ),
                  ID=c('1234', '1234', '1234', '5678', '4567', '6789', '6789'),
                  Charge=c(25,25,51, 60,60, 15, 15))

原错误代码

list(
  DF, DF2, DF3
) %>%
  purrr::set_names(paste("SpreadsheetA"), paste("SpreadsheetB"), paste("SpreadsheetC"), paste("SpreadsheetD")) %>% 
  purrr::map(~ split(.x, .x$Company)) %>%
  purrr::transpose() %>%
  purrr::iwalk(~writexl::write_xlsx(.x, file.path(path, paste0("results_", .y, ".xlsx"))))

报错原因:transpose()要求每个拆分后的列表结构完全一致,但部分公司仅在部分表中存在,导致结构不匹配。

解决方案

核心思路:先收集所有唯一公司名,对每个公司单独遍历源表,仅保留该公司有数据的表,再导出Excel(无数据的表自动跳过,不生成工作表)。

修改后代码

library(purrr)
library(writexl)

# 1. 定义数据表列表并命名(修正原代码多余的SpreadsheetD)
df_list <- list(
  SpreadsheetA = DF,
  SpreadsheetB = DF2,
  SpreadsheetC = DF3
)

# 2. 获取所有数据表中出现的唯一Company值
all_companies <- df_list %>%
  map(pull, Company) %>%
  unlist() %>%
  unique()

# 3. 遍历每个公司,筛选数据并导出
walk(all_companies, function(company) {
  # 对每个源表,筛选当前公司的数据,仅保留有数据的表
  company_data <- df_list %>%
    map(~ filter(.x, Company == company)) %>%
    keep(~ nrow(.x) > 0)
  
  # 导出Excel文件,无数据的表不会生成工作表
  if(length(company_data) > 0) {
    write_xlsx(
      company_data,
      path = file.path(getwd(), paste0("results_", company, ".xlsx"))
    )
  }
})

代码说明

  • df_list:直接给三个数据表命名为对应的源表名称,简化原代码中冗余的set_names写法。
  • all_companies:收集所有出现过的公司名,确保不会遗漏任何公司。
  • map(...) %>% keep(...):对每个源表筛选当前公司的数据,用keep过滤掉空表(无数据的表)。
  • 导出逻辑:仅当存在有效数据时才生成文件,避免空文件产生。

内容的提问来源于stack exchange,提问作者CuRious Coder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 08:17:33