R语言合并拼写/命名不一致的分类行并对数值求和
分类列重名合并与数值求和实现方案
问题背景
现有大型数据集每行对应一个独立分类,但category分类列存在拼写错误、命名不统一问题,导致同一实际分类对应多条数据行,需要合并指定重复分类行,并对对应数值列按年份求和。
输入输出要求
- 输入数据框结构:包含
category分类列,以及2021、2022、2023三个年份数值列 - 测试数据行内容:
Grain:三年数值分别为890、900、978Dried Fruits and Veg:三年数值分别为45、55、58Dried Fruits & Veg:三年数值分别为66、74、88
- 预期输出:
Grain行数值保持不变- 两个果干类分类合并为
Dried Fruits and Veg,对应年份数值求和
原有失败代码
DF %>% mutate_at(c(2021:2023), cumsum(starts_with("Dried Fruits")))
可复现测试数据构造代码
注:原构造代码中第二列年份笔误写为2020,已按需求修正为2022
df <- data.frame( stringsAsFactors = FALSE, category = c("Grain", "Dried Fruits and Veg","Dried Fruits & Veg"), "2021" = c(890L, 45L, 66L), "2022" = c(900L, 55L, 74L), "2023" = c(978L, 58L, 88L) )
原有代码问题说明
mutate_at仅用于修改现有列值,无法实现行维度的合并汇总,分组聚合需要搭配group_by+summarise实现c(2021:2023)是按列位置索引取列,数据集总列数仅4列,该写法会直接触发下标越界错误cumsum()是逐行累计求和函数,不是分组聚合用的sum(),且不能直接在mutate_at中传入starts_with这类选择器作为函数参数
正确实现代码
方法1:按规则匹配统一分类名(适合别名有统一命名规律的场景)
library(dplyr) df %>% # 统一分类命名:所有以Dried Fruits开头的分类都映射为标准名 mutate(category = case_when( grepl("^Dried Fruits", category) ~ "Dried Fruits and Veg", TRUE ~ category )) %>% # 按统一后的分类分组,对所有数值列求和 group_by(category) %>% summarise(across(where(is.numeric), sum), .groups = "drop")
方法2:手动指定映射表(适合别名无规律、大型数据集多别名维护场景)
library(dplyr) # 维护分类别名与标准名的映射关系,新增别名直接在向量中追加即可 category_mapping <- c( "Dried Fruits & Veg" = "Dried Fruits and Veg" ) df %>% mutate(category = recode(category, !!!category_mapping)) %>% group_by(category) %>% summarise(across(where(is.numeric), sum), .groups = "drop")
运行代码得到的输出结果如下:
| category | 2021 | 2022 | 2023 |
|---|---|---|---|
| Grain | 890 | 900 | 978 |
| Dried Fruits and Veg | 111 | 129 | 146 |
注:描述中提到的2022年预期值62与两个分类对应数值求和结果(55+74=129)不符,代码按数值列实际值求和,若预期值为62请核对原始数据的数值录入是否正确。
内容的提问来源于stack exchange,提问作者somewhat_confused
相关产品推荐
相关产品推荐

