簡體   English   中英

在 R 中加入數據集,其中唯一 ID 有拼寫錯誤

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM