2

I'm using the following code to create two side-by-side pie-charts

library(ggplot2)
mtcars$cyl <- factor(mtcars$cyl) # converts to a categorical variable
mtcars$gear <- factor(mtcars$gear) # converts to a categorical variable

p <- ggplot(data=mtcars, aes(x=factor(1), stat="bin", fill=cyl)) + geom_bar(position="fill") # Stacked bar chart
p <- p + ggtitle("Cylinders by Gears") + xlab("") + ylab("Gears") # Adds titles
p <- p + facet_grid(facets=. ~ gear) 
p <- p + coord_polar(theta="y") + theme_void()
p

This works well, but unfortunately I need to do this programmatically. In particular, I need to be able to change "fill = cyl" and "facets = .~ gear" to other variables, as part of a function. Ideally, I could pass variables names as strings to the code above.

I've tried to use aes_string() and quote/substitute, but get unanticipated results each time. Please advise.

Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
Zhaochen He
  • 610
  • 4
  • 12

2 Answers2

2

For fill argument we can use sym to convert string to symbol and then evaluate it with !! whereas for facet_grid we can use reformulate.

library(ggplot2)
library(rlang)

apply_fun <- function(data, fill_col, facet_col) {
   ggplot(data=data, aes(x=factor(1), stat="bin", fill= !!sym(fill_col))) + 
        geom_bar(position="fill")  + 
        ggtitle("Cylinders by Gears") + xlab("") + ylab("Gears") +
        facet_grid(reformulate(facet_col, ".")) +
        coord_polar(theta="y") + theme_void()
}

apply_fun(mtcars, "cyl", "gear")

enter image description here

Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
  • Great. It works (as long as you convert the variables to factors first)! Would never have figured that out on my own. – Zhaochen He Dec 24 '19 at 11:16
1

you can define your variables before the plot function:

Var1 = "cyl"
Var2 = "gear"

And then use these variables in your plotting dunction:

ggplot(data=mtcars, aes(x=factor(1), stat="bin", fill=mtcars[,Var1])) + 
  geom_bar(position="fill") + 
  ggtitle("Cylinders by Gears") + xlab("") + ylab("Gears") + 
  facet_grid(facets=. ~ mtcars[,Var2]) + 
  coord_polar(theta="y") + theme_void()

If you want to write a function using this, you can do:

plot_function = function(dataset,Var1,Var2) {
  ggplot(data=dataset, aes(x=factor(1), stat="bin", fill=dataset[,Var1])) + 
    geom_bar(position="fill") + 
    ggtitle(paste0(Var1, " by ", Var2)) + xlab("") + ylab(Var2) + 
    guides(fill = guide_legend(title = Var1))+
    facet_grid(facets=. ~ dataset[,Var2]) + 
    coord_polar(theta="y") + theme_void()
}

And use it like this:

plot_function(mtcars, "cyl","gear")

Does it answer your question ?

dc37
  • 15,840
  • 4
  • 15
  • 32