Conditional aes in ggplot

Is there away to add a conditional aes to a ggplot?

I am trying to build a function that generates a kernel plot but I want allow the function user the option to toggle weights on and off. I know I could write it as

if ( toggle_on = TRUE) { ggoplot with weighting) else if (toggle_on = FALSE) {ggplot without weights)

But I don't like this because I have to copy the plot code twice which gives an opportunity for the versions of the plot with and without weights to diverge if someone else later on changes one and forgets to change the other.
I would prefer a solution like this:

ggplot(plot_data, aes(x=value)) +
   geom_density(aes( if(toggle_on = TRUE){weights = weight_value}))

This is the actual code for my plot unconditioned and with weights.

ggplot(plot_data, aes(x=value, color=!!sym(plot_type))) +
    geom_density(aes(y=after_stat(count), weight = !!sym(pop_units)), kernel="epanechnikov", bw=5, linewidth = 1)

Below is one way to alter a plot via a function argument without having to rewrite the plot. Rather than making the "toggle" adjustment in the plot function, the adjustment can be made in the data prior to plotting. The altered column is then passed to the aes argument (size in this example).


# sample data
plot_data = mtcars

create_plot = function(toggle = FALSE) {
  plot_df = plot_data %>% 
    rowwise() %>%
    mutate(point_size = ifelse(toggle == T, hp, am)) %>%
  ggplot(plot_df, aes(x = mpg, y = qsec)) +
    geom_point(aes(size = point_size))

Both outcomes shown below.

Created on 2023-02-07 with reprex v2.0.2.9000

you can do an inline if, but not within aes but just immediately around it; since the aes itself is an optional thing.

lapply(c(FALSE, TRUE), \(toggle){
  ggplot(diamonds, aes(x = carat)) +
    geom_density(if (toggle) {
      aes(weight = price)
}) |>
  plot_grid(plotlist = _,labels=c(FALSE, TRUE),label_x=.4)

This topic was automatically closed 54 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.