为什么across只能在函数内部使用coalesce?

yfjy0ee7  于 2023-06-03  发布在  其他
关注(0)|答案(1)|浏览(302)

小tidyeval问题,我有这个功能:

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

然后如果我这样做:

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

很管用。但是如果我在函数外做同样的事情,我会得到一个错误:

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()`.

怎么回事?我有点迷路了。谢谢!

iqxoj9l9

iqxoj9l91#

你已经达到了整洁的eval编程的晦涩的一面:-/
问题是!!!很早就被第一个恰好支持注入操作符的动词求值了:

  • 在第一个示例中,mutate()调用中没有任何注入。相反,!!!是在coacross()内部的coalesce()调用时触发的,因此时序是正确的。
  • 在第二个示例中,!!!mutate()调用时被触发。注入是第一件发生的事情,这意味着mutate()还没有时间设置across()需要的数据屏蔽上下文,因此时机已经太晚了。

为了解决这个问题,必须删除注入上下文之间的重叠。这就是您通过在另一个函数中移动!!!所做的。另一种方法是注入一个对coalesce()的调用,但这相当难看,也很难理解:

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

我更喜欢你的coacross()解决方案。

相关问题