【问题标题】:How to find a typo in a data frame and replace it如何在数据框中找到拼写错误并替换它
【发布时间】:2017-08-31 22:26:58
【问题描述】:

我有一个包含姓名、姓氏、生日和一些随机变量的数据框。假设它看起来像这样:

    BIRTH  NAME    SURNAME random_value
 1      1  Luke  Skywalker            1
 2      1  Luke  Skywalker            2
 4      2  Leia     Organa            3
 5      3   Han       Solo            7
 7      1   Ben       Solo            1
 8      5 Lando Calrissian            3
 9      3   Han       Solo            4
 10     3   Ham       Solo            4
 11     1  Luke  Wkywalker            9

如何根据BIRTHNAMESURNAME判断姓名或姓氏是否有拼写错误,然后将拼写错误替换为正确的姓名或姓氏?

例如,我们看到有两个Han Solos 的生日是3,然后还有一个Ham Solo 的生日是相同的。我希望这个算法做的是找出Ham是错误的,并用Han替换它。

如果有两个不同的拼写出现相同的次数(对于相同的BIRTH),那么选择哪一个并不重要,只要该组的所有NAMESURNAME是一样的(所以总是HamHan但不能混合为相同的BIRTH)。

所以最终的结果是这样的:

BIRTH   NAME          SURNAME random_value
    1      1  Luke  Skywalker            1
    2      1  Luke  Skywalker            2
    4      2  Leia     Organa            3
    5      3   Han       Solo            7
    7      1   Ben       Solo            1
    8      5 Lando Calrissian            3
    11     3   Han       Solo            4
    12     3   Han       Solo            4
    13     1  Luke  Skywalker            9

有没有自动化的方法来做到这一点?我的数据集很大(>3mill 行),无法手动检查。

我想我们会寻找所有具有相同出生的名字和姓氏,然后检查是否有一些仅由一个字母不同的奇异异常值或者字母的顺序被交换(Lukevs@ 987654338@)。当我们发现这样的异常值时,我们会替换它。

【问题讨论】:

  • 如果你这样总结require(data.table); setDT(df1); df1[, .N, keyby =.(BIRTH, NAME, SURNAME)]你最终得到多少条记录,最大的N值是多少?
  • 我最终得到的行数略少于 700.000 行。最大的 N 值为 24。

标签: r dataframe data-cleaning


【解决方案1】:

这是查找错别字的一种方法。 首先,定义您在问题中提到的数据框:

my_df<-data.frame(BIRTH = c(1,1,2,3,1,5,3,3,1),
       NAME = c("Luke","Luke","Leia","Han","Ben","Lando","Han","Ham","Luke"),
       SURNAME = c("Skywalker","Skywalker","Organa","Solo","Solo","Calrissian","Solo","Solo","Wkywalker"),
       random_value = c(1,2,3,7,1,3,4,4,9))

其次,创建一个新列,结合您要匹配的所有条目:

my_df$birth_and_names <- do.call(paste, c(my_df[c("BIRTH", "NAME", "SURNAME")], sep = " ")) 

三、根据字符串距离定义一个距离矩阵,使用包stringdist:

library(stringdist)
dist.matrix<-stringdistmatrix(my_df$birth_and_names,my_df$birth_and_names,method='jw',p=0.1)
row.names(dist.matrix)<-my_df$birth_and_names
names(dist.matrix)<-my_df$birth_and_names
dist.matrix<-as.dist(dist.matrix)

第四,将结果聚类并显示为树状图。

clusts<-hclust(dist.matrix,method="ward.D2")
plot(clusts)

在此处查看树状图:

现在,您想在哪里设置参数以自动组合相似结果当然取决于您,并且取决于问题。假阳性和假阴性之间通常需要权衡取舍。

对于这个例子,以 0.2 的距离切割似乎是合适的,所以:

my_df$LikelyGroup<-cutree(clusts,h=0.2)

现在my_df$LikelyGroup 是标识符列,每个人都有一个数字,即使拼写错误。

现在要命名组,找到每个名称/生日列的模式:

library(dplyr)

Mode <- function(x) {
  ux <- unique(x)
  ux[which.max(tabulate(match(x, ux)))]
}

my_df<-my_df%>%
  group_by(LikelyGroup)%>%
  mutate(Group_Birth=Mode(BIRTH),
         Group_Name=Mode(NAME),
         Group_Surname=Mode(SURNAME))

输出 my_df:

 BIRTH|NAME |SURNAME   | random_value| LikelyGroup| Group_Birth|Group_Name |Group_Surname 
------|-----|----------|-------------|------------|------------|-----------|--------------
     1|Luke |Skywalker |            1|           1|           1|Luke       |Skywalker     
     1|Luke |Skywalker |            2|           1|           1|Luke       |Skywalker     
     2|Leia |Organa    |            3|           2|           2|Leia       |Organa        
     3|Han  |Solo      |            7|           3|           3|Han        |Solo          
     1|Ben  |Solo      |            1|           4|           1|Ben        |Solo          
     5|Lando|Calrissian|            3|           5|           5|Lando      |Calrissian    
     3|Han  |Solo      |            4|           3|           3|Han        |Solo          
     3|Ham  |Solo      |            4|           3|           3|Han        |Solo          
     1|Luke |Wkywalker |            9|           1|           1|Luke       |Skywalker     

https://gist.github.com/gdmcdonald/9135ec8f7e903a0735a0b16d8cb97297的要点

【讨论】:

  • 谢谢。您能否建议任何对数据进行切片的方法,以便该方法在合理的时间内可行?如果我尝试创建一个 3mil x 3mil 大的矩阵,r 会停止响应。此外,任何建议如何,现在我有了组号,用拼写错误更改名称。
  • 我已经解决了切片问题(将使用group_by(BIRTH)。这假设生日是正确的,但我可以接受。所以我只是请求您帮助为组分配正确的名称,如果您有任何建议。
  • 嗨@Ravonrip,我已经编辑了答案以添加名称。
  • 很抱歉打扰您,但是您对分割数据以使其在合理的时间内执行有什么建议吗?我试过了,觉得就够了,但我测试的时候还不行。
  • 对于大数据,knn 聚类算法可能比分层算法效果更好。
猜你喜欢
  • 2021-11-17
  • 2019-10-22
  • 1970-01-01
  • 2018-02-11
  • 2013-10-18
  • 2023-03-12
  • 2018-09-28
  • 2022-12-07
  • 1970-01-01
相关资源
最近更新 更多