Skip to content

Commit d1cecde

Browse files
authored
Make usage of across() and data frames in filter() defunct (#7765)
* Advance usage of `across()` and data frames in `filter()` to defunct By removing support for data frames entirely, so now the incompatible type error is thrown. This nicely simplifies the `filter()` internals. * Remove unused `column_name` error field * Provide some extra advice for users of `across()`-in-`filter()`
1 parent 64152af commit d1cecde

File tree

7 files changed

+112
-203
lines changed

7 files changed

+112
-203
lines changed

NEWS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@
125125

126126
* The `keep` argument of `group_map()`, `group_modify()`, and `group_split()`. Deprecated in 1.0.0, use `.keep` instead.
127127

128+
* Using `across()` and data frames in `filter()`. Deprecated in 1.0.8, use `if_any()` or `if_all()` instead.
129+
128130
* `multiple = NULL` in joins. Deprecated in 1.1.1, use `multiple = "all"` instead.
129131

130132
* `multiple = "error" / "warning"` in joins. Deprecated in 1.1.1, use `relationship = "many-to-one"` instead.

R/filter.R

Lines changed: 15 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -231,12 +231,6 @@ filter_eval <- function(
231231
},
232232
`dplyr:::signal_filter_one_column_matrix` = function(e) {
233233
warn_filter_one_column_matrix(env = error_call, user_env = user_env)
234-
},
235-
`dplyr:::signal_filter_across` = function(e) {
236-
warn_filter_across(env = error_call, user_env = user_env)
237-
},
238-
`dplyr:::signal_filter_data_frame` = function(e) {
239-
warn_filter_data_frame(env = error_call, user_env = user_env)
240234
}
241235
)
242236

@@ -250,18 +244,25 @@ filter_bullets <- function(cnd, ...) {
250244

251245
#' @export
252246
`filter_bullets.dplyr:::filter_incompatible_type` <- function(cnd, ...) {
253-
column_name <- cnd$dplyr_error_data$column_name
254247
index <- cnd$dplyr_error_data$index
255248
result <- cnd$dplyr_error_data$result
256249

257-
if (is.null(column_name)) {
258-
input_name <- glue("..{index}")
259-
} else {
260-
input_name <- glue("..{index}${column_name}")
261-
}
262-
glue(
263-
"`{input_name}` must be a logical vector, not {obj_type_friendly(result)}."
250+
bullets <- cli::format_inline(
251+
"`..{index}` must be a logical vector, not {obj_type_friendly(result)}."
264252
)
253+
254+
if (is.data.frame(result)) {
255+
# Provide some extra advice for people who try and use `across()` inside
256+
# of `filter()`
257+
bullets <- c(
258+
bullets,
259+
i = cli::format_inline(
260+
"If you used {.fn across} to generate this data frame, please use {.fn if_any} or {.fn if_all} instead."
261+
)
262+
)
263+
}
264+
265+
bullets
265266
}
266267

267268
#' @export
@@ -283,27 +284,3 @@ warn_filter_one_column_matrix <- function(env, user_env) {
283284
always = TRUE
284285
)
285286
}
286-
287-
warn_filter_across <- function(env, user_env) {
288-
# TODO: https://github.com/tidyverse/dplyr/issues/7758
289-
lifecycle::deprecate_warn(
290-
when = "1.0.8",
291-
what = I("Using `across()` in `filter()`"),
292-
with = I("`if_any()` or `if_all()`"),
293-
always = TRUE,
294-
env = env,
295-
user_env = user_env
296-
)
297-
}
298-
299-
warn_filter_data_frame <- function(env, user_env) {
300-
# TODO: https://github.com/tidyverse/dplyr/issues/7758
301-
lifecycle::deprecate_warn(
302-
when = "1.0.8",
303-
what = I("Returning data frames from `filter()` expressions"),
304-
with = I("`if_any()` or `if_all()`"),
305-
always = TRUE,
306-
env = env,
307-
user_env = user_env
308-
)
309-
}

src/dplyr.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ SEXP eval_tidy(SEXP expr, SEXP data, SEXP env);
6464
SEXP as_data_pronoun(SEXP x);
6565
SEXP new_data_mask(SEXP bottom, SEXP top);
6666
SEXP str_as_symbol(SEXP);
67-
SEXP quo_get_expr(SEXP quo);
6867
void env_unbind(SEXP, SEXP);
6968
}
7069

src/filter.cpp

