R语言筛选三列分类值精确匹配行 kmodes聚类结果不符预期
需求描述
需要在数据框中定位rg1、rg2、rg3(对应B、C、D列)三个分类变量列值完全匹配的行:若某组三列值组合(例如首行的(70,71,72))在多个用户ID对应的行中存在完全一致的匹配项,则保留所有携带该组合的用户行,删除其余不满足重复匹配条件的数据。
此前尝试使用kmodes聚类实现该需求,但运行结果仅按数据框中出现频率最高的单个rg值分组排名,未达到预期效果,原有实现代码如下:
kmodes <- klaR::kmodes(mapped_df, modes= 5, iter.max = 10, weighted = FALSE) # 将聚类结果添加到主数据框 final <- mapped_df %>% mutate(cluster = kmodes$cluster)
最优实现方案
这个场景属于精确值匹配分组,不需要使用聚类算法,直接按三列值组合分组过滤即可,用dplyr可以快速实现:
核心逻辑
- 以B、C、D三个列作为分组键,聚合统计每个三值组合的出现频次
- 筛选出出现次数大于等于2的组合(即存在完全匹配的组合)
- 保留所有属于这些组合的行,其余行直接剔除
实现代码
如果只需要判断三列组合是否重复出现(不区分是否为同一用户),直接使用以下代码:
library(dplyr) final <- mapped_df %>% group_by(B, C, D) %>% # 保留出现至少2次的组合对应的所有行 filter(n() >= 2) %>% # 可选:给每个匹配的组合加唯一分组ID,取消注释即可 # mutate(match_group_id = cur_group_id()) %>% ungroup()
如果要求三列组合必须对应至少2个不同的用户ID(排除同一用户重复提交同组合数据的干扰),将统计逻辑替换为独立用户计数即可,假设用户ID列名为user_id,代码调整为:
library(dplyr) final <- mapped_df %>% group_by(B, C, D) %>% # 替换user_id为你实际的用户ID列名 filter(n_distinct(user_id) >= 2) %>% ungroup()
原有方案问题说明
kmodes是用于相似性聚类的算法,做的是模糊近似分组,会把特征值接近但不完全一致的样本归为同一类,本身就不适用于严格等值匹配的场景,这也是之前结果只按单个rg值频率分组、达不到精确匹配要求的原因。
内容的提问来源于stack exchange,提问作者Anonymous
相关产品推荐
相关产品推荐

