Chris Umphlett
Chris Umphlett

Reputation: 430

With dplyr and enquo my code works but not when I pass to purrr::map

I want to create a plot for each column in a vector called dates. My data frame contains only these columns and I want to group on it, count the occurrences and then plot it.

Below code works, except for map which I want to use to go across a previously unknown number of columns. I think I'm using map correctly, I've had success with it before. I'm new to using quosures but given that my function call works I'm not sure what is wrong. I've looked at several other posts that appear to be set up this way.

df <- data.frame(
  date1 = c("2018-01-01","2018-01-01","2018-01-01","2018-01-02","2018-01-02","2018-01-02"),
  date2 = c("2018-01-01","2018-01-01","2018-01-01","2018-01-02","2018-01-02","2018-01-02"),
  stringsAsFactors = FALSE
)
dates<-names(df)

library(tidyverse)

dates.count<-function(.x){
  group_by<-enquo(.x)
  df %>% group_by(!!group_by) %>% summarise(count=n()) %>% ungroup() %>% ggplot() + geom_point(aes(y=count,x=!!group_by))
}
dates.count(date1)
map(dates,~dates.count(.x))

I get this error: Error in grouped_df_impl(data, unname(vars), drop) : Column .x is unknown

Upvotes: 1

Views: 910

Answers (1)

aosmith
aosmith

Reputation: 36076

When you pass the variable names to map() you are using strings, which indicates you need ensym() instead of enquo().

So your function would look like

dates.count <- function(.x){
    group_by = ensym(.x)
    df %>% 
        group_by(!!group_by) %>% 
        summarise(count=n()) %>% 
        ungroup() %>% 
        ggplot() + 
        geom_point(aes(y=count,x=!!group_by))
}

And you would use the variable names as strings for the argument.

dates.count("date2")

Note that tidyeval doesn't always play nicely with the formula interface of map() (I think I'm remembering that correctly). You can always do an anonymous function instead, but in your case where you want to map the column names to a function with a single argument you can just do

map(dates, dates.count)

Using the formula interface in map() I needed an extra !!:

map(dates, ~dates.count(!!.x))

Upvotes: 1

Related Questions