如何在R中搜索多列每行的值并基于关联项分组?
解决R语言中基于多属性连通性的分组问题
嘿,作为R新手碰到这种“只要任意一项属性相同就归为一组”的需求确实有点懵,不过别担心,这个问题本质是连通分量分组,用图论工具就能轻松搞定!
先确认下你的原始数据(我帮你补全了格式,假设C列是缺失值):
df <- data.frame( person_ID = c(11,12,13,14,15), city = c("chicago", "Denver", "atlanta", "chicago", "new-york"), A = c(1,1,2,1,2), B = c("AA", "AA", "BB", "AA", "BB"), C = c(NA, NA, NA, NA, NA) )
核心思路
我们可以把每个用户和他们的每个属性(city、A、B、C)看作图里的节点,只要用户和某个属性有关联,就画一条边。最后,连通在一起的所有用户就属于同一组——比如用户13和15都关联了“2”和“BB”,所以他们在同一个连通分量里。
具体实现步骤
我推荐用igraph包来处理图的连通性,操作简单高效:
- 安装并加载
igraph包
if (!require(igraph)) install.packages("igraph") library(igraph)
- 把宽格式数据转成“用户-属性”的长格式
这一步是为了建立用户和属性的关联关系:
library(tidyr) # 用tidyr做格式转换 long_df <- pivot_longer(df, cols = c(city, A, B, C), names_to = "attribute", values_to = "value", values_drop_na = TRUE) # 自动忽略缺失的属性值
- 构建图并计算连通分量
# 用用户ID和属性值构建无向图 user_attr_graph <- graph_from_data_frame(long_df[, c("person_ID", "value")], directed = FALSE) # 提取连通分量,每个分量对应一个组 group_components <- components(user_attr_graph)
- 把分组结果合并回原始数据框
# 给每个用户分配组编号 df$group <- group_components$membership[as.character(df$person_ID)] # 如果想把组编号换成你例子里的自定义名称(比如AA、BB),可以这样改: df$group <- dplyr::case_when( df$group == 1 ~ "AA", df$group == 2 ~ "BB", TRUE ~ as.character(df$group) # 处理更多组的情况 )
最终结果
运行完上面的代码后,你的数据框会变成:
person_ID city A B C group 1 11 chicago 1 AA <NA> AA 2 12 Denver 1 AA <NA> AA 3 13 atlanta 2 BB <NA> BB 4 14 chicago 1 AA <NA> AA 5 15 new-york 2 BB <NA> BB
完全符合你想要的分组规则!
补充说明
- 如果你的C列有实际值,这个方法会自动识别,只要用户和其他用户共享任意属性(city/A/B/C),就会被分到同一组。
- 如果你不想用
igraph,也可以用递归的方式实现,但igraph的代码更简洁,适合新手快速上手。
内容的提问来源于stack exchange,提问作者Famrin
相关产品推荐
相关产品推荐

