tidyverse / funs

Collection of low-level functions for working with vctrs
Other
34 stars 7 forks source link

[shelved] grouped_mean() #50

Open romainfrancois opened 4 years ago

romainfrancois commented 4 years ago

eval_summarise() is called by summarise() in https://github.com/tidyverse/dplyr/pull/5112

I'll write some more about this and try to stress it with other functions, but I think it's going the right direction.

romainfrancois commented 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
}
romainfrancois commented 3 years ago

converted this to draft, we might come back to this idea later ...