如何基于列名分类规则计算DataFrame的行合计?
按分类规则合并DataFrame列的高效方案
核心思路
用分类映射表关联子列和目标主列,后续新增同类别列只需要更新映射表,彻底告别一堆if语句。
具体实现
1. 定义分类映射
用命名向量存储映射关系,键是需要合并的子列名,值是对应的目标主列名:
category_map <- c( Facebook = "Social", Instagram = "Social", # 后续新增同类别列直接在这里追加 Newspaper = "Print" )
注意:主列(比如Social、Print)不需要写在映射的键中,它们本身就是最终要保留的列。
2. 基础R实现
先提取所有需要保留的主列,再将每个子列的值累加到对应主列,最后移除子列:
# 获取所有主列:原表中不在映射里的列 + 映射的目标列 main_cols <- unique(c(names(df_media)[!names(df_media) %in% names(category_map)], category_map)) # 初始化结果DataFrame df_result <- df_media[, main_cols, drop = FALSE] # 遍历映射表,累加子列到对应主列 for (sub_col in names(category_map)) { main_col <- category_map[sub_col] df_result[[main_col]] <- df_result[[main_col]] + df_media[[sub_col]] } # 查看最终结果 df_result
3. dplyr简洁实现
如果习惯用tidyverse工具链,代码会更清爽:
library(dplyr) library(tidyr) # 给每列分配对应的分类标签 col_categories <- ifelse(names(df_media) %in% names(category_map), category_map[names(df_media)], names(df_media)) # 按行、按分类求和并重构宽表 df_result <- df_media %>% mutate(row_id = row_number()) %>% # 添加行号避免跨行求和 pivot_longer(-row_id, names_to = "col", values_to = "value") %>% mutate(category = col_categories[col]) %>% group_by(row_id, category) %>% summarise(total = sum(value), .groups = "drop") %>% pivot_wider(names_from = category, values_from = total) %>% select(-row_id) df_result
测试结果
用你提供的测试数据运行后,结果如下:
TV Display Social Print 1 200 30 50 110 2 500 33 52 112 3 700 47 54 114 4 1000 55 56 116
完全符合需求:Social列是原Social与Facebook的和,Print列是原Print与Newspaper的和,其余列保持不变。
扩展性说明
后续如果新增同类别列(比如TikTok属于Social),只需要在category_map中追加一行TikTok = "Social",代码无需任何修改,直接运行就能自动完成合并,灵活性拉满。
内容的提问来源于stack exchange,提问作者setX
相关产品推荐
相关产品推荐

