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

如何用dplyr优雅实现24组对应小时列的批量求和?

解决方案

针对批量按小时匹配求和的需求,推荐几种简洁优雅的实现方式:

方法1:使用dplyr的across动态处理(最简洁)

利用across选中所有.x结尾的列,匹配对应.y列求和,自动生成.tot结尾的新列:

library(dplyr)
library(stringr)

a <- tibble(s1.x=2:7, s2.x=3:8, s1.y=4:9, s2.y=5:10)

a %>%
  mutate(
    across(
      ends_with(".x"), 
      ~ . + get(str_replace(cur_column(), "\\.x$", "\\.y")),
      .names = "{str_replace(.col, '\\.x$', '.tot')}"
    )
  )
  • ends_with(".x"):筛选所有以.x结尾的小时列
  • str_replace(cur_column(), "\\.x$", "\\.y"):将当前列名的.x替换为.y,获取对应y列数据
  • .names参数:自动将新列名的.x替换为.tot

方法2:长格式转换后求和(更直观)

先将宽格式数据转成长格式,按小时分组求和后再转回宽格式,适合需要中间查看分组数据的场景:

library(tidyr)
library(dplyr)

a %>%
  # 转成长格式,提取小时数和分组(x/y)
  pivot_longer(
    everything(), 
    names_to = c("hour", "group"), 
    names_pattern = "s(\\d+)\\.(.)"
  ) %>%
  # 按小时分组求和
  group_by(hour) %>%
  summarise(tot = sum(value)) %>%
  # 转回宽格式,调整列名
  pivot_wider(
    names_from = hour, 
    values_from = tot, 
    names_prefix = "s"
  ) %>%
  rename_with(~ str_replace(., "^s", "s\\."), everything()) %>%
  # 和原数据合并
  bind_cols(a, .)

方法3:purrr循环生成新列

通过循环1到24的小时数,批量创建求和列:

library(purrr)
library(dplyr)

a %>%
  mutate(
    map_dfc(
      1:24, 
      ~ tibble(!!paste0("s", .x, ".tot") := !!sym(paste0("s", .x, ".x")) + !!sym(paste0("s", .x, ".y")))
    )
  )
  • map_dfc:将每个循环生成的单列tibble按列合并
  • !!和sym:实现字符串到列名符号的转换,动态调用列数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 16:22:17