1

I cannot find an answer to this simple problem:

I want to create a ggplot. The aes parameter come partially from vector and partially are assigned directly.

names(mydt)
"gender"     "cat1"        "category_b"    "value"


category_a <- "cat1"

plot.sum <- mydt %>%
  dplyr::group_by(category_a, category_b) %>%
  ggplot(aes(x = category_a, y = N, fill = category_b)) +
  geom_bar(position="stack", stat="identity") 
plot.sum

This does not work and i get an error:

Error: Column category_a is unknown

I assume this is because R expects category_a to be a column in mydt and instead it gets an character item from a vector "cat1", which does not exist in mydt - correct me if i am wrong?

How can this be fixed?

The ultimate goal is to make this to a function:

make.plot.sum <- function (data, group_by1, group_by2, position){

data %>%
  dplyr::group_by(group_by1, group_by2) %>%
  ggplot(aes(x = group_by1, y = N, fill = group_by2)) +
    geom_bar(position="position", stat="identity") 
  plot.sum

  return(plot.sum)

}

make.plot.sum(mydt, category_a, category_b, stack)
3
  • Have you tried aes(x = {{group_by1}}, y = N, fill = {{group_by2}})? Commented Apr 12, 2020 at 20:53
  • @teunbrand i am not sure what the {{}} stand for, buut it seems like eit converts the group_by1 t plain text, but it was originally a factor with about 15 levels Commented Apr 12, 2020 at 21:32
  • Alright and aes(x = .data[[group_by1]], y = N, fill = .data[[group_by2]])? I think the post on this piece of nonstandard evaluation can be found here: tidyverse.org/blog/2019/06/rlang-0-4-0 Commented Apr 12, 2020 at 21:47

2 Answers 2

1

You are correct: the issue is likely due to passing a character "cat1" to aes(), when aes() expects you to pass a column name (i.e. cat1 without any quotes). If you want to pass info to aes(... as a character, you can use aes_string(...) in place of aes(): just make sure that when you use aes_string(), all the parameters are character vectors, and for aes(), all parameters are references to column names in your dataframe.

Side Note: I'm not actually sure if you can combine aes() and aes_string(...), in case you are wondering... I've never tried it. So, like can you say aes(x=cat1), then aes_string(y='cat2')? Not sure.

Sign up to request clarification or add additional context in comments.

Comments

0

chemdorks123s answer is a great one - but it is worth pointing out that aes_string is considered soft decrecated in favor of new idioms.

In your situation, where you want the user to pass a column into aes, you can use curly braces ({{}}).

make.plot.sum <- function (data, group_by1, group_by2, position){

data %>%
  dplyr::group_by(group_by1, group_by2) %>%
  ggplot(aes(x = {{group_by1}}, y = N, fill = {{group_by2}})) +
    geom_bar(position="position", stat="identity") 
  plot.sum

  return(plot.sum)

}

There's a lot more info in one of the ggplot2 vignettes - Using ggplot2 in packages

3 Comments

as i was just commenting to @teunbrand who proposed this solution (see above), this acts as if the factor group_by1 had only one level, when it acttually has multiple leevels
Can you expand on what you expect the group_by to do? Its been a while since I've looked, but I dont think ggplot2 understands groups created by dplyr. Does it work like you expect outside of the function? If you're wanting to create multiple plots based on a factor level, it would make more sense to pass the grouping into a facet
@Conoe Neilson it works fine, before when i use cat1 instead of instead of category_a in the plot. As soon as i use category_a <- cat1 , i get the error.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.