r - 使用精确匹配和模糊匹配在 R 中加入两个大型数据集
问题描述
我正在尝试内部连接两个数据集:df1
50,000 个 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
df2
500,000 个 obs 看起来像这样:
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
包,但我得到了一个Error: cannot allocate vector of size 120.6 Gb
,所以我想我必须使用另一种适用于更大数据集的方法。
关于解决此问题的最佳方法的任何想法是什么?
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)
)
解决方案
也许像下面这样的东西会满足问题的要求。它使用包stringdist
,而不是fuzzyjoin
.
首先,merge
by Postcode
only,因为匹配是精确的。然后得到Name
's 之间的相似性。如果它们高于预定阈值,则保留这些行。
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
推荐阅读
- python - 处理 CONNECT 请求的 Python 代理服务器
- r - 如何为大数据加速 R 中的嵌套 for 循环,目前在其中使用 append 并输出大列表?如何矢量化?
- django - request.method == 'POST' 无法正常工作
- go - 去不解决 GitHub 包导入
- php - 如何在 php 和 htaccess 中正确创建 url 重写
- mysql - 使用group by时如何在MYSQL中重叠NULL值?
- rest - 未知 SeaweedFs Filer API 响应格式
- sql - 为 Redshift SQL 中两个不同列的日期之间的每一天创建一个新行
- c# - 避免在 CosmosDB 中使用 UpsertAsync - 运行更新 SQL 命令
- mysql - MySQL 删除唯一键:在外键约束中需要