使用精确匹配和模糊匹配连接R中的两个大型数据集

使用精确匹配和模糊匹配连接R中的两个大型数据集,r,join,inner-join,fuzzyjoin,R,Join,Inner Join,Fuzzyjoin,我正在尝试内部连接两个数据集:df150000个obs,如下所示: Name | Line.1 | Line.2 | Town | County | Postcode -------------------|------------------|------------|------------|--------------|---------- ACME Inc | 63 Long S

我正在尝试内部连接两个数据集:
df1
50000个obs,如下所示:

  Name              | Line.1           | Line.2     | Town       | County       | Postcode 
 -------------------|------------------|------------|------------|--------------|---------- 
  ACME Inc          | 63 Long Street   |            | Fakeington | Lincolnshire | PA4 8QU  
  BETA LTD          | 91a              | Main Drove | Cloud City | Something    | BN1 6LD  
  The Giga          | 344 Lorem Street |            | Ipsom      | Dolor        | G2 8LY   
  Name              | AddressLine1   | AddressLine2     | AddressLine3 | AddressLine4 | Postcode | RatingValue 
 -------------------|----------------|------------------|--------------|--------------|----------|------------- 
  ACME              |                | 63 Long Street   | Fakeington   | Lincolnshire | PA4 8QU  | 1           
  Random Company    |                | Rose Ave         | Fakeington   |              | AB2 51GL | 5           
  BETA Limited      | Business House | 91a Main Drove   | Something    |              | BN1 6LD  | 3           
  Giga Incorporated |                | 344 Lorem Street | Ipsum        | Dolor        | G2 8LY   | 5           
df2
500000 obs的外观如下所示:

  Name              | Line.1           | Line.2     | Town       | County       | Postcode 
 -------------------|------------------|------------|------------|--------------|---------- 
  ACME Inc          | 63 Long Street   |            | Fakeington | Lincolnshire | PA4 8QU  
  BETA LTD          | 91a              | Main Drove | Cloud City | Something    | BN1 6LD  
  The Giga          | 344 Lorem Street |            | Ipsom      | Dolor        | G2 8LY   
  Name              | AddressLine1   | AddressLine2     | AddressLine3 | AddressLine4 | Postcode | RatingValue 
 -------------------|----------------|------------------|--------------|--------------|----------|------------- 
  ACME              |                | 63 Long Street   | Fakeington   | Lincolnshire | PA4 8QU  | 1           
  Random Company    |                | Rose Ave         | Fakeington   |              | AB2 51GL | 5           
  BETA Limited      | Business House | 91a Main Drove   | Something    |              | BN1 6LD  | 3           
  Giga Incorporated |                | 344 Lorem Street | Ipsum        | Dolor        | G2 8LY   | 5           
我想谈谈类似于
df_final

  Name              | Postcode | RatingValue 
 -------------------|----------|------------- 
  ACME Inc          | PA4 8QU  | 1           
  BETA LTD          | BN1 6LD  | 3           
  Giga Incorporated | G2 8LY   | 5           
这些是一对一的匹配,
df1
中的所有值都应该存在于
df2
Postcode
是一个精确匹配,而地址被分割成多行,没有规则的模式,因此我认为我最好的选择是通过
Name
匹配

我尝试了
fuzzyjoin
软件包,但是我得到了一个
错误:无法分配大小为120.6GB的向量,因此我想我必须使用另一种方法来处理更大的数据集

你有没有什么好办法

df1 <- data.frame(
  stringsAsFactors = FALSE,
              Name = c("ACME Inc", "BETA LTD", "Giga Incorporated"),
            Line.1 = c("63 Long Street", "91a", "344 Lorem Street"),
            Line.2 = c(NA, "Main Drove", NA),
              Town = c("Fakeington", "Cloud City", "Ipsom"),
            County = c("Lincolnshire", "Something", "Dolor"),
          Postcode = c("PA4 8QU", "BN1 6LD", "G2 8LY")
)

df2 <- data.frame(
  stringsAsFactors = FALSE,
              Name = c("ACME", "Random Company","BETA Limited","Giga Incorporated"),
      AddressLine1 = c(NA, NA, "Business House", NA),
      AddressLine2 = c("63 Long Street", "Rose Ave","91a Main Drove","344 Lorem Street"),
      AddressLine3 = c("Fakeington", "Fakeington", "Something", "Ipsum"),
      AddressLine4 = c("Lincolnshire", NA, NA, "Dolor"),
          Postcode = c("PA4 8QU", "AB2 51GL", "BN1 6LD", "G2 8LY"),
       RatingValue = c(1L, 5L, 3L, 5L)
)

df1也许像下面这样的东西可以满足问题的要求。它使用包
stringdist
,而不是
fuzzyjoin

首先,
merge
by
Postcode
,因为匹配是精确的。然后获取
名称
之间的相似性。如果它们高于预定阈值,则保留这些行

thresh <- 0.75

df_final <- merge(df2[c(1, 6:7)], df1[c(1, 6)], by = "Postcode", suffixes = c("",".y"))
i <- apply(df_final[c(2, 4)], 1, function(x) {stringdist::stringsim(x[1], x[2], method = 'jw')}) >= thresh

df_final <- df_final[i, c(2, 1, 3)]

df_final 
#               Name Postcode RatingValue
#1      BETA Limited  BN1 6LD           3
#2 Giga Incorporated   G2 8LY           5
#3              ACME  PA4 8QU           1

thresh我首先将其分解为一个较小的问题。从两个现有列中创建一个数据帧:df1$Name和df2$Name,其中的行表示满足某个匹配阈值(soundex、字符串距离,任何您想要的)的“匹配”公司名称的每个组合。对df1和df2进行笛卡尔连接,然后进行过滤,以便只保留有效的组合。@BillO'Brien笛卡尔连接
df1
是50K行,
df2
500K,
50000*500000
2.5e+10
。我被纠正了。这似乎已经完成了。我会做一些清理来移除stopwords,调整阈值并测试不同的方法,但到目前为止还不错!