R语言如何计算观测值与所属分组均值差值并生成新列
R数据框按地区分组计算相对均值差值实现
需求说明
现有存储地区经济指标的数据框,包含region(地区编码)、indicator(经济指标值)两列,其中地区A、B同属第一分组,C、D同属第二分组。需要新增comparative_indicator列,计算每条观测的指标值与其所属分组指标均值的差值,衡量观测值相对分组平均水平的高低。
原始测试数据构造
region<- c('A','B','C','D','B','C') indicator <- c(100,50,10,20,102,10) df <- data.frame(region,indicator)
原始数据样例:
| region | indicator |
|---|---|
| A | 100 |
| B | 50 |
| C | 10 |
| D | 20 |
| B | 102 |
| C | 10 |
期望输出
经计算第一组指标均值为84,第二组指标均值为13.33,最终输出需满足:
| region | comparative_indicator |
|---|---|
| A | 16 |
| B | -34 |
| C | -3.33 |
| D | 6.67 |
| B | 18 |
| C | -3.33 |
实现方案
方案1:基础R实现(无依赖)
不需要安装第三方包,通过内置函数完成分组匹配、均值计算、差值推导:
# 1. 构造地区与分组的映射规则 group_mapping <- data.frame( region = c("A", "B", "C", "D"), group_id = c(1, 1, 2, 2) ) # 2. 给原数据匹配所属分组 df <- merge(df, group_mapping, by = "region") # 3. 计算各分组的指标均值 group_avg <- aggregate(indicator ~ group_id, data = df, FUN = mean) # 4. 匹配分组均值,计算相对差值 df <- merge(df, group_avg, by = "group_id", suffixes = c("", "_group_avg")) df$comparative_indicator <- round(df$indicator - df$indicator_group_avg, 2) # 5. 清理辅助列,还原原始数据顺序 df <- df[order(as.numeric(rownames(df))), c("region", "comparative_indicator")]
运行后输出结果与期望完全一致。
方案2:dplyr实现(语法简洁)
使用tidyverse生态的dplyr包可以简化分组计算逻辑,代码可读性更高:
library(dplyr) df <- df %>% mutate( # 匹配观测所属分组 group_id = case_match( region, c("A", "B") ~ 1, c("C", "D") ~ 2 ), # 按分组计算均值,直接求差值 comparative_indicator = round(indicator - mean(indicator, na.rm = T), 2), .by = group_id ) %>% # 删除分组辅助列 select(-group_id)
提示:如果后续分组规则调整,仅需要修改
case_match内的地区-分组对应关系即可;如果分组数量较多,可以单独存储分组映射表,通过left_join关联匹配,适配更复杂的分组场景。
内容的提问来源于stack exchange,提问作者Rebecca James
相关产品推荐
相关产品推荐

