Fuzzy Left Join 精确+部分字符串匹配
Fuzzy Left Join exact + partial string match
我正在使用 fuzzy_left_join 函数通过精确 + 模糊匹配来匹配 table。
我使用的 match_fun 参数之一涉及检查字符串的一部分是否包含在另一个字符串中。当仅使用精确匹配时,它 returns 值,但当添加下面的函数时,连接仅 returns NA 值。
比较字符串的函数:
detect <- function(x, y){
any(unlist(strsplit(x, split = "/")) %in% unlist(strsplit(y, split = "/")))
}
想法是,在第一个 table X 上,名为“Names”的列的行值类似于“a/b/c”,在列“来自第二个 table Y 的名称”,值也类似于“a/d/e”,因此字符串的“a”部分也包含在第二个值中, TRUE 应该 return(从而允许加入)。
当使用简单连接时,没有自定义函数,它可以工作并找到一些值:
x <- tribble(~X1, ~X2, ~Names,
#--|--|----
"5000", "a", "a/b/c",
"6000", "b", "d/e/f",
"7000", "c", "g/h/i")
y <- tribble(~Y1, ~Y2, ~Names,
#--|--|----
"5000", "a", "a/j/k",
"6000", "b", "l/m/n",
"8000", "d", "o/p/q")
fuzzyjoin::fuzzy_left_join(x, y, by = c("X1" = "Y1", "X2" = "Y2"),
match_fun = list(`==`, `==`))
# Produces:
#> A tibble: 3 x 6
#> X1 X2 Names.x Y1 Y2 Names.y
#> <chr> <chr> <chr> <chr> <chr> <chr>
#> 1 5000 a a/b/c 5000 a a/j/k
#> 2 6000 b d/e/f 6000 b l/m/n
#> 3 7000 c g/h/i NA NA NA
但是添加自定义函数时:
fuzzyjoin::fuzzy_left_join(x, y, by = c("X1" = "Y1", "X2" = "Y2", "Names" = "Names"),
match_fun = list(`==`, `==`, detect))
# Produces:
#> A tibble: 3 x 6
#> X1 X2 Names.x Y1 Y2 Names.y
#> <chr> <chr> <chr> <chr> <chr> <chr>
#> 1 5000 a a/b/c NA NA NA
#> 2 6000 b d/e/f NA NA NA
#> 3 7000 c g/h/i NA NA NA
# Intended:
#> A tibble: 3 x 6
#> X1 X2 Names.x Y1 Y2 Names.y
#> <chr> <chr> <chr> <chr> <chr> <chr>
#> 1 5000 a a/b/c 5000 a a/j/k
#> 2 6000 b d/e/f NA NA NA
#> 3 7000 c g/h/i NA NA NA
你能给点意见吗?
match_fun
中应用的函数不适用于一次组合。它将函数应用于所有组合,因此您需要更改 detect
函数:
detect <- function(x, y){
mapply(function(x, y) any(x == y), strsplit(x, '/'), strsplit(y, '/'))
}
然后尝试:
fuzzyjoin::fuzzy_left_join(x, y, by = c("X1" = "Y1", "X2" = "Y2", "Names"),
match_fun = list(`==`, `==`, detect))
# X1 X2 Names.x Y1 Y2 Names.y
# <chr> <chr> <chr> <chr> <chr> <chr>
#1 5000 a a/b/c 5000 a a/j/k
#2 6000 b d/e/f NA NA NA
#3 7000 c g/h/i NA NA NA
我正在使用 fuzzy_left_join 函数通过精确 + 模糊匹配来匹配 table。
我使用的 match_fun 参数之一涉及检查字符串的一部分是否包含在另一个字符串中。当仅使用精确匹配时,它 returns 值,但当添加下面的函数时,连接仅 returns NA 值。
比较字符串的函数:
detect <- function(x, y){
any(unlist(strsplit(x, split = "/")) %in% unlist(strsplit(y, split = "/")))
}
想法是,在第一个 table X 上,名为“Names”的列的行值类似于“a/b/c”,在列“来自第二个 table Y 的名称”,值也类似于“a/d/e”,因此字符串的“a”部分也包含在第二个值中, TRUE 应该 return(从而允许加入)。
当使用简单连接时,没有自定义函数,它可以工作并找到一些值:
x <- tribble(~X1, ~X2, ~Names,
#--|--|----
"5000", "a", "a/b/c",
"6000", "b", "d/e/f",
"7000", "c", "g/h/i")
y <- tribble(~Y1, ~Y2, ~Names,
#--|--|----
"5000", "a", "a/j/k",
"6000", "b", "l/m/n",
"8000", "d", "o/p/q")
fuzzyjoin::fuzzy_left_join(x, y, by = c("X1" = "Y1", "X2" = "Y2"),
match_fun = list(`==`, `==`))
# Produces:
#> A tibble: 3 x 6
#> X1 X2 Names.x Y1 Y2 Names.y
#> <chr> <chr> <chr> <chr> <chr> <chr>
#> 1 5000 a a/b/c 5000 a a/j/k
#> 2 6000 b d/e/f 6000 b l/m/n
#> 3 7000 c g/h/i NA NA NA
但是添加自定义函数时:
fuzzyjoin::fuzzy_left_join(x, y, by = c("X1" = "Y1", "X2" = "Y2", "Names" = "Names"),
match_fun = list(`==`, `==`, detect))
# Produces:
#> A tibble: 3 x 6
#> X1 X2 Names.x Y1 Y2 Names.y
#> <chr> <chr> <chr> <chr> <chr> <chr>
#> 1 5000 a a/b/c NA NA NA
#> 2 6000 b d/e/f NA NA NA
#> 3 7000 c g/h/i NA NA NA
# Intended:
#> A tibble: 3 x 6
#> X1 X2 Names.x Y1 Y2 Names.y
#> <chr> <chr> <chr> <chr> <chr> <chr>
#> 1 5000 a a/b/c 5000 a a/j/k
#> 2 6000 b d/e/f NA NA NA
#> 3 7000 c g/h/i NA NA NA
你能给点意见吗?
match_fun
中应用的函数不适用于一次组合。它将函数应用于所有组合,因此您需要更改 detect
函数:
detect <- function(x, y){
mapply(function(x, y) any(x == y), strsplit(x, '/'), strsplit(y, '/'))
}
然后尝试:
fuzzyjoin::fuzzy_left_join(x, y, by = c("X1" = "Y1", "X2" = "Y2", "Names"),
match_fun = list(`==`, `==`, detect))
# X1 X2 Names.x Y1 Y2 Names.y
# <chr> <chr> <chr> <chr> <chr> <chr>
#1 5000 a a/b/c 5000 a a/j/k
#2 6000 b d/e/f NA NA NA
#3 7000 c g/h/i NA NA NA