Lines changed: 3 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,10 @@ void stop_filter_incompatible_size(R_xlen_t i,
1717
static inline
1818
void stop_filter_incompatible_type(R_xlen_t i,
1919
SEXP quos,
20-
SEXP column_name,
2120
SEXP result){
22-
DPLYR_ERROR_INIT(3);
21+
DPLYR_ERROR_INIT(2);
2322
DPLYR_ERROR_SET(0, "index", Rf_ScalarInteger(i + 1));
24-
DPLYR_ERROR_SET(1, "column_name", column_name);
25-
DPLYR_ERROR_SET(2, "result", result);
23+
DPLYR_ERROR_SET(1, "result", result);
2624
DPLYR_ERROR_THROW("dplyr:::filter_incompatible_type");
2725
}
2826

@@ -37,14 +35,6 @@ static
3735
void signal_filter_one_column_matrix() {
3836
signal_filter("dplyr:::signal_filter_one_column_matrix");
3937
}
40-
static
41-
void signal_filter_across() {
42-
signal_filter("dplyr:::signal_filter_across");
43-
}
44-
static
45-
void signal_filter_data_frame() {
46-
signal_filter("dplyr:::signal_filter_data_frame");
47-
}
4838

4939
}
5040

@@ -105,41 +95,6 @@ bool filter_is_valid_lgl(SEXP x, bool first) {
10595
return false;
10696
}
10797

