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

求助:用for循环结合sum_run实现多列分组滚动求和报错

批量按分组实现滚动求和的问题

我有一个包含约25个Area、45个不同时间维度变量的dataframe,已通过sum_run实现单列按Area分组的滚动求和,代码如下:

df%>%
  group_by(Area) %>%
  mutate(Measure_A_sum = sum_run(`Measure A`, k =4, na_pad = T, lag = 0))

现在想对39至71列批量执行该操作,尝试用for循环实现但持续报错,当前错误为unexpected =错误,我的循环代码如下:

for (col in 39:length(df)) {
  test <- df %>%
  group_by(Area) %>%
  mutate(paste(df[col], ' - Rolling', sep = '') = sum_run(df[col], k = 4, na_pad = T, lag = 0))

}

数据样本:

structure(list(Area = c("A", "A", 
"A", "A", "A", 
"A", "A", "A", 
"B", "B", "B", "B", "B", 
"B", "B", "B", "C", "C", "C", 
"C", "C", "C", "C", "C"), Quarter = c(2022.1, 
2022.2, 2022.3, 2022.4, 2023.1, 2023.2, 2023.3, 2023.4, 2022.1, 
2022.2, 2022.3, 2022.4, 2023.1, 2023.2, 2023.3, 2023.4, 2022.1, 
2022.2, 2022.3, 2022.4, 2023.1, 2023.2, 2023.3, 2023.4), Year = c(2021L, 
2021L, 2021L, 2022L, 2022L, 2022L, 2022L, 2023L, 2021L, 2021L, 
2021L, 2022L, 2022L, 2022L, 2022L, 2023L, 2021L, 2021L, 2021L, 
2022L, 2022L, 2022L, 2022L, 2023L), `Measure A` = c(3457L, 
3348L, 3279L, 3095L, 3155L, NA, NA, NA, 3416L, 3325L, 3248L, 
3076L, 3187L, NA, NA, NA, 2815L, 1942L, 1960L, 1863L, 2033L, 
NA, NA, NA), `Measure B` = c(NA, 
NA, NA, NA, NA, NA, NA, NA, 168L, 230L, 221L, 253L, 318L, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), `Measure C` = c(374L, 
408L, 404L, 497L, 455L, NA, NA, NA, 814L, 853L, 711L, 689L, 534L, 
NA, NA, NA, 1430L, 1335L, 1551L, 1352L, 1512L, NA, NA, NA)), row.names = c(NA, 
24L), class = "data.frame")

问题原因及解决方案

错误原因

循环代码的核心问题:

  1. mutate中直接用paste(...) = ...属于语法错误,R不允许在赋值左侧直接用表达式生成变量名,必须用动态变量名赋值方式。
  2. df[col]返回的是数据框子集,而sum_run需要向量输入,应该用df[[col]]或dplyr的.data pronoun引用列。
  3. 每次循环重新赋值test会覆盖之前的结果,需基于上一次的结果持续更新。

正确的For循环实现

# 初始化test为原始数据框
test <- df

# 获取目标列的列名(39到71列)
target_cols <- colnames(df)[39:length(df)]

for (col_name in target_cols) {
  # 生成新列名
  new_col_name <- paste0(col_name, ' - Rolling')
  # 按分组计算滚动求和并添加新列
  test <- test %>%
    group_by(Area) %>%
    mutate(!!new_col_name := sum_run(.data[[col_name]], k = 4, na_pad = TRUE, lag = 0)) %>%
    ungroup()  # 取消分组避免后续操作受影响
}

关键语法说明

  • !!new_col_name :=:!!用于解引用变量名,:=是dplyr中动态赋值的运算符,实现用变量作为新列名。
  • .data[[col_name]]:在dplyr管道中安全引用列名,避免环境变量冲突。
  • 每次循环基于test更新,保留之前添加的新列。

更高效的dplyr批量处理方式(无需循环)

推荐用dplyr::across实现批量操作,代码更简洁高效:

test <- df %>%
  group_by(Area) %>%
  mutate(across(39:last_col(),  # 选择39到最后一列
                ~sum_run(.x, k = 4, na_pad = TRUE, lag = 0),
                .names = "{col} - Rolling")) %>%  # 定义新列名格式
  ungroup()

优势

  • 无需手动循环,代码简洁易读。
  • 性能优于for循环,适合大数据集处理。
  • .names参数直接指定新列名格式,无需额外处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 06:10:58