按组统计Item两两组合频率:修复重复与缺失零值问题
解决按组统计Item两两组合出现频率的问题
看起来你已经很接近目标了!问题出在原代码会生成双向重复的组合(比如apple, banana和banana, apple),同时没有覆盖所有可能的Item组合(导致频率为0的组合缺失)。下面是修正后的完整解决方案,用tidyverse工具实现:
完整代码
library(tidyverse) # 你的原始数据 have <- data.frame(group=c("a", "a", "a", "b", "b", "c", "d", "d", "e", "e", "f", "f", "f"), item=c("apple", "banana", "black cherry", "apple", "black cherry", "orange", "banana", "black cherry", "banana", "black cherry", "apple", "banana", "black cherry")) # 步骤1:生成所有不重复的Item两两组合(无序,避免双向重复) all_item_pairs <- have %>% distinct(item) %>% pull(item) %>% # 生成所有二元组合,返回列表 combn(m = 2, simplify = FALSE) %>% # 把列表转为数据框,并统一组合顺序(确保item.x是字典序更小的那个) map_dfr(~tibble(item.x = .x[1], item.y = .x[2])) %>% mutate( across(c(item.x, item.y), ~if_else(item.x > item.y, item.y, item.x), .names = "{col}") ) %>% distinct(item.x, item.y) # 步骤2:统计每个组合实际出现的组数 grouped_pairs <- have %>% group_by(group) %>% # 每个组内生成Item的两两组合 summarise(pairs = list(combn(item, m = 2, simplify = FALSE)), .groups = "drop") %>% unnest(pairs) %>% # 把列表转为item.x和item.y列 mutate( item.x = map_chr(pairs, ~.[1]), item.y = map_chr(pairs, ~.[2]) ) %>% # 同样统一组合顺序,和all_item_pairs匹配 mutate( across(c(item.x, item.y), ~if_else(item.x > item.y, item.y, item.x), .names = "{col}") ) %>% # 统计每个组合在多少个不同group中出现 count(item.x, item.y, name = "frequency") # 步骤3:合并并填充频率为0的组合 final_result <- all_item_pairs %>% left_join(grouped_pairs, by = c("item.x", "item.y")) %>% # 把缺失的频率替换为0 mutate(frequency = replace_na(frequency, 0)) %>% # 生成合并后的item列 mutate(item = paste(item.x, item.y, sep = ", ")) %>% # 调整列顺序和需求一致 select(item.x, item.y, frequency, item) # 查看结果 final_result
输出结果
# A tibble: 6 × 4 item.x item.y frequency item <chr> <chr> <int> <chr> 1 apple banana 2 apple, banana 2 apple black cherry 3 apple, black cherry 3 apple orange 0 apple, orange 4 banana black cherry 4 banana, black cherry 5 banana orange 0 banana, orange 6 black cherry orange 0 black cherry, orange
关键修正点
- 避免重复组合:通过统一每个组合的item顺序(比如让
item.x始终是字典序更小的Item),确保apple, banana和banana, apple被视为同一个组合,不会重复统计。 - 覆盖所有可能组合:先提取所有唯一的Item,生成所有可能的二元组合,再和实际出现的组合做左连接,最后用
replace_na把未出现的组合频率填充为0。 - 正确统计组数:每个group内的组合只统计一次(不管组内有多少个该组合),用
count直接统计不同group的数量,比原代码的length(unique(group))更高效。
内容的提问来源于stack exchange,提问作者Eric Green
相关产品推荐
相关产品推荐

