这是我之前用R格式转发的问题。
我正在寻找一种方法来合并两个数据文件基于参与者的全名的部分匹配,有时以不同的格式输入,有时拼写错误。我知道部分匹配(如agrep和pmatch)和合并数据文件有一些不同的功能选项,但我需要a)结合两者的帮助;B)做可以忽略中间名的部分匹配;C)在合并的数据文件中存储原始名称格式和d)保留唯一的值,即使它们没有匹配。
例如,我有以下两个数据文件:文件名:Employee Data (df1 in R)
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
文件名称:Assessment data (df2 in 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);拼写错误(例如:Elena Popa = Elena Pope)等
理想的输出是这样的:
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
任何建议都将非常感谢!
对于第一次,我建议分两个阶段。
首先,清理字符串。规范化大小写,去掉多余的空格,去掉任何不需要的字符。下面是我用来进行相当严格的清理的函数:
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
一个小的例子,但我希望它是有帮助的。