0

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

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

比较字符串的函数:

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

这个想法是,在第一个表X上,名为“Names”的列具有像“a/b/c”这样的行值,而在第二个表Y的列“Names”上,值也像“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, ~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   

你能不能给点想法?

4

1 回答 1

1

中应用的功能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     
于 2020-10-23T02:04:33.460 回答