108-
static inline
109-
void filter_df_reduce(SEXP x,
110-
R_xlen_t n,
111-
bool first,
112-
R_xlen_t i_quo,
113-
SEXP quos,
114-
int* p_reduced) {
115-
if (first) {
116-
SEXP expr = rlang::quo_get_expr(VECTOR_ELT(quos, i_quo));
117-
const bool across = TYPEOF(expr) == LANGSXP && CAR(expr) == dplyr::symbols::across;
118-
119-
if (across) {
120-
dplyr::signal_filter_across();
121-
} else {
122-
dplyr::signal_filter_data_frame();
123-
}
124-
}
125-
126-
const SEXP* p_x = VECTOR_PTR_RO(x);
127-
const R_xlen_t n_col = Rf_xlength(x);
128-
129-
for (R_xlen_t i = 0; i < n_col; ++i) {
130-
SEXP col = p_x[i];
131-
132-
if (!filter_is_valid_lgl(col, first)) {
133-
SEXP names = PROTECT(Rf_getAttrib(x, R_NamesSymbol));
134-
SEXP name = PROTECT(Rf_ScalarString(STRING_ELT(names, i)));
135-
dplyr::stop_filter_incompatible_type(i_quo, quos, name, col);
136-
UNPROTECT(2);
137-
}
138-
139-
filter_lgl_reduce(col, n, p_reduced);
140-
}
141-
}
142-
14398
static
14499
SEXP eval_filter_one(SEXP quos,
145100
SEXP mask,
@@ -174,10 +129,8 @@ SEXP eval_filter_one(SEXP quos,
174129

175130
if (filter_is_valid_lgl(res, first)) {
176131
filter_lgl_reduce(res, n, p_reduced);
177-
} else if (Rf_inherits(res, "data.frame")) {
178-
filter_df_reduce(res, n, first, i, quos, p_reduced);
179132
} else {
180-
dplyr::stop_filter_incompatible_type(i, quos, R_NilValue, res);
133+
dplyr::stop_filter_incompatible_type(i, quos, res);
181134
}
182135

183136
UNPROTECT(2);

src/imports.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,6 @@ SEXP str_as_symbol(SEXP str) {
4343
return rlang_api().str_as_symbol(str);
4444
}
4545

46-
SEXP quo_get_expr(SEXP quo) {
47-
return rlang_api().quo_get_expr(quo);
48-
}
49-
5046
void env_unbind(SEXP env, SEXP sym) {
5147
rlang_api().env_unbind(env, sym);
5248
}

tests/testthat/_snaps/filter.md

Lines changed: 66 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -92,66 +92,6 @@
9292
i In argument: `c(TRUE, FALSE)`.
9393
Caused by error:
9494
! `..1` must be of size 150 or 1, not size 2.
95-
Code
96-
(expect_error(filter(group_by(iris, Species), data.frame(c(TRUE, FALSE)))))
97-
Output
98-
<error/rlang_error>
99-
Error in `filter()`:
100-
i In argument: `data.frame(c(TRUE, FALSE))`.
101-
i In group 1: `Species = setosa`.
102-
Caused by error:
103-
! `..1` must be of size 50 or 1, not size 2.
104-
Code
105-
(expect_error(filter(rowwise(iris), data.frame(c(TRUE, FALSE)))))
106-
Output
107-
<error/rlang_error>
108-
Error in `filter()`:
109-
i In argument: `data.frame(c(TRUE, FALSE))`.
110-
i In row 1.
111-
Caused by error:
112-
! `..1` must be of size 1, not size 2.
113-
Code
114-
(expect_error(filter(iris, data.frame(c(TRUE, FALSE)))))
115-
Output
116-
<error/rlang_error>
117-
Error in `filter()`:
118-
i In argument: `data.frame(c(TRUE, FALSE))`.
119-
Caused by error:
120-
! `..1` must be of size 150 or 1, not size 2.
121-
Code
122-
(expect_error(filter(tibble(x = 1), c(TRUE, TRUE))))
123-
Output
124-
<error/rlang_error>
125-
Error in `filter()`:
126-
i In argument: `c(TRUE, TRUE)`.
127-
Caused by error:
128-
! `..1` must be of size 1, not size 2.
129-
Code
130-
(expect_error(filter(group_by(iris, Species), data.frame(Sepal.Length > 3, 1:n())))
131-
)
132-
Condition
133-
Warning:
134-
Returning data frames from `filter()` expressions was deprecated in dplyr 1.0.8.
135-
i Please use `if_any()` or `if_all()` instead.
136-
Output
137-
<error/rlang_error>
138-
Error in `filter()`:
139-
i In argument: `data.frame(Sepal.Length > 3, 1:n())`.
140-
i In group 1: `Species = setosa`.
141-
Caused by error:
142-
! `..1$X1.n..` must be a logical vector, not an integer vector.
143-
Code
144-
(expect_error(filter(iris, data.frame(Sepal.Length > 3, 1:n()))))
145-
Condition
146-
Warning:
147-
Returning data frames from `filter()` expressions was deprecated in dplyr 1.0.8.
148-
i Please use `if_any()` or `if_all()` instead.
149-
Output
150-
<error/rlang_error>
151-
Error in `filter()`:
152-
i In argument: `data.frame(Sepal.Length > 3, 1:n())`.
153-
Caused by error:
154-
! `..1$X1.n..` must be a logical vector, not an integer vector.
15595
Code
15696
(expect_error(filter(mtcars, `_x`)))
15797
Output
@@ -209,24 +149,76 @@
209149
i In argument: `stop("{")`.
210150
Caused by error:
211151
! {
152+
153+
# Using data frames in `filter()` is defunct (#7758)
154+
212155
Code
213-
filter(data.frame(x = 1, y = 1), across(everything(), ~ .x > 0))
156+
filter(df, across(everything(), ~ .x > 0))
214157
Condition
215-
Warning:
216-
Using `across()` in `filter()` was deprecated in dplyr 1.0.8.
217-
i Please use `if_any()` or `if_all()` instead.
218-
Output
219-
x y
220-
1 1 1
158+
Error in `filter()`:
159+
i In argument: `across(everything(), ~.x > 0)`.
160+
Caused by error:
161+
! `..1` must be a logical vector, not a <tbl_df/tbl/data.frame> object.
162+
i If you used `across()` to generate this data frame, please use `if_any()` or `if_all()` instead.
163+
164+
---
165+
221166
Code
222-
filter(data.frame(x = 1, y = 1), data.frame(x > 0, y > 0))
167+
filter(gdf, across(everything(), ~ .x > 0))
223168
Condition
224-
Warning:
225-
Returning data frames from `filter()` expressions was deprecated in dplyr 1.0.8.
226-
i Please use `if_any()` or `if_all()` instead.
227-
Output
228-
x y
229-
1 1 1
169+
Error in `filter()`:
170+
i In argument: `across(everything(), ~.x > 0)`.
171+
i In group 1: `x = 1`.
172+
Caused by error:
173+
! `..1` must be a logical vector, not a <tbl_df/tbl/data.frame> object.
174+
i If you used `across()` to generate this data frame, please use `if_any()` or `if_all()` instead.
175+
176+
---
177+
178+
Code
179+
filter(rdf, across(everything(), ~ .x > 0))
180+
Condition
181+
Error in `filter()`:
182+
i In argument: `across(everything(), ~.x > 0)`.
183+
i In row 1.
184+
Caused by error:
185+
! `..1` must be a logical vector, not a <tbl_df/tbl/data.frame> object.
186+
i If you used `across()` to generate this data frame, please use `if_any()` or `if_all()` instead.
187+
188+
---
189+
190+
Code
191+
filter(df, tibble(x > 0, y > 0))
192+
Condition
193+
Error in `filter()`:
194+
i In argument: `tibble(x > 0, y > 0)`.
195+
Caused by error:
196+
! `..1` must be a logical vector, not a <tbl_df/tbl/data.frame> object.
197+
i If you used `across()` to generate this data frame, please use `if_any()` or `if_all()` instead.
198+
199+
---
200+
201+
Code
202+
filter(gdf, tibble(x > 0, y > 0))
203+
Condition
204+
Error in `filter()`:
205+
i In argument: `tibble(x > 0, y > 0)`.
206+
i In group 1: `x = 1`.
207+
Caused by error:
208+
! `..1` must be a logical vector, not a <tbl_df/tbl/data.frame> object.
209+
i If you used `across()` to generate this data frame, please use `if_any()` or `if_all()` instead.
210+
211+
---
212+
213+
Code
214+
filter(rdf, tibble(x > 0, y > 0))
215+
Condition
216+
Error in `filter()`:
217+
i In argument: `tibble(x > 0, y > 0)`.
218+
i In row 1.
219+
Caused by error:
220+
! `..1` must be a logical vector, not a <tbl_df/tbl/data.frame> object.
221+
i If you used `across()` to generate this data frame, please use `if_any()` or `if_all()` instead.
230222

231223
# `filter()` doesn't allow data frames with missing or empty names (#6758)
232224

0 commit comments

Comments
 (0)