1

Example:

library(dplyr)

df <- tibble(a = c(10, 10, 10, 20, 20),
             b = c(1, 2, 10, 2, 4))

## produces desired result:
df %>%
    group_by(a) %>%
    summarize(mn = mean(b), md = median(b))

stats <- function(x){
    list(mn = mean(x), md = median(x)) }

## object 'b' not found:
df %>%
    group_by(a) %>%
    summarize(!!! stats(b))

The call stats(b) does not see column b. What is the simplest solution that does not involve changing the stats function?

R version 3.4.3, dplyr version 0.7.2

scbagley
  • 158
  • 4
  • If you are attempting to summarize so that you have a mean column and median column, you could do: `summarize(mn = stats(b)[['mn']], md = stats(b)[['md']])` – C. Braun Mar 27 '18 at 15:35

1 Answers1

0

!!! is meant to change the call to a function. Which means it evaluates the target in the current environment in order to change the call before running it. You seem to want to use an on object returned after a function call. But in order to use things like b in that function call, you need to delay the evaluation of b till the function is actually run. So the !!! and the use of b both need to be evaluated a different times so you run into this problem.

This is something you still should be using do() for, see dplyr summarise() with multiple return values from a single function. For example you can do

df %>%
  group_by(a) %>%
  do(data.frame(stats(.$b)))

Or if you were to re-write the stats() function, it might look something like this

stats <- function(x){
  x <- enquo(x)
  quos(mn = mean(!!x), md = median(!!x)) }

df %>%
  group_by(a) %>%
  summarize(!!! stats(b))
MrFlick
  • 195,160
  • 17
  • 277
  • 295