EN VI

Passing variable for ggplot2 as a function argument - not mapping levels to fill aesthetic correctly?

2024-03-17 09:00:04
How to Passing variable for ggplot2 as a function argument - not mapping levels to fill aesthetic correctly

I tried to refactor this code as a function, but it's not giving me the expected output. In the original code, the color levels are mapped to individual plots - the desired behavior. In the refactored code, I get a single plot with a single level color. There are no errors or anything, and I've used browser() inside the function call to confirm the levels using unique() and everything looks correct. Not sure why this isn't working.

Example Working Code:

#### Load and prep the data set####
data(diamonds)

### Create bins for carat ###
carat_bins <- seq(0, ceiling(max(diamonds$carat) * 2) / 2, by = 0.5)  

### Add the bins to the table ###
diamonds$carat_bin <- cut(diamonds$carat, breaks = carat_bins, include.lowest = TRUE)

#### Plot ####
ggplot(diamonds, aes(x = carat_bin, y = price, fill = color)) +
  geom_violin(position = "identity", alpha = 0.15) +
  labs(x = "Carat", y = "Price", fill = "Color") +
  ggtitle("Distribution of Diamond Prices by Carat and Color") +
  theme_minimal()

Example Refactored Code (function replaces Plot section above):

#### Plot Function ####
my_plot <- function(x_var, fill_var) {
  
  ### Ensure fill_var is factored ###
  diamonds[[fill_var]] <- factor(diamonds[[fill_var]])
  
  ggplot(diamonds, aes(x = x_var, y = price, fill = fill_var)) +
    geom_violin(position = "identity", alpha = 0.15)
}

#### Test ####
my_plot("carat_bin", "color")

Output from working code:

plot correctly factored by color level

Output from refactored code:

plot incorrectly ignoring color levels

Solution:

With !!ensym() (so that ggplot evaluates the strings as variables):

library(tidyverse)

data(diamonds)

### Create bins for carat ###
carat_bins <- seq(0, ceiling(max(diamonds$carat) * 2) / 2, by = 0.5)  

### Add the bins to the table ###
diamonds$carat_bin <- cut(diamonds$carat, breaks = carat_bins, include.lowest = TRUE)


#### Plot Function ####
my_plot <- function(x_var, fill_var) {
  
  ### Ensure fill_var is factored ###
  diamonds[[fill_var]] <- factor(diamonds[[fill_var]])
  
  ggplot(diamonds, aes(x = !!ensym(x_var), y = price, fill = !!ensym(fill_var))) +
    geom_violin(position = "identity", alpha = 0.15)
}

#### Test ####
my_plot("carat_bin", "color")

Created on 2024-03-16 with reprex v2.1.0

Answer

Login


Forgot Your Password?

Create Account


Lost your password? Please enter your email address. You will receive a link to create a new password.

Reset Password

Back to login