根据两列的匹配/模糊匹配值选择列

时间:2016-07-28 06:51:45

标签: r record-linkage

我的数据框ILocationProvider包含df1列和"Year"

"Agent"

我有另一个数据框df1 <- structure(list(Year = c(1999, 1999, 1998), Agent = list(c("abn-amro-nv", "suntrust banks", "wachovia"), c("jp morgan", "abn-amro-nv"), c("ba-corp", "boston bks", "nbd"))), .Names = c("Year", "Agent"), row.names = c(NA, -3L), class = "data.frame") #df1 Year Agent 1999 abn-amro-nv, suntrust banks, wachovia 1999 jp morgan, abn-amro-nv 1998 ba-corp, boston bks, nbd ,其中包含5列df2"Rank""Arrangers""Share""Issues",如下所示:

"Year"

我需要将df2 <- structure(list(Rank = 1:3, Arranger = c("jp morgan", "boston-bank", "suntrust bk"), Share = c(1.2, 1.8, 2.1), Issues = c(7L, 4L, 3L), Year = c(1999L, 1998L, 1999L)), .Names = c("Rank", "Arranger", "Share", "Issues", "Year"), class = "data.frame", row.names = c(NA, -3L)) #df2 Rank Arranger Share Issues Year 1 jp morgan 1.2 7 1999 2 boston-bank 1.8 4 1998 3 suntrust bk 2.1 3 1999 的{​​{1}}和"Agent""Year"df1的{​​{1}}进行匹配,并从{{1}中选择3列例如"Arranger""Year"df2df2 "Rank""Share" "Issues"的匹配将是模糊匹配。这是因为它们并不完全相同。

我的原始数据框非常大,仅供您参考。

以下是我的代码:

"Agent"

在代码中,df1是我创建的矩阵。这样我就可以填入"Arranger"。我使用df2包和library(stringdist) leadrep <- matrix(ncol=3, nrow=length(df1$Agent)) for (i in 1:length(df1$Agent)) { for (j in 1:length(df2$Arrangers)) { if ((ain(df2$Arrangers[j], df1$Agent[[i]], maxDist=0.3, method="jw")) == 'TRUE' & (df1$Year[i] == df2$Year[j])){ leadrep[i,] <- df2[j, c('Rank', 'Mkt.Share', 'NumberofIssues')] } } } 函数进行模糊匹配。我使用了两个leadrepfor loop来比较字符串和年份。

以上代码有效,但由于我的数据框很大,因此需要很长时间才能得到结果。我真的认为我上面的方法效率不高。如果有人为我提供了比现有代码更好的替代方案,那将是一个很大的帮助。

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

以下方法使用foreach而不是两个嵌套的for循环,这样可以使您在大型数据帧上的计算速度更快。有关该软件包的详细概述,请参阅this。你也应该看看小插曲。

library(foreach)
library(stringdist)

match.cond <- function(ij, df1, df2) {                                   ## 1.
  i = floor((ij-1) / nrow(df2)) + 1
  j = ij - (i-1) * nrow(df2)
  if ((ain(df2$Arranger[j], df1$Agent[[i]], maxDist=0.3, 
       method="jw")) == 'TRUE' & (df1$Year[i] == df2$Year[j])){
    return(df2[j, c('Rank', 'Share', 'Issues')])
  }
}

leadrep <- foreach(ij = 1:(nrow(df1)*nrow(df2)), .combine=rbind) %do%    ## 2.
  match.cond(ij, df1, df2)

注意:

  1. match.cond是您的匹配条件,封装在内核函数中,{{1>}将{{1>}来自{{1}的所有行对矢量化 }和foreach。它的输入是df1,它是配对的索引和两个数据帧。在df2内:
    • ij转换为match.cond的行索引iji的{​​{1}}
    • 评估您的情况,如果符合条件,
    • 返回匹配行的df1列。
  2. 这是j来电。
    • 我们将df2的{​​{1}}索引循环到df2,其中列出了来自foreachij以及1的所有行对。 nrow(df1)*nrow(df2)函数。请注意,这只是一行。
    • df1参数声明我们要从df2收集所有结果并将它们绑定为行。
    • 返回数据框%do%
  3. 我已对您的数据进行了测试,我match.cond

    .combine=rbind

    给了我想要的结果:

    match.cond

    希望这有帮助。