Skip to content

Commit 6d752bf

Browse files
feat: Add support for %notin% (#349)
1 parent ed7be28 commit 6d752bf

5 files changed

Lines changed: 165 additions & 10 deletions

File tree

NEWS.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
# tidypolars (development)
2+
3+
## New features
4+
5+
* Added support for `%notin%` (#349).
6+
17
# tidypolars 0.18.0
28

39
`tidypolars` requires `polars` >= 1.10.0.

R/utils-expr.R

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,37 @@ translate <- function(
492492
)
493493
return(out)
494494
},
495+
# Same thing as "%in%" but with the "$not()" at the end.
496+
"%notin%" = {
497+
out <- tryCatch(
498+
{
499+
lhs <- translate(
500+
expr[[2]],
501+
.data = .data,
502+
new_vars = new_vars,
503+
env = env,
504+
caller = caller,
505+
expr_uses_col = expr_uses_col
506+
) |>
507+
as_polars_expr(as_lit = TRUE)
508+
rhs <- translate(
509+
expr[[3]],
510+
.data = .data,
511+
new_vars = new_vars,
512+
env = env,
513+
caller = caller,
514+
expr_uses_col = expr_uses_col
515+
) |>
516+
as_polars_expr(as_lit = TRUE)
517+
if (is.list(rhs)) {
518+
rhs <- unlist(rhs)
519+
}
520+
lhs$is_in(rhs$implode(), nulls_equal = TRUE)$not()
521+
},
522+
error = identity
523+
)
524+
return(out)
525+
},
495526
"base::ifelse" = ,
496527
"ifelse" = ,
497528
"dplyr::if_else" = ,

tests/testthat/test-filter-lazy.R

Lines changed: 63 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -190,11 +190,6 @@ test_that("%in% works", {
190190
test_df |> filter(Species %in% c("setosa", "virginica"))
191191
)
192192

193-
expect_equal_lazy(
194-
test_pl |> filter(Species %in% c("setosa", "virginica")),
195-
test_df |> filter(Species %in% c("setosa", "virginica"))
196-
)
197-
198193
test_df <- tibble(x = c(1, 2, 3), y = c(1, 3, 2))
199194
test_pl <- pl$LazyFrame(x = c(1, 2, 3), y = c(1, 3, 2))
200195

@@ -214,6 +209,69 @@ test_that("%in% works with NA", {
214209
)
215210
})
216211

212+
test_that("%notin% works", {
213+
test_df <- as_tibble(mtcars)
214+
test_pl <- as_polars_lf(test_df)
215+
216+
expect_equal_lazy(
217+
filter(test_pl, cyl %notin% 4:5),
218+
filter(test_df, cyl %notin% 4:5)
219+
)
220+
221+
expect_equal_lazy(
222+
filter(test_pl, cyl %notin% 4:5 & am %notin% 1),
223+
filter(test_df, cyl %notin% 4:5 & am %notin% 1)
224+
)
225+
226+
expect_equal_lazy(
227+
filter(test_pl, cyl %notin% 4:5, am %notin% 1),
228+
filter(test_df, cyl %notin% 4:5, am %notin% 1)
229+
)
230+
231+
expect_equal_lazy(
232+
filter(test_pl, cyl %notin% 4:5 | am %notin% 1),
233+
filter(test_df, cyl %notin% 4:5 | am %notin% 1)
234+
)
235+
236+
expect_equal_lazy(
237+
filter(test_pl, cyl %notin% 4:5, vs == 1),
238+
filter(test_df, cyl %notin% 4:5, vs == 1)
239+
)
240+
241+
expect_equal_lazy(
242+
filter(test_pl, cyl %notin% 4:5 | carb == 4),
243+
filter(test_df, cyl %notin% 4:5 | carb == 4)
244+
)
245+
246+
test_df <- as_tibble(iris)
247+
# TODO: this shouldn't be necessary
248+
test_df$Species <- as.character(test_df$Species)
249+
test_pl <- as_polars_lf(test_df)
250+
251+
expect_equal_lazy(
252+
test_pl |> filter(Species %notin% c("setosa", "virginica")),
253+
test_df |> filter(Species %notin% c("setosa", "virginica"))
254+
)
255+
256+
test_df <- tibble(x = c(1, 2, 3), y = c(1, 3, 2))
257+
test_pl <- pl$LazyFrame(x = c(1, 2, 3), y = c(1, 3, 2))
258+
259+
expect_equal_lazy(
260+
test_pl |> filter(x %notin% y),
261+
test_df |> filter(x %notin% y)
262+
)
263+
})
264+
265+
test_that("%notin% works with NA", {
266+
test_df <- tibble(x = c(1, 2, NA))
267+
test_pl <- as_polars_lf(test_df)
268+
269+
expect_equal_lazy(
270+
test_pl |> filter(x %notin% c(1, NA)),
271+
test_df |> filter(x %notin% c(1, NA))
272+
)
273+
})
274+
217275
test_that("between() works", {
218276
test_df <- as_tibble(iris)
219277
# TODO: this shouldn't be necessary

tests/testthat/test-filter.R

Lines changed: 63 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -186,11 +186,6 @@ test_that("%in% works", {
186186
test_df |> filter(Species %in% c("setosa", "virginica"))
187187
)
188188

189-
expect_equal(
190-
test_pl |> filter(Species %in% c("setosa", "virginica")),
191-
test_df |> filter(Species %in% c("setosa", "virginica"))
192-
)
193-
194189
test_df <- tibble(x = c(1, 2, 3), y = c(1, 3, 2))
195190
test_pl <- pl$DataFrame(x = c(1, 2, 3), y = c(1, 3, 2))
196191

@@ -210,6 +205,69 @@ test_that("%in% works with NA", {
210205
)
211206
})
212207

208+
test_that("%notin% works", {
209+
test_df <- as_tibble(mtcars)
210+
test_pl <- as_polars_df(test_df)
211+
212+
expect_equal(
213+
filter(test_pl, cyl %notin% 4:5),
214+
filter(test_df, cyl %notin% 4:5)
215+
)
216+
217+
expect_equal(
218+
filter(test_pl, cyl %notin% 4:5 & am %notin% 1),
219+
filter(test_df, cyl %notin% 4:5 & am %notin% 1)
220+
)
221+
222+
expect_equal(
223+
filter(test_pl, cyl %notin% 4:5, am %notin% 1),
224+
filter(test_df, cyl %notin% 4:5, am %notin% 1)
225+
)
226+
227+
expect_equal(
228+
filter(test_pl, cyl %notin% 4:5 | am %notin% 1),
229+
filter(test_df, cyl %notin% 4:5 | am %notin% 1)
230+
)
231+
232+
expect_equal(
233+
filter(test_pl, cyl %notin% 4:5, vs == 1),
234+
filter(test_df, cyl %notin% 4:5, vs == 1)
235+
)
236+
237+
expect_equal(
238+
filter(test_pl, cyl %notin% 4:5 | carb == 4),
239+
filter(test_df, cyl %notin% 4:5 | carb == 4)
240+
)
241+
242+
test_df <- as_tibble(iris)
243+
# TODO: this shouldn't be necessary
244+
test_df$Species <- as.character(test_df$Species)
245+
test_pl <- as_polars_df(test_df)
246+
247+
expect_equal(
248+
test_pl |> filter(Species %notin% c("setosa", "virginica")),
249+
test_df |> filter(Species %notin% c("setosa", "virginica"))
250+
)
251+
252+
test_df <- tibble(x = c(1, 2, 3), y = c(1, 3, 2))
253+
test_pl <- pl$DataFrame(x = c(1, 2, 3), y = c(1, 3, 2))
254+
255+
expect_equal(
256+
test_pl |> filter(x %notin% y),
257+
test_df |> filter(x %notin% y)
258+
)
259+
})
260+
261+
test_that("%notin% works with NA", {
262+
test_df <- tibble(x = c(1, 2, NA))
263+
test_pl <- as_polars_df(test_df)
264+
265+
expect_equal(
266+
test_pl |> filter(x %notin% c(1, NA)),
267+
test_df |> filter(x %notin% c(1, NA))
268+
)
269+
})
270+
213271
test_that("between() works", {
214272
test_df <- as_tibble(iris)
215273
# TODO: this shouldn't be necessary

vignettes/supported-functions.Rmd

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ out <- tribble(
8585
"`base`", "`unique`",
8686
"`base`", "`which.min`",
8787
"`base`", "`which.max`",
88+
"`base`", "`%in%`",
89+
"`base`", "`%notin%`",
8890
"`dplyr`", "`between`",
8991
"`dplyr`", "`case_match`",
9092
"`dplyr`", "`case_when`",

0 commit comments

Comments
 (0)