在 R 中加入唯一 ID 有拼写错误的数据集

Posted

技术标签:

【中文标题】在 R 中加入唯一 ID 有拼写错误的数据集【英文标题】:Joining data sets in R where the unique ids have spelling mistakes 【发布时间】:2021-06-16 04:24:31 【问题描述】:

您好,我正在尝试加入两个大型数据集,每个数据集 >10000 个条目。为此,我创建了一个“唯一 ID”——全名和出生日期的组合,两者都存在。但是,数据集在 ID 中有拼写错误/不同的字符,所以当使用左连接时,很多会不匹配。我无权访问 fuzyjoin/ match,所以不能使用它来部分匹配它们。有人建议使用 adist()。我如何使用它来匹配和合并数据集或标记接近匹配的数据集?请尽可能简单,我只使用 R 几个星期! 代码示例将是惊人的

【问题讨论】:

为了让我们帮助您,请编辑您的问题以包含reproducible example。例如,要生成最小数据集,您可以使用head()subset() 或索引。然后使用dput() 给我们一些可以立即放入R 的东西。另外,请确保您知道该怎么做when someone answers your question。更多信息可以在 *** 的help center 找到。谢谢! “无权访问fuzzyjoin”是什么意思?这是否意味着我们不应该推荐 base R 之外的其他软件包? 我的工作不允许我们从 cran 安装软件包,因此只能访问它们存储在系统上的软件包。包括最常用的软件包,但并非所有内容 【参考方案1】:

您可以将它们重命名为拼写正确的名称:

df$correct_spelling <- df$incorrect_spelling

【讨论】:

杰里米回答的一个快速附录,如果您还没有一列正确的拼写,您将不得不使用 df$UniqueIDColumn[df$UniqueIDColumn == "WrongSpelling"]&lt;-"CorrectSpelling" 之类的内容更改每个拼写错误【参考方案2】:

这可能有点手动解决方案,但可能是一个基本的 R 解决方案,即查看连接字段的唯一值并使用 grep() 函数更正拼写错误的任何内容,并创建一个人行横道以合并到具有拼写错误的唯一 ID 的数据帧。这是我的意思的一个简单的例子:

假设我们有一个包含科学家及其出生年份的数据框,然后我们有第二个包含科学家姓名及其研究领域的数据框,但“姓名”列充满了拼写错误。以下是制作示例数据框的代码:

##Fake Data##
Names<-c("Jill", "Maria", "Carlos", "DeAndre") #Names
BirthYears<-c(1974, 1980, 1991, 1985) # Birthyears 
Field<-c("Astronomy", "Geology", "Medicine", "Ecology") # Fields of science
Mispelled<-c("Deandre", "Marai", "Jil", "Clarlos")# Names misspelled

##Creating Dataframes##
DF<-data.frame(Names=Names, Birth=BirthYears) # Dataframe with correct spellings
DF2<-data.frame(Names=Mispelled, Field=Field) # Dataframe with incorrect spellings we want to fix and merge

我们可以做的是使用正则表达式替换函数gsub().找到科学家姓名的正确拼写和错误拼写版本的所有唯一值

Mispelled2<-unique(DF2$Names) # Get unique values of names from misspelled dataframe
Correct<-unique(DF$Names) # Get unique values of names from correctly spelled dataframe

fix<-NULL #blank vector to save results from loop

for(i in 1:length(Mispelled2))#Looping through all unique mispelled values
  ptn<-paste("^",substring(Mispelled2[i],1,1), "+", sep="") #Creating a regular expression string to find patterns similar to the correct name
  fix[i]<-grep(ptn, Correct, value=TRUE) #Finding and saving replacement name values
#End loop

您必须想出适合您的情况所需的正则表达式,这里有一个指向如何构建正则表达式的备忘单的链接

https://rstudio.com/wp-content/uploads/2016/09/RegExCheatsheet.pdf

现在我们可以创建一个数据框,用正确的拼写来交叉拼写错误的名称,即,第 1 行将具有“Deandre”和“DeAndre”,第 2 行将具有“Jil”和“Jill”。

CWX<-data.frame(Name_wrong=Mispelled2, Name_correct=fix)

最后我们将人行横道合并到拼写错误的数据框,然后将生成的数据框合并到拼写正确的数据框

Mispelled3<-merge(DF2, CWX, by.x="Names", by.y="Name_wrong")
Joined_DF<-merge(DF, Mispelled3[,-1], by.x="Names", by.y="Name_correct")

