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

如何用R批量比较两组数据中同名成对列的数值差异?

批量计算两组数据对应列的绝对差异

我有两组来自组织主数据库的数据,数据获取与聚合方式略有差异,且无法查看原始查询语句。需要逐行逐列对比两组数据的计数差异。目前通过mutate手动实现可行,但实际数据列数众多,代码冗余且低技能使用者易出错。期望有一个不依赖列位置的基础函数来实现批量处理,示例数据如下:

library(tidyverse)

eg_data1 <- data.frame(
  Group = c('RubberChickens', 'WhoopieCushions', 'FartSpray', 'Tupperware', 'Coffee', 'Bags', 'Scissors', 'Goodfellas'),
  Fall21 = c(1, 18, 38, 28, 34, 92, 34, 16) , 
  Spring22 = c(29, 45, 23, 94, 23, 19, 20, 83) , 
  Fall22 = c(26, 18, 87, 54, 96, 21, 57, 51) ,
  Spring23 = c(58, 41, 54, 92, 71, 15, 51, 84) ,
  Fall23 = c(12, 51, 49, 25, 63, 17, 80, 74))

eg_data2 <- data.frame(
  Group = c('RubberChickens', 'WhoopieCushions', 'FartSpray', 'Tupperware', 'Coffee', 'Bags', 'Scissors', 'Goodfellas'),
  Fall21 = c(1, 19, 34, 28, 33, 92, 34, 17) , 
  Spring22 = c(29, 47, 23, 96, 21, 19, 20, 82) , 
  Fall22 = c(24, 18, 86, 54, 99, 21, 53, 51) ,
  Spring23 = c(58, 43, 54, 92, 79, 15, 53, 84) ,
  Fall23 = c(13, 51, 45, 25, 66, 18, 81, 74))

方案1:用dplyr::across批量生成差异列

利用across可以批量匹配目标列,自动计算对应列的绝对差异,无需手动逐个定义:

eg_data3 <- eg_data1 %>%
  left_join(eg_data2, by = "Group") %>%
  mutate(
    # 匹配所有以Fall/Spring开头的.x列,计算与对应.y列的绝对差
    across(starts_with(c("Fall", "Spring")), 
           ~abs(.x - get(str_replace(cur_column(), "\\.x", "\\.y"))),
           .names = "Comp{col}"
           ) %>%
    # 去掉差异列名里的.x后缀
    rename_with(~str_remove(., "\\.x"), starts_with("Comp"))
  )

# 查看差异列结果
select(eg_data3, Group, starts_with("Comp"))

关键逻辑说明:

  • starts_with(c("Fall", "Spring")):精准匹配需要对比的数值列(排除Group列)
  • str_replace(cur_column(), "\\.x", "\\.y"):自动将当前.x列名替换为对应的.y列名
  • .names = "Comp{col}":为新生成的差异列统一添加Comp前缀,后续用rename_with清理冗余后缀

方案2:宽转长再合并计算(更易理解)

如果觉得列名替换逻辑复杂,可先将数据转为长格式,合并后计算差异,再转回宽格式,逻辑更直观:

# 将两组数据转为长格式
long_data1 <- eg_data1 %>%
  pivot_longer(-Group, names_to = "Period", values_to = "Value1")

long_data2 <- eg_data2 %>%
  pivot_longer(-Group, names_to = "Period", values_to = "Value2")

# 合并数据并计算绝对差异
comp_data <- long_data1 %>%
  left_join(long_data2, by = c("Group", "Period")) %>%
  mutate(CompValue = abs(Value1 - Value2))

# 转回宽格式,还原原始列结构
eg_data3_wide <- comp_data %>%
  pivot_wider(
    names_from = Period, 
    values_from = c(Value1, Value2, CompValue),
    names_glue = "{.value}{Period}"
  )

# 查看差异列结果
select(eg_data3_wide, Group, starts_with("CompValue"))

优势:

  • 无需处理.x/.y的列名后缀,步骤清晰
  • 低技能使用者更容易理解数据转换的逻辑,出错概率更低

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 11:17:48