2015-06-05 32 views
1

這是我以前用R格式轉發的問題。R - 基於不一致全名格式的部分匹配合並兩個數據文件

我正在尋找一種合併兩個數據文件的方法,它基於部分匹配的參與者的全名,有時以不同格式輸入並且有時拼錯。我知道部分匹配有一些不同的功能選項(如agrep和pmatch)和合並數據文件,但我需要幫助:a)組合這兩個; b)進行可以忽略中間名的部分匹配; c)在合併的數據文件存儲中都使用原始名稱格式,d)保留唯一值,即使它們沒有匹配。

例如,我有以下兩個數據文件:

文件名稱:員工數據(作爲R DF1)

 Full.Name Date.Started Orders 
1 ANGELA MUIR  6/15/14 25  44 
2 EILEEN COWIE  6/15/14  40 
3 LAURA CUMMING  10/6/14  43 
4 ELENA POPA  1/21/15  37 
5 KAREN MACEWAN  3/15/99  39 

文件名稱:評估數據(DF2在R)

  Candidate Leading.Factor SI.D SI.I 
1   Angie muir    I -3 12 
2  Caroline Burn    S -5 -3 
3 Eileen Mary Cowie    S -5 5 
4   Elena Pope    C -4 7 
5  Henry LeFeuvre    C -5 -1 
6  Jennifer Ford    S -3 -2 
7  Karen McEwan    I -4 10 
8  Laura Cumming    S 0 6 
9  Mandip Johal    C -2 2 
10 Mubarak Hussain    D 6 -1 

我想根據名稱(df1中的全名和df2中的候選者)將它們合併,忽略中間名(例如Eilen Cowie = Eileen Mary Cowie),額外空格(Laura Cumming = Laura Cumming);拼錯(例如埃琳娜波帕=埃琳娜教皇)等

理想的輸出是這樣的:

   Name  Full.Name   Candidate Date.Started Orders Leading.Factor SI.D SI.I 
1 ANGELA MUIR ANGELA MUIR   Angie muir 6/15/14 25  44    I -3 12 
2 EILEEN COWIE EILEEN COWIE Eileen Mary Cowie  6/15/14  40    S -5 5 
3 LAURA CUMMING LAURA CUMMING  Laura Cumming  10/6/14  43    S 0 6 
4  ELENA POPA  ELENA POPA   Elena Pope  1/21/15  37    C -4 7 
5 KAREN MACEWAN KAREN MACEWAN  Karen McEwan  3/15/99  39    I -4 10 
6 Caroline Burn   N/A  Caroline Burn   N/A N/A    S -5 -3 
7 Henry LeFeuvre   N/A Henry LeFeuvre   N/A N/A    C -5 -1 
8 Jennifer Ford   N/A  Jennifer Ford   N/A N/A    S -3 -2 
9  Mandip Johal   N/A  Mandip Johal   N/A N/A    C -2 2 
10 Mubarak Hussain   N/A Mubarak Hussain   N/A N/A    D 6 -1 

任何建議,將不勝感激!

+0

我有經驗的唯一合併函數是合併,但我不知道如何使用部分字符串匹配代碼 –

回答

2

第一遍,我會建議一個兩階段的過程。

首先,清理你的琴絃。標準化外殼,去除多餘的空間,去除任何不需要的字符。我用了一個相當強勁的清潔功能是如下:

stringCleaning <- function(x) { 
# x <- stringr::str_trim(x) 
# x <- tolower(x) 
# x <- gsub("\\s+", " ", x) 
# x <- gsub("[^[:space:]A-z0-9]", "", x) 
    stringr::str_trim(tolower(gsub("\\s+", " ", gsub("[^[:space:]A-z0-9]", "", x)))) 
} 

這將字符串轉換爲小寫,剔除了任何非字母數字或字符串中的字符,剔除了多餘的空格,並在字符串的兩側刪除空格。

二,使用Levenshtein(或編輯)距離來找到最接近的匹配。 stringdist包裝包括一個簡單的距離計算器來幫助你。

stringdist::stringdist('your mother', c("bellow", "your mom", 'yourmother')) 
min(stringdist::stringdist('your mother', c("bellow", "your mom", 'yourmother'))) 
which.min(stringdist::stringdist('your mother', c("bellow", "your mom", 'yourmother'))) 

您可以使用此功能在另一個數據框中找到最合適的匹配。

df1 <- data.frame(name = c("Jena Stars", "Gina Starz")) 
df2 <- data.frame(name = c("gina starz", "Jena starz ")) 

df1$clean <- stringCleaning(df1$name) 
df2$clean <- stringCleaning(df2$name) 

df1$check <- df2$name[sapply(df1$clean, function(x) { 
    which.min(stringdist::stringdist(x, df2$clean)) 
    })] 
df1 

一個小例子,但我希望它有幫助。

+0

謝謝,是的這是非常有用的!現在我只需要根據您創建的匹配函數將這兩個文件合併在一起。但是,我需要將它們合併,同時保留其他數據框中沒有匹配的唯一行。我知道我可以在合併中使用all.x參數,但我不確定如何將合併函數與此字符串匹配代碼集成。 –

+1

我認爲這個函數應該這樣做:merge(df1,df2,by.x =「check」,by.y =「name」,all.x = TRUE,all.y = TRUE,sort = TRUE) –

+0

我有一個關於上面的字符串代碼的問題(或者一般的函數)。使用答案中的當前代碼,如果我嘗試將名稱Wayne Sinclair與Dan Inch或Wayne Danielson Sinclair相匹配,則會將匹配返回給Dan Inch:min(stringdist :: stringdist('Wayne Sinclair',c(「 Wayne Danielson Sincalir「)))= 11 while min(stringdist :: stringdist('Wayne Sinclair',c(」Dan Inch「)))= 9.有什麼我可以做的(也許使用amatch函數和weight參數)解決這個問題,並設置一條規則,說如果需要太多的字符串編輯返回一個N/A的匹配? –

相關問題