How to use a variable to specify column name in ggplot How to use a variable to specify column name in ggplot r r

How to use a variable to specify column name in ggplot


You can use aes_string:

f <- function( column ) {    ...    ggplot( rates.by.groups, aes_string(x="name", y="rate", colour= column,                                        group=column ) )}

as long as you pass the column to the function as a string (f("majr") rather than f(majr)). Also note that we changed the other columns, "name" and "rate", to be strings.

If for whatever reason you'd rather not use aes_string, you could change it to (the somewhat more cumbersome):

    ggplot( rates.by.groups, aes(x=name, y=rate, colour= get(column),                                        group=get(column) ) )


From the release notes of ggplot2 V3.0.0 :

aes() now supports quasiquotation so that you can use !!, !!!, and :=. This replaces aes_() and aes_string() which are now soft-deprecated (but will remain around for a long time).

The idiomatic way now would be to convert to a symbol the string that the variable contains, using sym()(which is almost the same as base aliases as.name() / as.symbol()), and unquote it using !!

Simulating OP's data we can do :

library(tidyverse)rates.by.groups <- data.frame(  name = LETTERS[1:3],  rate = 1:3,  mjr = LETTERS[c(4,4,5)],  gender = c("M","F","F"))f <- function(column) {  column <- sym(column)  ggplot(rates.by.groups,          aes(x = name,              y = rate,              fill  = !!column,              group = !!column)) +    geom_col()}f("gender")f("mjr")x <- "gender"f(x)

If we'd rather feed raw names to the function we can do:

f2 <- function(column) {  column <- ensym(column)  ggplot(rates.by.groups,          aes(x = name,              y = rate,              fill  = !!column,              group = !!column)) +    geom_col()}

It will work with names a.k.a. symbols AND with string literals

f2(gender)f2(mjr)f2("gender")f2("mjr")

As Lionel says about ensym():

it's meant to mimic the syntax of arguments where you can supply both in the LHS, e.g. list(bare = 1, "quoted" = 2)


A note on enquo()

enquo()quotes the expression (not necessarily a symbol) fed to the argument, it doesn't convert a string literal to a symbol as ensym() does so it might be less adapted here, but we can do :

f3 <- function(column) {  column <- enquo(column)  ggplot(rates.by.groups,          aes(x = name,              y = rate,              fill  = !!column,              group = !!column)) +    geom_col()}f3(gender)f2(mjr)


Another option (ggplot2 > 3.0.0) is to use the tidy evaluation pronoun .data to slice the chosen variable/column from the rates.by.groups data frame.

library(ggplot2)theme_set(theme_classic(base_size = 14))# created by @Moody_Mudskipperrates.by.groups <- data.frame(  name = LETTERS[1:3],  rate = 1:3,  mjr = LETTERS[c(4, 4, 5)],  gender = c("M", "F", "F"))f1 <- function(df, column) {  gg <- ggplot(df,          aes(x = name,              y = rate,              fill  = .data[[column]],              group = .data[[column]])) +    geom_col() +    labs(fill = column)  return(gg)}plot_list <- lapply(list("gender", "mjr"), function(x){ f1(rates.by.groups, x) })plot_list#> [[1]]

#> #> [[2]]

# combine all plotslibrary(egg)ggarrange(plots = plot_list,          nrow = 2,          labels = c('A)', 'B)'))

Created on 2019-04-04 by the reprex package (v0.2.1.9000)