模糊左连接完全匹配+部分字符串匹配

问题描述

我正在使用Fuzzy_left_join函数来匹配具有精确+模糊匹配的表。

我正在使用的 match_fun 参数之一涉及检查字符串的一部分是否包含在另一个字符串中。仅使用完全匹配时,它将返回值,但是当添加下面的函数时,联接仅返回NA值。

比较字符串的功能

detect <- function(x,y){ 
  any(unlist(strsplit(x,split = "/")) %in% unlist(strsplit(y,split = "/")))
    }

这个想法是,在第一个 X 上,名为“名称”的列具有行值,例如“ a / b / c”,而在第二个表 Y中的“名称”列中,值也类似于“ a / d / e”,因此字符串的“ a”部分也包含在第二个值中,并且应返回TRUE(并因此允许连接)。

使用简单的联接时,如果没有自定义功能,它将起作用并找到一些值:

x <- tribble(~X1,~X2,~Names,#--|--|----
        "5000","a","a/b/c","6000","b","d/e/f","7000","c","g/h/i")

y <- tribble(~Y1,~Y2,"a/j/k","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,"X2" = "Y2","Names" = "Names"),`==`,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