Skip to content

Commit fbe4a4b

Browse files
authored
Switch if_else() to vec_if_else() (#7723)
* Switch `if_else()` to `vec_if_else()` * NEWS bullet * Regenerate snapshots with r-lib/vctrs#2049 * NEWS bullet about `condition`
1 parent 29d3766 commit fbe4a4b

File tree

6 files changed

+35
-22
lines changed

6 files changed

+35
-22
lines changed

DESCRIPTION

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ Imports:
3434
tibble (>= 3.2.0),
3535
tidyselect (>= 1.2.0),
3636
utils,
37-
vctrs (>= 0.6.4)
37+
vctrs (>= 0.6.5.9000)
3838
Suggests:
3939
bench,
4040
broom,
@@ -66,3 +66,5 @@ Encoding: UTF-8
6666
LazyData: true
6767
Roxygen: list(markdown = TRUE)
6868
RoxygenNote: 7.3.3
69+
Remotes:
70+
r-lib/vctrs

NEWS.md

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

3+
* `if_else()` no longer allows `condition` to be a logical array. It must be a logical vector with no `dim` attribute (#7723).
4+
5+
* `if_else()` has gotten significantly faster and uses much less memory due to a rewrite in C via `vctrs::vec_if_else()` (#7723).
6+
37
* Passing `size` to `if_else()` is now deprecated. The output size is always taken from the `condition` (#7722).
48

59
* `bind_rows()` now replaces empty (or `NA`) element names in a list with its numeric index while preserving existing names (#7719, @Meghansaha).

R/if-else.R

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
#' `FALSE`, the matching values from `false`, and where it is `NA`, the matching
3636
#' values from `missing`, if provided, otherwise a missing value will be used.
3737
#'
38+
#' @seealso [vctrs::vec_if_else()]
39+
#'
3840
#' @export
3941
#' @examples
4042
#' x <- c(-5:5, NA)
@@ -66,26 +68,12 @@ if_else <- function(
6668
lifecycle::deprecate_warn("1.2.0", "if_else(size = )")
6769
}
6870

69-
# Assert early since we `!` the `condition`
70-
check_logical(condition)
71-
72-
conditions <- list(
71+
vec_if_else(
7372
condition = condition,
74-
!condition
75-
)
76-
values <- list(
7773
true = true,
78-
false = false
79-
)
80-
81-
vec_case_when(
82-
conditions = conditions,
83-
values = values,
84-
conditions_arg = "",
85-
values_arg = "",
86-
default = missing,
87-
default_arg = "missing",
74+
false = false,
75+
missing = missing,
8876
ptype = ptype,
89-
call = current_env()
77+
error_call = current_env()
9078
)
9179
}

man/if_else.Rd

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/_snaps/if-else.md

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,29 +22,37 @@
2222
Error in `if_else()`:
2323
! `condition` must be a logical vector, not an integer vector.
2424

25+
# `condition` can't be an array (#7723)
26+
27+
Code
28+
if_else(array(TRUE), 1, 2)
29+
Condition
30+
Error in `if_else()`:
31+
! `condition` must be a logical vector, not a logical vector.
32+
2533
# `true`, `false`, and `missing` must recycle to the size of `condition`
2634

2735
Code
2836
if_else(x < 2, bad, x)
2937
Condition
3038
Error in `if_else()`:
31-
! `true` must have size 3, not size 2.
39+
! Can't recycle `true` (size 2) to size 3.
3240

3341
---
3442

3543
Code
3644
if_else(x < 2, x, bad)
3745
Condition
3846
Error in `if_else()`:
39-
! `false` must have size 3, not size 2.
47+
! Can't recycle `false` (size 2) to size 3.
4048

4149
---
4250

4351
Code
4452
if_else(x < 2, x, x, missing = bad)
4553
Condition
4654
Error in `if_else()`:
47-
! `missing` must have size 3, not size 2.
55+
! Can't recycle `missing` (size 2) to size 3.
4856

4957
# must have empty dots
5058

tests/testthat/test-if-else.R

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,14 @@ test_that("`condition` must be logical (and isn't cast to logical!)", {
7474
})
7575
})
7676

77+
test_that("`condition` can't be an array (#7723)", {
78+
expect_snapshot(error = TRUE, {
79+
# TODO: Error message will improve with
80+
# https://github.com/r-lib/rlang/pull/1832
81+
if_else(array(TRUE), 1, 2)
82+
})
83+
})
84+
7785
test_that("`true`, `false`, and `missing` must recycle to the size of `condition`", {
7886
x <- 1:3
7987
bad <- 1:2

0 commit comments

Comments
 (0)