按ID生成所有层级产品组合(R语言技术需求)
问题需求
给定如下包含客户ID与对应产品的tibble数据集:
library(tibble) df <- tibble(ID = c(1,1,1,2,2,3,3,4), prod = c("Prod1", "Prod2", "Prod3", "Prod1", "Prod4", "Prod3", "Prod5", "Prod2"))
需要按ID分组,生成每个ID下产品的所有非空组合(包含1个产品的单元素组合,到n个产品的全组合,n为该ID的唯一产品数量),最终输出格式如下:
df_results <- tibble(ID = c(1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4), combo = c("Prod1", "Prod2", "Prod3", "Prod1|Prod2", "Prod1|Prod3", "Prod2|Prod3", "Prod1|Prod2|Prod3", "Prod1", "Prod4", "Prod1|Prod4", "Prod3", "Prod5", "Prod3|Prod5", "Prod2"))
解决方案
结合dplyr的分组功能与purrr的迭代函数,搭配combn生成组合,具体实现代码如下:
library(dplyr) library(purrr) df_results <- df %>% # 按ID分组,提取每个ID对应的唯一产品列表 group_by(ID) %>% summarise(prod_list = list(unique(prod)), .groups = "drop") %>% # 为每个产品列表生成所有非空组合 mutate(combo = map(prod_list, function(x) { # 迭代生成1到产品总数长度的所有组合,并用|拼接 map(seq_along(x), ~combn(x, ., paste, collapse = "|")) %>% unlist() })) %>% # 展开组合列,转换为每行一个组合的结构 unnest(combo) %>% # 移除中间辅助列(可选操作) select(-prod_list)
代码说明
- 分组提取唯一产品:通过
group_by+summarise将每个ID对应的去重产品存入列表列,避免重复处理相同产品; - 生成全量组合:
- 用
seq_along(x)获取1到当前ID产品数量的序列,对应要生成的组合长度; combn函数生成指定长度的所有组合,并直接用|拼接成字符串;- 用
map迭代所有长度后,通过unlist合并成单一向量;
- 用
- 展开结果:
unnest(combo)将列表类型的组合列展开为多行,得到目标格式。
运行上述代码后,输出结果与示例完全匹配。
内容的提问来源于stack exchange,提问作者Jirka Čep
相关产品推荐
相关产品推荐

