连续在变量中命名,然后创建一个具有最短名称的新变量以进行接近匹配

Successively agrep names in a variable, then create a new variable with the shortest name for close matches

假设一个公司名称的字符向量,其中名称以各种形式出现。这是 10,000 行数据框的小型版本;它显示了所需的第二个向量 ("two.names")。

structure(list(firm = structure(1:8, .Label = c("Carlson Caspers", 
"Carlson Caspers Lindquist & Schuman P.A", "Carlson Caspers Vandenburgh  Lindquist & Schuman P.A.", 
"Carlson Caspers Vandenburgh & Lindquist", "Carmody Torrance", 
"Carmody Torrance et al", "Carmody Torrance Sandak", "Carmody Torrance Sandak & Hennessey LLP"
), class = "factor"), two.name = structure(c(1L, 1L, 1L, 1L, 
2L, 2L, 2L, 2L), .Label = c("Carlson Caspers", "Carmody Torrance"
), class = "factor")), .Names = c("firm", "two.name"), row.names = c(NA, 
-8L), class = "data.frame")


                                               firm         two.name
1                                       Carlson Caspers  Carlson Caspers
2               Carlson Caspers Lindquist & Schuman P.A  Carlson Caspers
3 Carlson Caspers Vandenburgh  Lindquist & Schuman P.A.  Carlson Caspers
4               Carlson Caspers Vandenburgh & Lindquist  Carlson Caspers
5                                      Carmody Torrance Carmody Torrance
6                                Carmody Torrance et al Carmody Torrance
7                               Carmody Torrance Sandak Carmody Torrance
8               Carmody Torrance Sandak & Hennessey LLP Carmody Torrance

假设向量已按公司名称的字母顺序排序(我相信将最短的版本放在首位)。我如何使用 agrep() 以第一个公司名称开头,将其与第二个公司名称匹配 - 假设匹配度很高 - 将第一个公司名称添加到新列 (short.name) 中他们。然后,将它与第三个元素匹配,等等。所有 Carlson 变体都会被匹配。

如果没有足够的匹配,例如当 R 遇到第一个 Carmody 时,重新开始并匹配到下一个元素,依此类推直到下一个不匹配。

如果连续公司之间没有匹配项,R 应该继续,直到找到匹配项。

这个问题的答案是对整个向量进行模糊匹配,并按年份分组。 Create a unique ID by fuzzy matching of names (via agrep using R) It seems, however, to offer part of the code that would solve my problem. This question uses stringdist(). stringdist

编辑:

下面,对象 matches 是一个显示匹配项的列表,但我不知道告诉 R 的代码 "take the first one and convert the following matches, if any, to that name and put that name in the new variable column."

as.factor(df$firm)
matches <- lapply(levels(df$firm), agrep, x=levels(df$firm), fixed=TRUE, value=FALSE)

我用 for 循环写出来,首先将第一行定义为 short.name,然后找到匹配项,更新数据帧并选择下一个要查找的匹配项。这就是我所说的 "do not try to solve this with a one-liner" 的意思——你必须首先以更详细的方式让它工作,这样你才能理解发生了什么。然后,只有在需要时,您才可以尝试将其压缩成单行本。

firm.txt <- as.character(df$firm)
short.name <- firm.txt[1]
for (i in 2:length(firm.txt)) {
  # i don't know how to write it any prettier
  match <- agrep(short.name, firm.txt)
  if (length(match) > 0) {
    df$two.name[match] <- short.name
    i <- max(match) + 1
    short.name <- firm.txt[i]
  }
}