Here is one solution and how I came to it.
What does group_by expect?
> group_by function (x, ..., add = FALSE) { new_groups <- named_dots(...)
Down the rabbit holes:
> dplyr:::named_dots function (...) { auto_name(dots(...)) } <environment: namespace:dplyr> > dplyr:::auto_name function (x) { names(x) <- auto_names(x) x } <environment: namespace:dplyr> > dplyr:::auto_names function (x) { nms <- names2(x) missing <- nms == "" if (all(!missing)) return(nms) deparse2 <- function(x) paste(deparse(x, 500L), collapse = "") defaults <- vapply(x[missing], deparse2, character(1), USE.NAMES = FALSE) nms[missing] <- defaults nms } <environment: namespace:dplyr> > dplyr:::names2 function (x) { names(x) %||% rep("", length(x)) }
Using this information, how to solve the problem?
# Naive solution fails: ChickWeight %>% do.call( group_by, list( Chick, Diet ) ) %>% summarise( mw = mean( weight ) )
The solution is to quote the arguments, so their evaluation is delayed until they are in an environment containing x tbl:
do.call( group_by, list( x = ChickWeight, quote(Chick), quote(Diet), add = FALSE ) ) %>% summarise( mw = mean( weight ) ) ## Bingo! v <- "Diet" do.call( group_by, list( x = ChickWeight, quote(Chick), substitute( a, list( a = v ) ), add = FALSE ) ) %>% summarise( mw = mean( weight ) )
source share