Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R-基于不一致全名格式的部分匹配合并两个数据文件_R_Merge_String Matching_Fuzzy Comparison - Fatal编程技术网

R-基于不一致全名格式的部分匹配合并两个数据文件

R-基于不一致全名格式的部分匹配合并两个数据文件,r,merge,string-matching,fuzzy-comparison,R,Merge,String Matching,Fuzzy Comparison,这是我以前的问题,以R格式转发 我正在寻找一种方法,通过部分匹配参与者的全名来合并两个数据文件,这些全名有时以不同的格式输入,有时拼写错误。我知道部分匹配(如agrep和pmatch)和合并数据文件有一些不同的功能选项,但我需要a)结合这两种功能的帮助;b) 进行可以忽略中间名的部分匹配;c) 在合并数据文件存储中,原始名称格式和d)保留唯一值,即使它们没有匹配项 例如,我有以下两个数据文件: 文件名:员工数据(R中的df1) 文件名:评估数据(R中的df2) 我想根据姓名(df1中的全名和df

这是我以前的问题,以R格式转发

我正在寻找一种方法,通过部分匹配参与者的全名来合并两个数据文件,这些全名有时以不同的格式输入,有时拼写错误。我知道部分匹配(如agrep和pmatch)和合并数据文件有一些不同的功能选项,但我需要a)结合这两种功能的帮助;b) 进行可以忽略中间名的部分匹配;c) 在合并数据文件存储中,原始名称格式和d)保留唯一值,即使它们没有匹配项

例如,我有以下两个数据文件:

文件名:员工数据(R中的df1)

文件名:评估数据(R中的df2)

我想根据姓名(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))))
}
您可以使用此函数在另一个数据帧中查找最合适的匹配项

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

df1谢谢,是的,这非常有用!现在我只需要根据您创建的匹配函数将这两个文件合并在一起。但是,我需要合并它们,同时保留在其他数据帧中不匹配的唯一行。我知道我可以在merge中使用all.x参数,但我不确定如何将merge函数与这个字符串匹配代码集成。我认为这个函数应该做到:merge(df1,df2,by.x=“check”,by.y=“name”,all.x=TRUE,all.y=TRUE,sort=TRUE)我对上面的stringdist代码(或一般的函数)有一个问题。使用答案中的当前代码,如果我尝试将Wayne Sinclair的名字与Dan Inch或Wayne Danielson Sinclair匹配,它将返回一个匹配到Dan Inch:min(stringdist::stringdist('Wayne Sinclair',c(“Wayne Danielson Sincalir”))=11,而min(stringdist::stringdist('Wayne Sinclair',c(“Dan Inch”)=9。我能做些什么(可能使用amatch函数和weight参数)来解决这个问题,并设置一个规则,如果匹配需要太多的字符串编辑,则返回N/a到匹配中?@SonyaBendriem-有趣的例子!您可以在
stringdist
函数本身中使用权重参数,以便告诉算法在交换中更加重视删除(例如)。也就是说,我可能会通过分解名称来处理包含这种混淆的数据集。我会尝试通过在空格处拆分字符串并添加一个简单的算法来识别常用后缀来识别名字、中间名和姓氏。我唯一有经验的合并函数是merge,但我不确定如何将其用于部分字符串匹配代码
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))))
}
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