Ggplot2: stat_summary throws an error when trying to pass an argument to a function as a parameter, rather than hard coding

I get an error when I try to pass a parameter to the round function inside stat_summary (although similar code works, say geom_text ). Here is an example:

 # Fake data set.seed(5) dat = data.frame(group=rep(c("A","B"),each=10), val=rnorm(20)) 

We will try to set the number of decimal places for value labels using a parameter rather than hard coding:

 places = 2 ggplot(dat, aes(group, val)) + stat_summary(fun.y=mean, geom="text", aes(label=round(..y.., places))) 

Error in eval (expr, envir, enc): "place" object not found

However, the following two examples work fine.

 ggplot(dat, aes(group, val)) + stat_summary(fun.y=mean, geom="text", aes(label=round(..y.., 2))) ggplot(dat, aes(group, val)) + geom_text(aes(label=round(val, places))) 

I ran into this problem while trying to write a ggplot function. At first, I thought the problem was that ggplot was not getting the parameter from the functional environment, but the above example suggests that this is not a problem. For completeness, below is a simplified example of a function along with an error message. The function works fine if I hard-code the argument of the digits round , instead of trying to pass the parameter places .

 pp1 = function(data, group, var, places=2, e=1.5) { ggplot(data, aes_string(group, var)) + geom_boxplot() + stat_summary(fun.y=mean, geom="text", aes(label=round(..y.., places))) + scale_y_continuous(limits = e * range(data[,var])) } pp1(dat, "group","val") 

Error in eval (expr, envir, enc): "place" object not found

I hope to find out that I am doing something wrong and how I can achieve the desired behavior.

I am running R 3.2.3 and ggplot2 2.1.0 on OS X 10.10.5.

+5
source share
1 answer

aes uses a non-standard estimate and thus tries to evaluate places in the data argument that you give it, However, its NSE depends on what you pass.

A typical way to bypass NSE is substitute , which, well, replaces the value inside the code. Then you can use eval to run the code:

 eval(substitute(ggplot(dat, aes(group, val)) + stat_summary(fun.y=mean, geom="text", aes(label=round(..y.., places))), list(places = places))) 

works as expected:

plot with labels

Hadley also provides several versions of SE aes : aes_ , aes_q and aes_string , which may allow you to avoid using substitute , but I could not evaluate ..y.. (If someone knows how to structure it, please comment and I will update.)

Hadley also created the lazyeval package , which is useful for managing NSE.

+2
source

Source: https://habr.com/ru/post/1244464/


All Articles