在R中去除模糊重复数据:Record Linkage适用性及实现
近似重复记录的模糊去重实现(R语言)
Record Linkage完全适用于你的近似重复去重场景,它专门用于识别不同记录是否指向同一实体,正好匹配你当前的需求。下面分别演示两种去重需求,同时说明fuzzyjoin的适用性。
先准备你的数据集
address = c("882 4N Road River NY, NY 12345", "882 - River Road NY, ZIP 12345", "123 Fake Road Boston Drive Boston", "123 Fake - Rd Boston 56789") name = c("ABC Center Building", "Cent. Bldg ABC", "BD Home 25 New", "Boarding Direct 25") my_data = data.frame(address, name)
1. 基于name和address列去重(保留2行)
使用RecordLinkage包可以系统完成实体匹配与去重:
# 安装并加载包 install.packages("RecordLinkage") library(RecordLinkage) library(dplyr) # 创建比对对象,指定name和address为匹配字段,用Jaro-Winkler算法计算相似度 rlp <- compare.dedup(my_data, strcmp = c("name", "address"), strcmpfun = jarowinkler) # 设定相似度阈值(score >= 0.7视为匹配),生成匹配簇 clusters <- cluster(rlp, threshold = 0.7) # 根据簇去重,保留每组第一行 deduped_combined <- my_data[!duplicated(clusters$cluster), ]
执行后deduped_combined会保留2行,分别对应两组近似重复记录的其中一条。
2. 仅基于address列去重
同样用RecordLinkage实现,只需调整匹配字段:
# 仅基于address创建比对对象 rlp_address <- compare.dedup(my_data, strcmp = "address", strcmpfun = jarowinkler) # 生成匹配簇(可根据address的相似度调整阈值,这里设为0.6) clusters_address <- cluster(rlp_address, threshold = 0.6) # 去重后的数据 deduped_address <- my_data[!duplicated(clusters_address$cluster), ]
如果你偏好更轻量的实现,也可以用stringdist包直接计算字符串距离来分组:
install.packages("stringdist") library(stringdist) # 计算address列的Jaro-Winkler距离矩阵(距离越小越相似) sim_matrix <- stringdistmatrix(my_data$address, method = "jw") # 设定距离阈值<=0.2(对应相似度>=0.8),找到匹配组 matches <- apply(sim_matrix <= 0.2, 1, function(x) min(which(x))) # 去重,保留每组第一行 deduped_address_light <- my_data[!duplicated(matches), ]
fuzzyjoin是否适合该需求?
fuzzyjoin完全适合,它通过模糊自连接的方式可以快速识别近似重复记录,优势是灵活易上手,适合快速验证需求:
install.packages("fuzzyjoin") library(fuzzyjoin) # 基于name和address做模糊自连接,设定距离阈值<=0.3(相似度>=0.7) fuzzy_matches <- stringdist_join(my_data, my_data, by = c("name", "address"), method = "jw", max_dist = 0.3, mode = "inner") %>% filter(row.x < row.y) # 避免重复匹配对(如1-2和2-1) # 提取匹配的行ID,分组后保留每组第一行 matched_ids <- unique(c(fuzzy_matches$row.x, fuzzy_matches$row.y)) groups <- data.frame(row_id = matched_ids, group = rep(1:2, each=2)) deduped_fuzzy <- my_data %>% mutate(row_id = row_number()) %>% left_join(groups, by = "row_id") %>% group_by(group) %>% slice(1) %>% ungroup() %>% select(-row_id, -group)
fuzzyjoin适合快速原型开发,而RecordLinkage提供更严谨的实体匹配流程(包括权重分配、聚类优化等),适合复杂场景的批量处理。
内容的提问来源于stack exchange,提问作者stats_noob
相关产品推荐
相关产品推荐

