I am creating a custom function that generates bar plots using ggplot2
and geom_col()
.
My objective is to enable the function to dynamically assign either a single color or a color based on a grouping variable to the fill
aesthetic. Here's the code I've developed:
library(ggplot2)
library(dplyr)
library(RColorBrewer)
f1 <- function(data, x, y, z, single_color=FALSE, color="red") {
data <- data %>%
count({{x}})
if (single_color) {
p <- ggplot(data, aes(x = factor({{ x }}), y = {{ y }})) +
geom_col(width = 0.6, fill = color) +
theme_minimal()
} else {
p <- ggplot(data, aes(x = factor({{ x }}), y = {{ y }}, fill = factor({{ z }}))) +
geom_col(width = 0.6) +
theme_minimal() +
scale_fill_brewer(palette = "Set1")
}
return(p)
}
f1(mtcars, cyl, n, cyl, single_color=TRUE, color="blue")
f1(mtcars, cyl, n, cyl, single_color=FALSE)
I'm contemplating whether there's a more straightforward method, such as:
f1 <- function(data, x, y, z) {
z <- ensym(z)
ggplot(data, aes(x = factor({{x}}), y = {{y}}, fill= !!z)) +
geom_col(width = 0.6) +
scale_fill_brewer(palette = "Set1")
}
To summarize my question: Is it possible for z
to be both a column name and a string simultaneously?
Related link:
If I understand you correctly, you want the argument z
to be either a symbol representing a column name, or a string representing a color. I guess this is possible, though it's a little convoluted:
library(ggplot2)
f1 <- function(data, x, y, z) {
is_column <- deparse(substitute(z)) %in% names(data)
ggplot(data, aes(x = factor({{x}}), y = {{y}})) +
do.call("geom_col", c(list(width = 0.6),
if(is_column) list(mapping = aes(fill = factor({{z}}))),
if(!is_column) list(fill = z)))
}
Testing we get
f1(mtcars, cyl, mpg, cyl)
and
f1(mtcars, cyl, mpg, "blue")