【问题标题】:R - Merging two data files based on partial matching of inconsistent full name formatsR - 基于不一致的全名格式的部分匹配合并两个数据文件
【发布时间】:2015-08-20 16:22:37
【问题描述】:

这是我以前用 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

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

           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

任何建议将不胜感激!

【问题讨论】:

  • 我唯一使用过的合并功能是合并,但我不确定如何将其与部分字符串匹配代码一起使用

标签: r merge string-matching fuzzy-comparison


【解决方案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

一个小例子,但我希望它会有所帮助。

【讨论】:

  • 谢谢,是的,这非常有用!现在我只需要根据您创建的匹配函数将两个文件合并在一起。但是,我需要合并它们,同时保留其他数据框中不匹配的唯一行。我知道我可以在合并中使用 all.x 参数,但我不确定如何将合并函数与此字符串匹配代码集成。
  • 我认为这个函数应该这样做:merge(df1, df2, by.x = "check", by.y = "name", all.x = TRUE, all.y = TRUE,排序 = 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 函数本身中使用权重参数,以便告诉算法更重视删除而不是交换(例如)。也就是说,我可能会通过分解名称来处理包含此混杂因素的数据集。我会尝试通过在空格处拆分字符串并添加一个简单的算法来识别常见的后缀来识别名字、中间名和姓氏。
猜你喜欢
  • 1970-01-01
  • 2020-10-15
  • 1970-01-01
  • 2016-04-15
  • 1970-01-01
  • 2020-10-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多