Cluster Analysis:用户信息变更时识别唯一用户的代码扩展咨询
适配多字段唯一用户识别的修改方案
核心思路是通过行号作为临时锚点,将同一行的所有标识字段(user_id、手机号、邮箱等)关联到同一网络中,所有属于同一个真实用户的标识会自动聚到同一个连通分量内,该方案可以适配任意数量的标识字段,新增字段仅需少量调整即可。
完整可运行代码
library(tidyverse) library(igraph) # 示例数据 dat <- data.frame(user_id = c(101,102,102,103,103,106, 107, 111, 112), phone_number = c(4030201, 4030201, 4030202, 4030202, 4030203, 4030204, 4030205, 4030203, 4030206), email = c("a@gmail.com", "b@gmail.com", "c@gmail.com", "d@gmail.com", "e@gmail.com", "f@gmail.com", "g@gmail.com", "h@gmail.com", "a@gmail.com")) # 多字段唯一用户识别代码 dat_with_grp <- dat %>% # 新增行号作为临时锚点,关联同一行的所有标识 mutate(row_id = row_number() %>% as.character()) %>% # 把所有标识字段转为长格式,生成「行号-标识」的边列表 pivot_longer(cols = -row_id, names_to = "type", values_to = "id") %>% # 统一转成字符避免数值/因子类型匹配问题 mutate(id = as.character(id)) %>% # 构建无向图,行号和对应标识连边 graph_from_data_frame(directed = FALSE) %>% # 计算连通分量 components() %>% pluck(membership) %>% stack() %>% set_names(c("GRP", "id")) %>% # 过滤临时行号,仅保留原数据的标识映射关系 inner_join( dat %>% mutate(across(everything(), as.character)) %>% pivot_longer(everything(), values_to = "id"), by = "id" ) %>% # 去重后关联回原表 select(-name) %>% distinct() %>% right_join(dat %>% mutate(across(everything(), as.character)), by = c("user_id", "phone_number", "email"))
代码说明
- 适配性强:如果要新增其他标识字段(比如身份证号、设备号),不需要修改核心逻辑,只需要保证新字段在原表中即可,代码会自动纳入关联逻辑
- 结果输出:最终的
dat_with_grp会在原数据的基础上新增GRP字段,相同GRP的行属于同一个真实用户 - 兼容性好:所有标识统一转为字符类型,避免数值和因子类型的匹配错误
内容的提问来源于stack exchange,提问作者James Harrington
相关产品推荐
相关产品推荐

