Trying to write a relatively simple wrapper to produce some plots, but can not work out how to specify tidy evaluation of grouping variables specified as ...
an example function that facets variables but doesn't distinguish by grouping...
my_plot <- function(df = starwars,
select = c(height, mass),
...){
results <- list()
## Tidyeval arguments
quo_select <- enquo(select)
quo_group <- quos(...)
## Filter, reshape and plot
results$df <- df %>%
dplyr::filter(!is.na(!!!quo_group)) %>%
dplyr::select(!!quo_select, !!!quo_group) %>%
gather(key = variable, value = value, !!!quo_select) %>%
## Specify what to plot
ggplot(aes(value)) +
geom_histogram(stat = 'count') +
facet_wrap(~variable, scales = 'free', strip.position = 'bottom')
return(results)
}
## Plot height and mass as facets but colour histograms by hair_color
my_plot(df = starwars, select = c(height, mass), hair_color)
Great it works, but how to distinguish between different hair_color
? Normally this is done within aes()
but since this is using the results of quos()
(i.e. quo_group
) I should (I think) be using aes_()
instead
my_plot <- function(df = starwars,
select = c(height, mass),
...){
results <- list()
## Tidyeval arguments
quo_select <- enquo(select)
quo_group <- quos(...)
## Filter, reshape and plot
results$df <- df %>%
dplyr::filter(!is.na(!!!quo_group)) %>%
dplyr::select(!!quo_select, !!!quo_group) %>%
gather(key = variable, value = value, !!!quo_select) %>%
## Specify what to plot, including colouring by the supplied ... groupings
ggplot(aes_(~value, colour = !!!quo_group)) +
geom_histogram(stat = 'count') +
facet_wrap(~variable, scales = 'free', strip.position = 'bottom')
return(results)
}
## Plot height and mass as facets but colour histograms by hair_color
my_plot(df = starwars, select = c(height, mass), hair_color)
Error in !quo_group : invalid argument type
I can't see or work out having read Programming with dplyr several times now where I'm going wrong.
Can anyone point out my error/show me the way?
I'm not sure I understand the question. Does this satisfy the requirements?
library(ggplot2)
library(data.table)
your_plot <- function(df, select, color=NULL) {
df <- as.data.table(df)[, mget(na.omit(c(select, color)))]
ggplot(melt(df, color, select), aes_string(x=quote(value), color=color)) +
geom_histogram(stat="count") +
facet_wrap(~variable, scales="free", strip.position="bottom")
}
your_plot(dplyr::starwars, c("height", "mass"), "hair_color")
This uses melt
to stack the select
variables, with the color
variable(s) repeated for each stack. It also uses aes_string
, since aes(x=value, color=color)
fails when color=NULL
.
The new released ggplot2 v3.0.0
supports !!
inside aes()
. With some minor modification, your function is now working
library(tidyverse)
my_plot <- function(df = starwars,
select = c(height, mass),
...){
results <- list()
## Tidyeval arguments
quo_select <- enquo(select)
# only need quo here, if quos is used then we need to `unlist` to
# convert its output from list to vector
quo_group <- quo(...)
## Filter, reshape and plot
results$df <- df %>%
dplyr::filter(!is.na(!!!quo_group)) %>%
dplyr::select(!!quo_select, !!!quo_group) %>%
gather(key = variable, value = value, !!!quo_select) %>%
## Specify what to plot, including coloring by the supplied dots `...`
ggplot(aes(value, color = !!quo_group, fill = !!quo_group)) + # unquote inside aes
geom_histogram(stat = 'count') +
facet_wrap(vars(variable), scales = 'free', strip.position = 'bottom')
return(results)
}
## Plot height and mass as facets but color histograms by hair_color
my_plot(df = starwars, select = c(height, mass), hair_color)
Created on 2018-09-12 by the reprex package (v0.2.0.9000).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With