返回两个数据框的反连接,其值超出特定百分比差异

Return anti-join of two data frames with values outside a certain percentage difference

提问人:JemJem 提问时间:5/23/2023 最后编辑:M--JemJem 更新时间:5/23/2023 访问量:68

问:

我想比较两个混合类型的数据框,并返回它们之间不同的行,但我希望只返回一定百分比内的数值。

tbl1 <- tibble(var1 = c('r1', 'r2', 'r3', 'r4', 'r5'),
               var2 = c('apple', 'orange', 'banana', 'strawberry', 'lime'),
               var3 = c(1, 2, 3, 4, 5),
               var4 = c('yes', 'no', 'yes', 'yes', 'no'))

tbl2 <- tibble(var1 = c('r6', 'r7', 'r8', 'r9', 'r10'),
               var2 = c('orange', 'banana', 'apple', 'lemon', 'strawberry'),
               var3 = c(2, 3, 1.5, 10, 4.1),
               var4 = c('no', 'yes', 'yes', 'no', 'yes'))

我知道有,但会检查完全匹配。因此,如果我可以接受 20% 以内的数值,那么函数将如下所示:dplyr::anti_join

tbl1 %>%
  antijoin_function(tbl2, by = c('var2' = 'var2', 'var3' = 'var3', 'var4' = 'var4'),
                    pct = 0.2)

并返回

变量1 变量2 变量3 变量4
R1型 苹果 1 是的
R5型 石灰 5

不会返回 with 的行,因为 中的单次差值小于 20%。strawberryvar3

是否有任何函数或包可以做到这一点?

R DataFrame DPLYR FuzzyJoin 反联接

评论

0赞 M-- 5/23/2023
让我们以第一行为例。你想把它与第三行匹配,如果差值大于 20%,那么你就保留它,否则你放弃它。我说对了吗?tbl1tbl2var3
0赞 M-- 5/23/2023
此外,fuzzyjoin::d ifference_anti_join 确实存在,但根据您想要的输出,它似乎不是您需要的。您实际上是在匹配,然后如果差异超过 20% 或者没有匹配,则将行从 .没有一个函数可以同时做到这一点。您需要通过几个步骤来解决这个问题。var2var3tbl1
0赞 JemJem 5/23/2023
联接需要跨多个列进行,即对于 tbl1 中的 var2、var3 和 var4,返回与 tbl2 中所有这些值不匹配的行,如果数字值在 20% 或更小范围内,则将其计为“匹配”。
0赞 JemJem 5/23/2023
即字符/因子列应完全匹配,数字列匹配在 20% 以内。我需要确保匹配也沿着 var4 进行。我创建了虚拟的“var1”列,因为它不需要与 var1 匹配,我只是想证明我不能与所有内容进行反连接。
1赞 M-- 5/23/2023
最后,您希望 Character 列的行匹配且具有差异超过 20% 的数字列,对吗?我下面的回答就是这样做的。

答:

1赞 M-- 5/23/2023 #1
library(dplyr)

full_join(tbl1, tbl2, by = c("var2" = "var2"), suffix = c("", ".right")) %>% 
  filter(abs(var3 - var3.right)/var3 > 0.2 | if_all(contains(".right"), ~ is.na(.))) %>% 
  select(-contains(".right"))

#> # A tibble: 2 × 4
#>   var1  var2   var3 var4 
#>   <chr> <chr> <dbl> <chr>
#> 1 r1    apple     1 yes  
#> 2 r5    lime      5 no

创建于 2023-05-22 with reprex v2.0.2

评论

1赞 akrun 5/23/2023
这似乎很整洁。也许,他们可能会将 x$、y$ 扩展到其他表达式。目前,在 , -?join_byOther expressions are not supported. If you need to perform a join on a computed variable, e.g. join_by(sales_date - 40 >= promo_date), you'll need to precompute and store it in a separate column.