1

I wrote a code to create a plot

#Create a plot mean Calories in each Category
p<-mean_table %>%
  ggplot(aes(mean.Calories,reorder(Category, mean.Calories))) + 
  geom_col(aes(fill = mean.Calories)) + 
  scale_fill_gradient2(low = "forestgreen",
                       high = 'firebrick1',
                       mid = "gold", midpoint = 283.8947)+
  scale_x_continuous(breaks = seq(0, 600, length.out = 7),
                     limits = c(0, 600),
                     labels = seq(0, 600, length.out = 7))+
  xlab("Calories")+
  ylab("Category")+
  ggtitle("Mean of Calories in each Category")+
  theme_minimal()
#Theme for plots
theme<-theme(axis.title.x=element_text(size=16),
        axis.title.y = element_text(size = 16),
        axis.text.x = element_text(size = 12, color = "black"),
        axis.text.y = element_text(size = 12, color = "black"),
        panel.background = element_rect(color = "black"),
        plot.title = element_text(size = 20,hjust = 0.5),
        legend.position = "none")
#Calories+theme
p+theme 

It works well. We can see this plot enter image description here

But I'd like to write a function because I need several similar graphs. It's my variant:

p3<-function(data, x_data, breaks, xlab, title){
  my_plot<-data %>% 
    ggplot(aes(x_data,reorder(Category, x_data))) + 
    geom_col(aes(fill = x_data)) + 
    scale_fill_gradient2(low = "forestgreen",
                       high = 'firebrick1',
                       mid = "gold", midpoint = median(data$x_data))+
    scale_x_continuous(breaks = round(seq(0, breaks, length.out = 7)),
                     limits = c(0,  breaks),
                     labels = round(seq(0,  breaks, length.out = 7)))+
    xlab(xlab)+
    ylab("Category")+
    ggtitle(title)+
    theme_minimal()
  return(my_plot)
}
p3(mean_table, mean_table$mean.Cholesterol, 155, "Gram", "Mean of Fat in each Cholesterol")

I use data.frame like this(it's small version):

mean_table<-data.frame(Category=c("Beef & Pork","Beverages","Breakfast"), mean.Cholesterol=c(87.3333333, 0.5555556,     152.8571429))

Error:Elements must equal the number of rows or 1 Run rlang::last_error() to see where the error occurred.

1: Unknown or uninitialised column: x_data.

What is wrong with my function?

Ekaterina
  • 69
  • 8

1 Answers1

1

You need to use non-standard evaluation (NSE) while passing the column names to the function.

There are two ways in which you can pass the column names, unquoted and quoted column names. In this answer, we pass unquoted column names. We use curly-curly ({{}}) operator.

library(ggplot2)
library(rlang)

p3<-function(data, x_data, breaks, xlab, title){
    my_plot<-data %>% 
             ggplot(aes({{x_data}},reorder(Category, {{x_data}}))) + 
             geom_col(aes(fill = {{x_data}})) + 
             scale_fill_gradient2(low = "forestgreen",
                                 high = 'firebrick1',
                                 mid = "gold", 
                                  midpoint = median(data %>% pull({{x_data}}))) +
             scale_x_continuous(breaks = round(seq(0, breaks, length.out = 7)),
                                limits = c(0,  breaks),
                                labels = round(seq(0,  breaks, length.out = 7)))+
             xlab(xlab)+
             ylab("Category")+
             ggtitle(title) +
             theme_minimal()

   return(my_plot)
}

and call p3 as :

p3(mean_table, mean.Cholesterol, 155, "Gram", "Mean of Fat in each Cholesterol")

enter image description here

If we want to pass column names as quoted variables as "mean.Cholesterol" we can use sym and !! to evaluate it.

Ronak Shah
  • 377,200
  • 20
  • 156
  • 213