在R中,创建一个算法来纠正输入错误

时间:2016-04-15 22:39:55

标签: r

我想创建一个能够纠正一些输入错误的算法。在我的例子中,我有一个包含以下变量的数据框,例如:

<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很可能是同一个公民

一些想法?

1 个答案:

答案 0 :(得分:3)

以下是使用adistdplyr包的解决方案。为了示例,我稍微更改了您的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组上调用的函数。它使用adistLevenshtein距离计算距离矩阵。然后,如果找到重复项,低于某个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

这是你想要的吗?