两个数据库的模糊和精确匹配

时间:2020-10-12 15:57:16

标签: r purrr parallel.foreach fuzzyjoin furrr

我有两个数据库。第一个大约有70k行和3列。第二个有790k行和2列。这两个数据库都有一个公共变量grantee_name。我想根据此grantee_name将第一个数据库的每一行与第二个数据库的一个或多个行进行匹配。请注意,merge不能正常工作,因为grantee_name不能完全匹配。拼写不同,因此,我在使用fuzzyjoin包并尝试以下操作:

library("haven"); library("fuzzyjoin"); library("dplyr")
forfuzzy<-read_dta("/path/forfuzzy.dta")
filings <- read_dta ("/path/filings.dta")
> head(forfuzzy)
# A tibble: 6 x 3
  grantee_name                 grantee_city grantee_state
  <chr>                        <chr>        <chr>        
1 (ICS)2 MAINE CHAPTER         CLEARWATER   FL           
2 (SUFFOLK COUNTY) VANDERBILT~ CENTERPORT   NY           
3 1 VOICE TREKKING A FUND OF ~ WESTMINSTER  MD           
4 10 CAN                       NEWBERRY     FL           
5 10 THOUSAND WINDOWS          LIVERMORE    CA           
6 100 BLACK MEN IN CHICAGO INC CHICAGO      IL   
... 7 - 70000 rows to go

> head(filings)
# A tibble: 6 x 2
  grantee_name                       ein 
  <chr>                             <dbl>               
1 ICS-2 MAINE CHAPTER              123456             
2 SUFFOLK COUNTY VANDERBILT        654321            
3 VOICE TREKKING A FUND OF VOICES  789456            
4 10 CAN                           654987               
5 10 THOUSAND MUSKETEERS INC       789123               
6 100 BLACK MEN IN HOUSTON INC     987321      

rows 7-790000 omitted for brevity

上面的例子很清楚,足以提供一些好的匹配和一些不太好的匹配。请注意,例如,10 THOUSAND WINDOWS10 THOUSAND MUSKETEERS INC最匹配,但这并不意味着它是一个很好的匹配。 filings数据中的某处将有更好的匹配项(上面未显示)。在现阶段这无关紧要。

所以,我尝试了以下方法:

df<-as.data.frame(stringdist_inner_join(forfuzzy, filings, by="grantee_name", method="jw", p=0.1, max_dist=0.1, distance_col="distance"))

R完全不熟悉。这将导致错误: cannot allocate vector of size 375GB(当然还有大数据库)。 forfuzzy的100行样本始终有效。因此,我想到了一次遍历100行的列表。

我尝试了以下操作:

n=100
lst = split(forfuzzy, cumsum((1:nrow(forfuzzy)-1)%%n==0))

df<-as.data.frame(lapply(lst, function(df_)
{
(stringdist_inner_join(df_, filings, by="grantee_name", method="jw", p=0.1, max_dist=0.1, distance_col="distance", nthread = getOption("sd_num_thread")))
}
)%>% bind_rows)

我也用mclapply而不是lapply尝试了上述方法。即使我尝试将3个CPU的高性能集群设置为3个,每个CPU具有480G内存,并使用带有选项mclapply的{​​{1}},也会发生相同的错误。也许mc.cores=3命令可能会有所帮助,但是我不知道如何实现它。

建议我使用foreachpurrr软件包,所以我尝试以下操作:

repurrrsive

purrr::map(lst, ~stringdist_inner_join(., filings, by="grantee_name", method="jw", p=0.1, max_dist=0.1, distance_col="distance", nthread = getOption("sd_num_thread"))) 语句中出现新手错误之后,这似乎起作用。但是,这将永远持续下去,我不确定它是否会起作用。 by=grantee_name中有100行的示例列表,其中有forfuzzy(所以10个列表,每行10行)已经运行了50分钟,仍然没有结果。

2 个答案:

答案 0 :(得分:0)

我以前没有使用过foreach,但也许变量x已经是zz1的各个行了?

您尝试过吗:

stringdist_inner_join(x, zz2, by="grantee_name", method="jw", p=0.1, max_dist=0.1, distance_col="distance")

答案 1 :(得分:0)

如果您将唯一的grantees数据帧(例如,用base::splitdplyr::group_bydplyr::group_split拆分为数据帧列表,则可以在列表上调用purrr::map 。 (map差不多是lapply

purrr::map(list_of_dfs, ~stringdist_inner_join(., filings, by="grantee_name", method="jw", p=0.1, max_dist=0.1, distance_col="distance"))

您的结果将是一个数据框的列表,每个数据框均模糊不清并带有归档。然后,您可以调用bind_rows(或者可以执行map_dfr)以再次将所有结果存储在同一数据框中。

请参见R - Splitting a large dataframe into several smaller dateframes, performing fuzzyjoin on each one and outputting to a single dataframe

相关问题