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

727 Views Asked by At

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

1

There are 1 best solutions below

1
On BEST ANSWER

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))