1

I'm not happy with scales::percent, for example, scales::percent(21/80) returns "26.2%" while I'd prefer getting "26.25%". So I wrote a quick function:

custom_percent <- function(x, digits = 2) {
  paste0(round(100 * x, digits = digits), "%")
}

However, when I try to use it with ggplot2, I receive the following error "Error in eval(expr, envir, enclos) : could not find function "custom_percent". Here is an example:

dset <- data.frame(data = 10:90)
p <- ggplot(dset, aes(x = data))
p + geom_bar(aes(y = (..count..)/sum(..count..)), width = .5) +
  geom_text(aes(y = ((..count..)/sum(..count..)),
            label = custom_percent((..count..)/sum(..count..))),
            stat = "count", vjust = -0.25) +
  scale_y_continuous(labels = custom_percent)

What can I do to access custom_percent?

green diod
  • 1,399
  • 3
  • 14
  • 29
  • I'm not sure if it's a problem with `ggplot` not being able to find the custom function. For example, `d <- data.frame(x=1:10, y=rnorm(10))` and then `ggplot(d) + geom_text(aes(x, y, label = custom_percent(y)))` works perfectly fine. – Weihuang Wong Oct 23 '16 at 00:23
  • It seems like a problem that's specific to using the special variables (like `..count..`) together with a custom function. Interesting. – Weihuang Wong Oct 23 '16 at 00:34
  • It was unexpected as when I used `scales::percent` everywhere instead, it just worked. But then `scales` was by the same author who wrote `ggplot2` so maybe he used a trick in both. – green diod Oct 23 '16 at 07:07
  • it sounded like setting an [environment](http://stackoverflow.com/a/10662937/471093) should have helped, but it doesn't appear to work – baptiste Oct 23 '16 at 19:58
  • Hi @baptiste, actually, given **all** the questions about capturing arguments or local variables in `aes`, that was the first path I tried. And of course it miserably failed. Maybe because, in my case, the `ggplot` and `aes` calls were not inside a function definition. – green diod Oct 24 '16 at 07:06

1 Answers1

2

aes_q and bquote can help with these tricky scoping issues,

dset <- data.frame(data = 10:90)
p <- ggplot(dset, aes(x = data))
p + geom_bar(aes_(y = ~(..count..)/sum(..count..)), width = .5) +
  geom_text(aes_(y = ~((..count..)/sum(..count..)),
                label = bquote(.(custom_percent)((..count..)/sum(..count..)))),
            stat = "count", vjust = -0.25) +
  scale_y_continuous(labels = custom_percent)
Community
  • 1
  • 1
baptiste
  • 75,767
  • 19
  • 198
  • 294