模糊左连接与 R 的使用

3
library(tidyverse)
library(fuzzyjoin)

df1 <- tibble(col1 = c("apple", "banana", "carrot"),
              col2 = as.numeric(0:2),
              col3 = as.numeric(0:2))
#> # A tibble: 3 x 3
#>   col1   col2  col3
#>   <chr> <int> <int>
#> 1 apple     0     0
#> 2 banana    1     1
#> 3 carrot    2     2

df2 <- tibble(col4 = c("app", "carr"), col5 = c(5, 9), matched = rep(TRUE, 2))
#> # A tibble: 2 x 3
#>   col4   col5 matched
#>   <chr> <dbl> <lgl>  
#> 1 app       5 TRUE   
#> 2 carr      9 TRUE 

我有两个数据框,分别为df1df2。我需要为df1创建一个新列,以指示每一行是否与df2中的某个条目匹配。

我还需要模糊匹配,并且模糊匹配需要不区分大小写(因此需要使用自定义的ci_str_detect函数):
ci_str_detect <- function(x, y){str_detect(x, regex(y, ignore_case = TRUE))}

df1 %>% 
  fuzzy_inner_join(df2, by = c("col1" = "col4"), match_fun = ci_str_detect)
#># A tibble: 2 x 6
#>  col1    col2  col3 col4   col5 matched
#>  <chr>  <dbl> <dbl> <chr> <dbl> <lgl>  
#>1 apple      0     0 app       5 TRUE   
#>2 carrot     2     2 carr      9 TRUE 

很遗憾(在这种情况下),fuzzyjoin R包似乎只能执行INNER JOIN,而我需要的是LEFT JOIN。

最终我需要这个输出:

#> # A tibble: 3 x 6
#>   col1    col2  col3 col4   col5  matched
#>   <chr>  <dbl> <dbl> <chr> <dbl>  <lgl>  
#> 1 apple      0     0 app       5  TRUE   
#> 2 banana     1     1 NA       NA  FALSE 
#> 3 carrot     2     2 carr      9  TRUE 

...而使用LEFT JOIN可以提供下面展示的中间数据框,我可以将其中的NA替换为FALSE,以获取我最终想要的结果(如上方所示)。

#> # A tibble: 3 x 6
#>   col1    col2  col3 col4   col5  matched
#>   <chr>  <dbl> <dbl> <chr> <dbl>  <lgl>  
#> 1 apple      0     0 app       5  TRUE   
#> 2 banana     1     1 NA       NA  NA 
#> 3 carrot     2     2 carr      9  TRUE 

我该如何在R中进行模糊LEFT连接?

2
你确定你期望香蕉的值为 col2 == 2col3 == 2 吗?当我尝试使用 fuzzy_left_join(df1, df2, match_fun = ci_str_detect, by = c(col1 = "col4")) 时,我得到了以下结果:structure(list(col1 = c("apple", "banana", "carrot"), col2 = c(0, 1, 2), col3 = c(0, 1, 2), col4 = c("app", NA, "carr"), col5 = c(5, NA, 9), matched = c(TRUE, NA, TRUE)), row.names = c(NA, -3L), class = c("tbl_df", "tbl", "data.frame")) - biomiha
@biomiha,那就是答案了,我不知道有一个fuzzy_left_join函数。哇。你可以把它作为答案,我会标记为已解决。是的,我之前复制/粘贴/逻辑错误,现在已经更正了。感谢你的帮助。 - Display name
1个回答

7

完成了 :)

fuzzy_left_join(df1, df2, match_fun = ci_str_detect, by = c(col1 = "col4"))

2
正切 - 你知道为什么上面的"col1"col1都可以使用吗?和library(dplyr)library("dplyr")可以使用的原因一样。 - Display name
1
我必须说,我从来没有完全清楚 NSE 的规则,但是是的,我认为这是最好的解释,即它可以评估未引用和引用的字符串。 - biomiha
但是当我尝试使用 df1 %>% fuzzy_inner_join(df2, by = c("col1" = "col4"), match_fun = ci_str_detect) 时,R也能正确地返回数据表。也许后续版本会修复这个问题。 - Leon Smith
与NSE无关,只是向量的名称可以引用或不引用,因此c(name = "value")等于c("name" = "value") - Remko Duursma

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接