R语言按ID分组生成名称组合 拼接名称并对数值列求和
R实现按ID分组生成名称非空组合并汇总数值
核心逻辑:按id字段拆分分组后,对每个分组生成所有长度≥1的行索引组合,针对每个组合拼接名称字段、累加对应的数值字段即可,两种常用实现方式如下:
方法1:tidyverse 实现(代码简洁易读)
适合日常用tidyverse生态处理数据的场景:
library(dplyr) library(purrr) # 加载示例数据 df <- structure(list(id = c("a", "a", "b", "b"), name = c("bob", "jane", "mark", "brittney"), number = c(1L, 2L, 1L, 2L), value = c(1L, 2L, 1L, 2L)), class = "data.frame", row.names = c(NA, -4L)) res <- df %>% group_by(id) %>% group_modify(~{ n <- nrow(.x) map_dfr(seq_len(n), function(k){ # 生成选k个元素的所有组合 combn(n, k, simplify = FALSE) %>% map_dfr(function(idx){ data.frame( name = paste(.x$name[idx], collapse = ", "), number = sum(.x$number[idx]), value = sum(.x$value[idx]) ) }) }) }) %>% ungroup()
运行后输出和需求给出的预期结果完全一致:
# A tibble: 6 × 4 id name number value <chr> <chr> <int> <int> 1 a bob 1 1 2 a jane 2 2 3 a bob, jane 3 3 4 b mark 1 1 5 b brittney 2 2 6 b mark, brittney 3 3
方法2:基础R实现(无第三方包依赖)
不需要安装任何扩展包,直接运行即可得到结果:
# 加载示例数据 df <- structure(list(id = c("a", "a", "b", "b"), name = c("bob", "jane", "mark", "brittney"), number = c(1L, 2L, 1L, 2L), value = c(1L, 2L, 1L, 2L)), class = "data.frame", row.names = c(NA, -4L)) # 按id拆分数据分组处理 df_grouped <- split(df, df$id) res_list <- lapply(df_grouped, function(sub_df){ n <- nrow(sub_df) do.call(rbind, lapply(seq_len(n), function(k){ all_comb <- combn(n, k, simplify = FALSE) do.call(rbind, lapply(all_comb, function(idx){ data.frame( id = sub_df$id[1], name = paste(sub_df$name[idx], collapse = ", "), number = sum(sub_df$number[idx]), value = sum(sub_df$value[idx]) ) })) })) }) res <- do.call(rbind, res_list) rownames(res) <- NULL
- 补充说明:如果数据中存在name为空值/空字符串的行,可以在分组处理前先过滤掉这类行,避免无效组合进入结果。
内容的提问来源于stack exchange,提问作者BHudson
相关产品推荐
相关产品推荐

