我有一张桌子,上面有数千个“潜在”重复人员,任务是识别这些潜在重复并为其分配一个通用ID。
我在我关心的列上使用了stringdist_inner_join,将表连接到自身上并返回所有行及其可能的匹配项。在大多数情况下,这种方法效果很好,但是我可以获得长链的比赛,最终应该将其识别为同一个人,这就是我遇到的问题。
我的示例源表可能如下所示:
systemid last_name -------- --------- 13 Samison 14 Samsun 15 Sanison
我在last_name上使用stringdist_inner_join来获得一个看起来像这样的表:
systemid.x systemid.y ---------- ---------- 13 15 14 13 15 13
但是我需要知道的是,所有这三个记录都可能是相同的,所以最终我想要这样的东西:
finalid systemid.x systemid.y ------- ---------- ---------- 13 13 15 13 14 13 13 15 13
为了更复杂,这些潜在重复项的数量可以是任意数量,并且它们之间的关系链可以是任意长度。我可能会将ID 13匹配为14,将14匹配为15,将15匹配为21,以此类推。
我也有可能解决所有这些错误,需要学习其他内容,例如compare.dedup。
答案 0 :(得分:0)
不确定这是最好的方法,但这是我所做的:
样品表:
tbl1 <- tibble(userId = c(13, 14, 15, 16, 21)
, lastName = c("Samison", "Samsun", "Sanison", "Simison", "Sumison"))
使用compare.dedup映射记录对:
mapped.tbl1 <- compare.dedup(tbl1, exclude = "userId"
, strcmp = TRUE, strcmpfun = levenshteinSim) %>%
epiWeights() %>%
epiClassify(0.7) %>%
getPairs(show = "links", single.rows = TRUE)
按我的lastName列分组,并消除重复项
mapped.tbl1 <- mapped.tbl1 %>%
group_by(lastName.2) %>%
mutate(rnk=order(order(desc(Weight)))) %>%
filter(rnk == 1)
将原始表加入映射表,并使用mutate更新userId:
tbl1 <- tbl1 %>%
left_join(mapped.tbl1, by = c("userId" = "userId.2")) %>%
mutate(
userId.2 = userId
, userId = if_else(is.na(userId.1) == FALSE, userId.1, userId)
) %>%
select(names(tbl1))