I got this message "Error in FUN(X[[i]], ...) : object 'share' not found" when running ggplot2 inside a function. It works fine if I run it outside a function.
Any idea? Thanks so much!
NOTE: I need to pass 'share' as an argument since this function will be applied to some other variables besides 'share'.
df <- data.frame(own.manu = c("AO", "AO", "AO", "Own", "Own"), brand = c('A', "B", "C", "D", "E"), share = c(.1, .2, .3, .25, .15))
createPlot <- function(myvar, mydata) {
out <- ggplot2::ggplot(environment=environment()) +
ggplot2::geom_bar(ggplot2::aes(y = myvar, x = own.manu, fill = brand), stat = "identity", position = ggplot2::position_stack(reverse = TRUE), data = mydata) +
ggplot2::scale_y_continuous(labels = scales::percent_format()) +
ggplot2::geom_text(data = mydata, ggplot2::aes(x = own.manu,
y = myvar,
label = ifelse(myvar >= 0.05, paste0(sprintf("%.0f", myvar*100),"%"),"")),
position = ggplot2::position_stack(vjust=0.5))
out
}
out2 <- createPlot(myvar = share, mydata = df)
I recently ran into a similar issue, and think I might be able to help -- could you provide the example you mentioned that worked outside of the function, @ktanizar, so I can make sure I can generate the right output?
It works! Thank you! One follow-up question: why do we need to use double curly bracket only for 'myvar'? Why not use it for 'own.manu' and 'brand' also?
@ktanizar. It is about the concept of tidy evaluation which you can refer to the following https://tidyeval.tidyverse.org/sec-up-to-speed.html#quote-and-unquote and https://www.tidyverse.org/blog/2019/06/rlang-0-4-0/.
Simply, ggplot is based on a quoted expression. So, when it evaluate, the expression only contains myvar, not the value inside (share). Double curly or called curly curly unquote the myvar and evaluate it's value, then enquoted again by aes. However, own.manu and brand are not variable and no need evaluation before enquote. I hope I can make myself clear.
This is partly your choice: If you always expect your tables to have own.manu and brand columns, and a column with data similar to share's but maybe with a different name, then your function fits the bill. But if you wanted a function that works on tables with similar data but different column names, then you'd want to use {{ for them, too.