Open romainfrancois opened 4 years ago
Now updated to match https://github.com/tidyverse/dplyr/pull/5524
Main thing is eval_hybrid()
that takes a quosure and an environment of (promises of) chops and then:
internal dplyr::::dplyr_eval_tidy_all
calls eval_hybrid()
and knows how to deal with it.
This now handles mean()
which calls grouped_mean()
if possible, n()
which can use list_sizes()
and hybrid()
which might stay or not, it's just a way to give code that operates on the chops instead of on each slice.
#' @export
eval_hybrid <- function(quo, chops) {
expr <- quo_get_expr(quo)
local_chops(chops)
# the function we meant to call
fn_meant <- eval_bare(node_car(expr),
env(quo_get_env(quo), hybrid = hybrid, `::` = `::`, `:::` = `:::`)
)
# hunt for an hybrid matcher for it
fn_hybrid <- NULL
for (fn in hybrid_functions) {
if (identical(fn_meant, fn$target)) {
fn_hybrid <- fn$match
break
}
}
# if we found one, try to call it, but it will however
# perform its own validation of inputs before calling an
# actual grouped_*() function
res <- NULL
if (!is.null(fn_hybrid)) {
expr <- node_poke_car(expr, fn_hybrid)
res <- eval_bare(expr)
}
if (!is.null(res) && is.null(attr(res, "ptype"))) {
attr(res, "ptype") <- vec_ptype_common(!!!res)
}
res
}
converted this to draft, we might come back to this idea later ...
:::list_ptype_common(x)
: gets the commonptype
of the slicesgrouped_mean()
which does one time dispatch based on that ptype, the point is to eventually implement things likegrouped_mean.double
internally, here it's just to toy dispatch.eval_summarise(expr = <expression>)
that tries to evaluateexpr
for all columns at once by recognizing known patterns, for now ifexpr
ismean(x = <column>, na.rm = <TRUE/FALSE>)
thengrouped_mean()
ends up being called withx = mask$resolve(<column>)
.eval_summarise()
is called bysummarise()
in https://github.com/tidyverse/dplyr/pull/5112I'll write some more about this and try to stress it with other functions, but I think it's going the right direction.