rtidyeval

why does across work with coalesce only when inside a function?


Little tidyeval question, I've got this function:

coacross <- function(...) {
  coalesce(!!!across(...))
}

And then if I do something like this:

aa = tibble(a1 = c(NA, 1), a2 = c(2, NA), b = 3:4) %>% 
mutate(a_full = coacross(starts_with('a')))

Works like a charm. But if I do the same outside a function, I get an error:

aa %>% mutate(c = coalesce(!!!across(starts_with('a'))))


Error in `across()`:
! Must only be used inside data-masking verbs like `mutate()`, `filter()`, and
  `group_by()`.

What gives? I'm a bit lost here. Thanks!


Solution

  • You've reached the obscure side of tidy eval programming :-/

    The problem is that !!! is evaluated very early by the first verb that happens to support injection operators:

    To work around this the overlap between injection contexts must be removed. This is what you did by moving the !!! in another function. An alternative is to inject a call to coalesce() but that's rather ugly and very hard to understand:

    aa |> mutate(c = !!quote(coalesce(!!!across(starts_with('a')))))
    

    I prefer your coacross() solution.