Skip to content

Commit 18b1294

Browse files
authored
Implement filter_out() (#7775)
* Implement `filter_out()` * Document `filter_out()` * Revise examples * Overhaul tests to include `filter_out()` * Add to list of `.by` supported verbs * Mention in extending dplyr docs * Mention in `across()` example * Test alongside `pick()` * Test alongside `rowwise()` * Use `filter_out()` in a few vignettes * Mark `filter_out()` as experimental * NEWS bullet * Add complement test * Fix NEWS example BECAUSE THIS IS HARD Y'ALL * Apply documentation updates from code review * Remove `filter_out()` defunct tests
1 parent f20c2aa commit 18b1294

File tree

22 files changed

+811
-179
lines changed

22 files changed

+811
-179
lines changed

NAMESPACE

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ S3method(filter_,data.frame)
6161
S3method(filter_,tbl_df)
6262
S3method(filter_bullets,"dplyr:::filter_incompatible_size")
6363
S3method(filter_bullets,"dplyr:::filter_incompatible_type")
64+
S3method(filter_out,data.frame)
6465
S3method(full_join,data.frame)
6566
S3method(group_by,data.frame)
6667
S3method(group_by_,data.frame)
@@ -281,6 +282,7 @@ export(filter_)
281282
export(filter_all)
282283
export(filter_at)
283284
export(filter_if)
285+
export(filter_out)
284286
export(first)
285287
export(full_join)
286288
export(funs)

NEWS.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,23 @@
11
# dplyr (development version)
22

3+
* New `filter_out()` companion to `filter()`.
4+
5+
* Use `filter()` when specifying rows to _keep_.
6+
7+
* Use `filter_out()` when specifying rows to _drop_.
8+
9+
`filter_out()` simplifies cases where you would have previously used a `filter()` to drop rows. It is particularly useful when missing values are involved. For example, to drop rows where the `count` is zero:
10+
11+
```r
12+
df |> filter(count != 0 | is.na(count))
13+
14+
df |> filter_out(count == 0)
15+
```
16+
17+
With `filter()`, you must provide a "negative" condition of `!= 0` and must explicitly guard against accidentally dropping rows with `NA`. With `filter_out()`, you directly specify rows to drop and you don't have to guard against dropping rows with `NA`, which tends to result in much clearer code.
18+
19+
This work is a result of [Tidyup 8: Expanding the `filter()` family](https://github.com/tidyverse/tidyups/pull/30), with a lot of great feedback from the community (#6560, #6891).
20+
321
* The `.groups` message emitted by `summarise()` is hopefully more clear now (#6986).
422

523
* `if_any()` and `if_all()` are now more consistent in all use cases (#7059, #7077, #7746, @jrwinget). In particular:

R/across.R

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,12 @@
204204
#' iris |>
205205
#' filter(if_any(ends_with("Width"), ~ . > 4))
206206
#' iris |>
207+
#' filter_out(if_any(ends_with("Width"), ~ . > 4))
208+
#'
209+
#' iris |>
207210
#' filter(if_all(ends_with("Width"), ~ . > 2))
211+
#' iris |>
212+
#' filter_out(if_all(ends_with("Width"), ~ . > 2))
208213
#'
209214
#' @export
210215
#' @seealso [c_across()] for a function that returns a vector

R/data-mask.R

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,11 +116,12 @@ DataMask <- R6Class(
116116
eval()
117117
},
118118

119-
eval_all_filter = function(quos, env_filter) {
119+
eval_all_filter = function(quos, invert, env_filter) {
120120
eval <- function() {
121121
.Call(
122122
`dplyr_mask_eval_all_filter`,
123123
quos,
124+
invert,
124125
private,
125126
private$size,
126127
env_filter

0 commit comments

Comments
 (0)