【发布时间】:2017-07-14 20:08:45
【问题描述】:
Dplyr 的 mutate 函数可以计算“链式”表达式,例如
library(dplyr)
data.frame(a = 1) %>%
mutate(b = a + 1, c = b * 2)
## a b c
## 1 1 2 4
如何实现?快速浏览一下 dplyr 的源代码,可以发现候选代码的基本结构:
library(lazyeval)
library(rlang)
compat_as_lazy <- function(quo) {
structure(class = "lazy", list(
expr = f_rhs(quo),
env = f_env(quo)
))
}
compat_as_lazy_dots <- function(...) {
structure(class = "lazy_dots", lapply(quos(...), compat_as_lazy))
}
my_mutate <- function(.data, ...) {
lazy_eval(compat_as_lazy_dots(...), data = .data)
}
data.frame(a = 1) %>%
my_mutate(b = a + 1, c = b * 2)
## Error in eval(x$expr, data, x$env) : object 'b' not found
...但是这种“幼稚”的实现不起作用,mutate_impl 背后的 C++ 代码非常复杂。我知道它不起作用,因为"lazy_dots" 上的lazy_eval 使用lapply,即每个表达式都相互独立地评估,而我宁愿需要链式评估并将结果返回到共享环境。如何让它发挥作用?
【问题讨论】:
-
哦,您正在尝试制作自己的变异函数....