How do pipes work with purrr map() function and th

2019-04-29 12:09发布

When using both pipes and the map() function from purrr, I am confused about how data and variables are passed along. For instance, this code works as I expect:

library(tidyverse)

cars %>% 
  select_if(is.numeric) %>% 
  map(~hist(.))

Yet, when I try something similar using ggplot, it behaves in a strange way.

cars %>% 
  select_if(is.numeric) %>% 
  map(~ggplot(cars, aes(.)) + geom_histogram())

I'm guessing this is because the "." in this case is passing a vector to aes(), which is expecting a column name. Either way, I wish I could pass each numeric column to a ggplot function using pipes and map(). Thanks in advance!

2条回答
We Are One
2楼-- · 2019-04-29 12:24

You aren't supposed to pass raw data to an aesthetic mapping. Instead you should dynamically build the data.frame. For example

cars %>% 
  select_if(is.numeric) %>% 
  map(~ggplot(data_frame(x=.), aes(x)) + geom_histogram())
查看更多
霸刀☆藐视天下
3楼-- · 2019-04-29 12:36
cars %>% 
  select_if(is.numeric) %>% 
  map2(., names(.), 
       ~{ggplot(data_frame(var = .x), aes(var)) + 
           geom_histogram() + 
           labs(x = .y)                    })

# Alternate version
cars %>% 
  select_if(is.numeric) %>% 
  imap(.,
       ~{ggplot(data_frame(var = .x), aes(var)) + 
           geom_histogram() + 
           labs(x = .y)                    })

enter image description here

enter image description here

There's a few extra steps.

  • Use map2 instead of map. The first argument is the dataframe you're passing it, and the second argument is a vector of the names of that dataframe, so it knows what to map over. (Alternately, imap(x, ...) is a synonym for map2(x, names(x), ...). It's an "index-map", hence "imap".).
  • You then need to explicitly enframe your data, since ggplot only works on dataframes and coercible objects.
  • This also gives you access to the .y pronoun to name the plots.
查看更多
登录 后发表回答