D Pinto
D Pinto

Reputation: 901

Lazy evaluation when writing functions with dplyr

I want to write a function using dplyr functions to output how many unique tuples (z, y) each element from z has. The function would look like this

library(tidyverse)

data <- data_frame(z = rep(c('a', 'b'), 50), 
       y = sample(letters[13:18], size = 100, T))

foo1 <- function(data, x, n){

  library(lazyeval)
  data %>%
    group_by_(lazy(n, x)) %>%
    filter(row_number() == 1) %>%
    ungroup() %>% 
    group_by_(lazy(x)) %>%
    summarise(nr_x = n()) %>%
    arrange(desc(nr_x))

}

foo1(data, x = z, n = y)

But I receive the following error:

Error in as.lazy_dots(list(...)) : object 'z' not found 

This simpler function, which seems very similar to the previous, works fine.

foo <- function(data, x, n){

  library(lazyeval)
  data %>%
    group_by_(lazy(n, x)) %>%
    summarise(n = n())
}

Any ideas how to fix that?

Upvotes: 2

Views: 1147

Answers (1)

D Pinto
D Pinto

Reputation: 901

Coming back to this question 8 months later, I don't get the error I used to get while running foo1. No idea why.

But I decided to solve this problem using the more recent tidyeval approach. The following works for me just fine:

library(tidyverse)

data <- data_frame(z = rep(c('a', 'b'), 50), 
   y = sample(letters[13:18], size = 100, T))

foo_tidyeval <- function(data, x, n){
  x <- enquo(x)
  n <- enquo(n)

  data %>%
    group_by(!!n, !!x) %>%
    filter(row_number() == 1) %>%
    ungroup() %>% 
    group_by_(x) %>%
    summarise(nr_x = n()) %>%
    arrange(desc(nr_x))
}

foo_tidyeval(data, x = z, n = y)

Upvotes: 2

Related Questions