[英]Joining data sets in R where the unique ids have spelling mistakes
您好我正在尝试加入两个大型数据集 > 10000 个条目。 为此,我创建了一个“唯一 ID”——全名和出生日期的组合,两者都存在。 但是,数据集在 ID 中有拼写错误/不同的字符,因此在使用左连接时,许多将不匹配。 我无权访问 fuzyjoin/ match,所以不能使用它来部分匹配它们。 有人建议使用 adist()。 我如何使用它来匹配和合并数据集或标记接近匹配的数据集? 请尽可能简单,我只使用 R 几个星期! 代码示例将是惊人的
您可以将它们重命名为拼写正确的名称:
df$correct_spelling <- df$incorrect_spelling
这可能有点手动解决方案,但也许是一个基础 - R 解决方案是查看连接字段的唯一值并更正使用grep()
function 拼写错误的任何内容,并创建人行横道以合并到拼写错误的数据帧中唯一的 ID。 这是我的意思的一个简单的例子:
假设我们有一个 dataframe 的科学家和他们的出生年份,然后我们有第二个 dataframe 有科学家的姓名和他们的研究领域,但是“姓名”列充满了拼写错误。 这是制作示例数据框的代码:
##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
我们可以做的是使用正则表达式替换 function 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
现在我们可以制作一个 dataframe 以正确的拼写来交叉拼写错误的名称,即,第 1 行将有“Deandre”和“DeAndre” 第 2 行将有“Jil”和“Jill”。
CWX<-data.frame(Name_wrong=Mispelled2, Name_correct=fix)
最后我们将人行横道合并到拼写错误的 dataframe,然后将生成的 dataframe 合并到拼写正确的 dataframe
Mispelled3<-merge(DF2, CWX, by.x="Names", by.y="Name_wrong")
Joined_DF<-merge(DF, Mispelled3[,-1], by.x="Names", by.y="Name_correct")
对于您有关以多种方式进行匹配的问题,这是我能够提出的。 它有点笨拙,但它适用于下面的示例数据。 诀窍是使对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()
的开始、中间和结束调用。 根据拼写错误的严重程度,您可能需要使用最大距离和cost
max.distance
。 祝你好运。 保重,-肖恩
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.