我想创建一个能够纠正一些输入错误的算法。在我的例子中,我有一个包含以下变量的数据框,例如:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="checkbox" name="menubar" id="d1">
<label for="d1">Open 1</label>
<input type="checkbox" name="menubar" id="d2">
<label for="d2">Open 2</label>
<input type="checkbox" name="menubar" id="d3">
<label for="d3">Open 3</label>
<div class="d1"><div class="hi">Lorem ipsum dolor.</div></div>
<div class="d2">Lorem ipsum dolor sit amet.</div>
<div class="d3">Lorem ipsum dolor sit amet, consectetur adipisicing.</div>
解释firts变量:id_number是每个公民的身份证明,但并未显示出来。源只提供中间数字。
我想构建一个概率算法,能够指示或说明具有相同中间id_number的两个公民是相同还是不同的公民。
例如,在732组中,Maria dosSantosMagalhães和MariaSantosMagalhães很可能是同一个公民。在 * 329 组中,这两个公民具有很高的不同性。
第三组更有意思,Paulo Silva da Fonseca和Wagner Silva Junior不是同一个公民,但Paulo Silva da Fonseca和Paulo Silva Fonseca很可能是同一个公民
一些想法?
答案 0 :(得分:3)
以下是使用adist
和dplyr
包的解决方案。为了示例,我稍微更改了您的data.frame,添加了de Fonseca
。
首先,我们重新创建您的数据:
data <- read.table(text="
id_number;name
123;Maria dos Santos Magalhães
123;Maria Santos Magalhães
329;Lucas Barbosa
329;Danilo Carvalho
732;Paulo Silva de Fonseca
732;Paulo Silva da Fonseca
732;Wagner Silva Junior
732;Paulo Silva Fonseca", h=T, sep=";")
以下是将在每个id_number
组上调用的函数。它使用adist
和Levenshtein距离计算距离矩阵。然后,如果找到重复项,低于某个thres
,我们将返回所有(但第一个)相似的名称。它们将被删除,请注意-
。如果没有找到重复项,我们将返回组中的所有索引,以便不删除任何内容。
library(dplyr)
possible_duplicates <- function(ch, thresh=5) {
# calculate Levenshtein distance
d <- ch %>% adist()
# finds possible duplicates
# (0 is for perfect match, we dont want them)
# (above thres is fine, you will need to adjust this)
dup <- which(d != 0 & d < thresh, arr.ind=TRUE) %>%
as.numeric() %>% unique() %>% sort()
# case where duplicates where found, all but the first are removed
if (length(dup)>1)
-dup[-1]
# no duplicate we won't slice then
else
seq_along(ch)
}
以下是使用它的管道:我们首先group_by
id_number
,我们在每个组中应用possible_duplicate
函数,该结果用于slice
- 。
data %>%
group_by(id_number) %>%
slice(possible_duplicates(name)) %>%
ungroup()
Source: local data frame [5 x 2]
id_number name
(int) (fctr)
1 123 Maria dos Santos Magalhães
2 329 Lucas Barbosa
3 329 Danilo Carvalho
4 732 Paulo Silva de Fonseca
5 732 Wagner Silva Junior
如果您想要更严格的阈值(默认为5),您可以:
data %>%
group_by(id_number) %>%
slice(possible_duplicates(name, 2)) %>%
ungroup()
Source: local data frame [7 x 2]
id_number name
(int) (fctr)
1 123 Maria dos Santos Magalhães
2 123 Maria Santos Magalhães
3 329 Lucas Barbosa
4 329 Danilo Carvalho
5 732 Paulo Silva de Fonseca
6 732 Wagner Silva Junior
7 732 Paulo Silva Fonseca
这是你想要的吗?