【讨论】:

您知道是否可以使用 adist( ) 完成类似的操作,计算出编辑距离?并且只有在一定数量之外才配对? 是的,我想是的,尽管您可能正在寻找允许模糊字符串匹配的agrep()。如果你走那条路,它将与上面的代码几乎相同,除了你想在循环中使用fix[i] &lt;-agrep(pattern=ptn, x=Correct, max.distance = 2, value=TRUE)。这里的参数 max.distance 允许您指定您希望函数如何考虑近似匹配。查看文档了解更多详细信息。 如何编辑正则表达式,使其匹配开头和/或中间和/或结尾? 嗨,Beth,我认为要做这样的事情,您必须使用 if/else 语句编写自定义函数。我想我明白你想要什么......基本上,如果你的 ID 类似于“Carmen_1990_Chemistry”,并且 ID 的拼写错误版本是“Carmne_1990_Cemistry”,那么你会想要一个匹配 1990 的正则表达式。但我不是 100 %确定这就是你所追求的。如果您有一些您想要的示例数据,请发布它,我会看看是否可以为您提供自定义功能。 嗨,肖恩,基本上是的,所以如果 ID 是“deborahoziajames04/14/2000”,我希望能够将其与“oziajames04/14/2000”匹配。但如果它是“deborahozia04/14/2000”或 deborahoziajames10/14/1990,也需要能够匹配它 - 所以拼写错误的名称可能会缺少不同的部分【参考方案3】:

对于您关于以多种方式匹配的问题,我能够提出以下建议。它有点笨拙,但它适用于下面的示例数据。诀窍是对agrep() 的调用足够敏感,以不匹配部分匹配但真正不同的名称,但又足够灵活,允许部分匹配和拼写错误:

Example1<-"deborahoziajames04/14/2000"
Example2<-"Somepersonnotdeborah04/15/2002"
Example3<-"AnotherpersonnamedJames01/23/1995"
Misspelled1<-"oziajames04/14/2000"
Misspelled2<-"deborahozia04/14/2000"
Misspelled3<-"deborahoziajames10/14/1990"
Misspelled4<-"personnamedJames"

String<-c(Example1, Example2, Example3)
Misspelled<-c(Misspelled1, Misspelled2, Misspelled3, Misspelled4)

Spell_Correct<-function(String, Misspelled)
  out<-NULL
 for(i in 1:length(Misspelled))
  
    ptn_front<-paste('^', Misspelled[i], "\\B", sep="") 
    ptn_mid<-paste('\\B', Misspelled[i], "\\B", sep="") 
    ptn_end<-paste('\\B', Misspelled[i], "$", sep="")
  
      ptn<-c(ptn_front, ptn_mid, ptn_end)
    
    Nchar_M<-nchar(Misspelled[i])
    Nchar_S<-nchar(String)
    
      out_front<-agrep(pattern=ptn[1], x=String, value=TRUE, max.distance=0.3, ignore.case=TRUE, costs = c(0.6, 0.6, 0.6))
      out_mid<-agrep(pattern=ptn[2], x=String, value=TRUE, max.distance=0.3, ignore.case=TRUE, costs = c(0.6, 0.6, 0.6))
      out_end<-agrep(pattern=ptn[3], x=String, value=TRUE, max.distance=0.3, ignore.case=TRUE, costs = c(0.6, 0.6, 0.6))
      
      out_test<-list(out_front, out_mid, out_end)
      for (j in 1:length(out_test))
        if(length(out_test[j])==1)
          use_me<-out_test[j]
      
      out[i]<-use_me
 
  return(unlist(out))


Spell_Correct(String, Misspelled)

基本上,这只是通过使用循环多次重复上一个答案并调整正则表达式以尝试对agrep() 的开始、中间和结束调用。根据拼写错误的严重程度,您可能需要使用max.distancecost 参数。祝你好运。 小心, -肖恩

【讨论】:

以上是关于在 R 中加入唯一 ID 有拼写错误的数据集的主要内容,如果未能解决你的问题,请参考以下文章

在 Spark 中加入数据集

在 Spark 中加入倾斜的数据集?

使用用户定义的函数在 spark 中加入数据集时需要填充其他信息

在 Visual Studio Report Services 中加入两个数据集

在 Pandas 中加入一个数据集和 OneHotEncoder 的结果

在 Spark Java API 中加入行数据集