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!
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:In your first example, there isn't any injection in the
mutate()call. Instead,!!!is triggered at thecoalesce()call insidecoacross(), and so the timing is correct.In your second example,
!!!is triggered at themutate()call. Injection is the very first thing that happens, which means thatmutate()hasn't had time yet to set up the data-masking context thatacross()needs, and so the timing is too late.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 tocoalesce()but that's rather ugly and very hard to understand:I prefer your
coacross()solution.