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

如何在R语言For Loop中存储ID与名称并生成对应命名的Excel文件

解决方案

问题根源

你的代码核心问题在于遍历逻辑错误:cust_list是一个2行2列的数据框,1:length(cust_list)返回的是列数(1:2),虽然循环次数刚好等于目标行数,但索引数据的方式不够严谨,且容易在数据结构变化时出错。

修正后的For循环版本

以下代码修复了遍历逻辑,同时优化了代码可读性:

library(tidyverse)
library(janitor)
library(writexl)

df.1 <- tribble(
  ~customer_id, ~cust_nm  ,~period, ~cost1, ~cost2 ,
  'cust1', 'pizzaco', '202201', 5, 10,
  'cust2', 'sodaco','202202', 5, 10,
  'cust1', 'pizzaco', '202203', 5, 10,
  'cust2', 'sodaco', '202204', 5, 10,
)

# 用distinct()替代unique(),更符合tidyverse编码习惯
cust_list <- df.1 %>% 
  select(customer_id, cust_nm) %>% 
  distinct()

# 按数据框的行数遍历,而非列数
for (i in seq(nrow(cust_list))) {
  # 直接提取当前行的客户ID和名称,索引更清晰
  current_cust_id <- cust_list$customer_id[i]
  current_cust_nm <- cust_list$cust_nm[i]
  
  test <- df.1 %>% 
    filter(customer_id == current_cust_id) %>% 
    group_by(customer_id, cust_nm, period) %>% 
    summarise(
      cost1 = sum(cost1, na.rm = TRUE),
      cost2 = sum(cost2, na.rm = TRUE),
      total = cost1 + cost2,
      .groups = "drop"  # 显式取消分组,避免后续警告
    ) %>% 
    adorn_totals(where = 'row') 
  
  write_xlsx(test, paste0("test_", current_cust_nm, ".xlsx"))
}

更简洁的Tidyverse风格实现

如果想摆脱手动循环,可使用group_split + map2组合,无需单独创建cust_list:

library(tidyverse)
library(janitor)
library(writexl)

df.1 <- tribble(
  ~customer_id, ~cust_nm  ,~period, ~cost1, ~cost2 ,
  'cust1', 'pizzaco', '202201', 5, 10,
  'cust2', 'sodaco','202202', 5, 10,
  'cust1', 'pizzaco', '202203', 5, 10,
  'cust2', 'sodaco', '202204', 5, 10,
)

df.1 %>%
  # 按客户分组后拆分为单个数据框列表
  group_by(customer_id, cust_nm) %>%
  group_split() %>%
  # 同时遍历数据框和对应的客户名称
  map2(., map(., ~ unique(.$cust_nm)), function(data, cust_name) {
    data %>%
      group_by(period) %>%
      summarise(
        cost1 = sum(cost1, na.rm = TRUE),
        cost2 = sum(cost2, na.rm = TRUE),
        total = cost1 + cost2,
        .groups = "drop"
      ) %>%
      # 添加总计行
      add_row(
        customer_id = unique(data$customer_id), 
        cust_nm = cust_name, 
        period = "Total", 
        cost1 = sum(.$cost1), 
        cost2 = sum(.$cost2), 
        total = sum(.$total)
      ) %>%
      # 写入Excel
      write_xlsx(paste0("test_", cust_name, ".xlsx"))
  })

关键优化点

  • 用seq(nrow(cust_list))替代1:length(cust_list),确保遍历的是数据框的行数而非列数
  • 直接用$索引提取客户信息,避免复杂的矩阵式索引,提升代码可读性
  • 在summarise中添加.groups = "drop",显式取消分组,避免后续操作的潜在警告
  • 用distinct()替代unique(),更贴合tidyverse的编码规范

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 15:27:53