Skip to content

Commit

Permalink
Fix scoping issue with across() in nested mutates
Browse files Browse the repository at this point in the history
  • Loading branch information
lionel- committed Aug 31, 2020
1 parent 5ce3284 commit 1289bbf
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 12 deletions.
2 changes: 1 addition & 1 deletion R/across.R
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ across_setup <- function(cols, fns, names, key, .caller_env) {
# `across()` is evaluated in a data mask so we need to remove the
# mask layer from the quosure environment (#5460)
cols <- enquo(cols)
cols <- quo_set_env(cols, data_mask_top(quo_get_env(cols), recursive = TRUE, inherit = TRUE))
cols <- quo_set_env(cols, data_mask_top(quo_get_env(cols), recursive = FALSE, inherit = TRUE))

vars <- tidyselect::eval_select(cols, data = mask$across_cols())
vars <- names(vars)
Expand Down
29 changes: 18 additions & 11 deletions tests/testthat/test-across.R
Original file line number Diff line number Diff line change
Expand Up @@ -212,22 +212,29 @@ test_that("across() uses environment from the current quosure (#5460)", {
expect_equal(df %>% mutate(across(all_of(y), mean)), df)
expect_equal(df %>% filter(across(all_of(y), ~ .x < 2)), df)

# Recursive case
out <- df %>% summarise(summarise(across(), across(all_of(y), mean)))
expect_equal(out, data.frame(x = 1))
# Recursive case fails because the `y` column has precedence (#5498)
expect_error(df %>% summarise(summarise(across(), across(all_of(y), mean))))

# Inherited case
out <- df %>% summarise(local(across(all_of(y), mean)))
expect_equal(out, data.frame(x = 1))
})

# Recursive + inherited case
out <- df %>%
summarise(
local(
summarise(across(), across(all_of(y), mean))
)
)
expect_equal(out, data.frame(x = 1))
test_that("across() sees columns in the recursive case (#5498)", {
df <- tibble(
vars = list("foo"),
data = list(data.frame(foo = 1))
)

out <- df %>% mutate(data = purrr::map2(data, vars, ~ {
.x %>% mutate(across(all_of(.y), ~ NA))
}))
exp <- tibble(
vars = list("foo"),
data = list(data.frame(foo = NA))
)

expect_identical(out, exp)
})


Expand Down

0 comments on commit 1289bbf

Please sign in to comment.