我有两个数据库。第一个大约有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 WINDOWS
与10 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
命令可能会有所帮助,但是我不知道如何实现它。
建议我使用foreach
和purrr
软件包,所以我尝试以下操作:
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分钟,仍然没有结果。
答案 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::split
或dplyr::group_by
和dplyr::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)以再次将所有结果存储在同一数据框中。