模糊合并多个变量(除了一个没有拼写错误)
Fuzzy merge on multiple variables (all but one with no mispellings)
我需要在三个变量上匹配两个数据集。
三个变量中的两个不存在拼写错误(设计使然)。
只有第三个变量需要模糊匹配。
标准的 fuyyzmerge 通过模糊连接所有三个变量产生了一些问题。
有没有办法指定三者中的哪一个应该模糊匹配,哪个应该精确匹配?
可重现的例子:
dataset_1 <- setNames(data.frame(c(1995,1996,1995,1996),c("AA","AA","BB","BB"),c("AAAA","AAAA","BBBB","BBBB")), c("var_1", "var_2", "var_3"))
dataset_2 <- setNames(data.frame(c(1995,1996,1995,1996),c("AA","AA","BB","BB"),c("AAAA","AAAA","BBBB","BBBC"),c("A","B","C","D")), c("var_1", "var_2", "var_3","var_4"))
merged <- stringdist_join(dataset_1, dataset_2,
by=c("var_1","var_2","var_3"),
max_dist = 2,
method = c("soundex"),
mode = "full",
ignore_case = FALSE)
理想结果:
merged <- setNames(data.frame(rep(1995,4),c("AA","AA","BB","BB"),c("AAAA","AAAA","BBBB","BBBB"),c("A","B","C","D")), c("var_1", "var_2", "var_3","var_4"))
stringdist_join
是 fuzzy_join
的包装器,而 fuzzy_join
有一个 match_fun
参数,它可以是唯一函数或函数列表,只要你的by
参数,所以我们可以使用 fuzzy_full_join
(这只是 fuzzy_join
和 mode= "full"
):
library(fuzzyjoin)
res <- fuzzy_full_join(dataset_1, dataset_2,
by=c("var_1","var_2","var_3"),
list(`==`, `==`, function(x,y) stringdist::stringdist(x,y, "soundex") <= 2))
res
# var_1.x var_2.x var_3.x var_1.y var_2.y var_3.y var_4
# 1 1995 AA AAAA 1995 AA AAAA A
# 2 1996 AA AAAA 1996 AA AAAA B
# 3 1995 BB BBBB 1995 BB BBBB C
# 4 1996 BB BBBB 1996 BB BBBC D
由于模糊匹配的性质,lhs 和 rhs 上的值通常不相同,所以我们最终得到两组按列,如果你只想保留 lhs 我们可以这样做:
library(dplyr)
res %>%
select(-ends_with(".y")) %>%
rename_all(~sub("\.x$","",.))
# var_1 var_2 var_3 var_4
# 1 1995 AA AAAA A
# 2 1996 AA AAAA B
# 3 1995 BB BBBB C
# 4 1996 BB BBBB D
我需要在三个变量上匹配两个数据集。 三个变量中的两个不存在拼写错误(设计使然)。 只有第三个变量需要模糊匹配。
标准的 fuyyzmerge 通过模糊连接所有三个变量产生了一些问题。
有没有办法指定三者中的哪一个应该模糊匹配,哪个应该精确匹配?
可重现的例子:
dataset_1 <- setNames(data.frame(c(1995,1996,1995,1996),c("AA","AA","BB","BB"),c("AAAA","AAAA","BBBB","BBBB")), c("var_1", "var_2", "var_3"))
dataset_2 <- setNames(data.frame(c(1995,1996,1995,1996),c("AA","AA","BB","BB"),c("AAAA","AAAA","BBBB","BBBC"),c("A","B","C","D")), c("var_1", "var_2", "var_3","var_4"))
merged <- stringdist_join(dataset_1, dataset_2,
by=c("var_1","var_2","var_3"),
max_dist = 2,
method = c("soundex"),
mode = "full",
ignore_case = FALSE)
理想结果:
merged <- setNames(data.frame(rep(1995,4),c("AA","AA","BB","BB"),c("AAAA","AAAA","BBBB","BBBB"),c("A","B","C","D")), c("var_1", "var_2", "var_3","var_4"))
stringdist_join
是 fuzzy_join
的包装器,而 fuzzy_join
有一个 match_fun
参数,它可以是唯一函数或函数列表,只要你的by
参数,所以我们可以使用 fuzzy_full_join
(这只是 fuzzy_join
和 mode= "full"
):
library(fuzzyjoin)
res <- fuzzy_full_join(dataset_1, dataset_2,
by=c("var_1","var_2","var_3"),
list(`==`, `==`, function(x,y) stringdist::stringdist(x,y, "soundex") <= 2))
res
# var_1.x var_2.x var_3.x var_1.y var_2.y var_3.y var_4
# 1 1995 AA AAAA 1995 AA AAAA A
# 2 1996 AA AAAA 1996 AA AAAA B
# 3 1995 BB BBBB 1995 BB BBBB C
# 4 1996 BB BBBB 1996 BB BBBC D
由于模糊匹配的性质,lhs 和 rhs 上的值通常不相同,所以我们最终得到两组按列,如果你只想保留 lhs 我们可以这样做:
library(dplyr)
res %>%
select(-ends_with(".y")) %>%
rename_all(~sub("\.x$","",.))
# var_1 var_2 var_3 var_4
# 1 1995 AA AAAA A
# 2 1996 AA AAAA B
# 3 1995 BB BBBB C
# 4 1996 BB BBBB D