问题
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!
回答1:
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) })
There's a few extra steps.
- Use
map2
instead ofmap
. The first argument is the dataframe you're passing it, and the second argument is a vector of thenames
of that dataframe, so it knows what tomap
over. (Alternately,imap(x, ...)
is a synonym formap2(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.
回答2:
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())
来源:https://stackoverflow.com/questions/45362462/how-do-pipes-work-with-purrr-map-function-and-the-dot-symbol