1

I need to have fixed number of decimals (two in this case) and I cannot make it work, I am aware of using round and accuracy function but it does not seem to work for me

code:

library(ggplot2)

ggplot(mtcars, aes(factor(cyl))) + 
  geom_bar(color = "steelblue", fill = "#00AFBB", na.rm = T) +
  scale_fill_discrete(drop=FALSE) +
  scale_x_discrete(drop=FALSE) +
  geom_text(aes(label=scales::percent(round(..count../sum(..count..),4))),
            stat='count',vjust = -0.5, size = 4)
NelsonGon
  • 13,015
  • 7
  • 27
  • 57
Petr
  • 1,606
  • 2
  • 14
  • 39
  • A rather weird "hack": `geom_text(aes(label=paste0(round(..count../sum(..count..) ,4) * 100,"%")), stat='count',vjust = -0.5, size = 4)` – NelsonGon Dec 18 '19 at 16:53

3 Answers3

5

This is built-in to scales::percent. There is an accuracy argument which is described as "the number to round to".

ggplot(mtcars, aes(factor(cyl))) + 
  geom_bar(color = "steelblue", fill = "#00AFBB", na.rm = T) +
  scale_fill_discrete(drop=FALSE) +
  scale_x_discrete(drop=FALSE) +
  geom_text(aes(label=scales::percent(..count../sum(..count..), accuracy = 0.01)),
            stat='count',vjust = -0.5, size = 4)
Gregor Thomas
  • 136,190
  • 20
  • 167
  • 294
  • I note that `percent` is "retired", what is the `label_percent` equivalent?(for learning purposes) – NelsonGon Dec 18 '19 at 16:57
  • Thank you - I was aware of accuracy argument, I just Did not know that the trick was to make it not `accuracy =3` but `0.03`. – Petr Dec 18 '19 at 17:01
  • 1
    @NelsonGon Ugh.. so many API changes. To the best of my knowledge, this will work with `scales::percent` or `scales::percent_format`. Looks like the new `scales::label_percent` is a functional, so the usage might be `label = label_percent(accuracy = 0.01)(..count../sum(..count..))`, but I'm not updating my package to test. – Gregor Thomas Dec 18 '19 at 17:05
  • 3
    @Petr, as kindly as possible, when you know of an argument and it doesn't seem to be working, check out the documentation. The explanation of `accuracy` is what I quote in the answer, "the number to round to", and if you scroll to the bottom of the help page to the examples section, the first few lines of examples illustrate use of the `accuracy` argument, contrasting `accuracy = 0.001` and `accuracy = 0.5`. – Gregor Thomas Dec 18 '19 at 17:06
  • I tried it but it complains about closures and replication. Usage is pretty much the same from the docs though. – NelsonGon Dec 18 '19 at 17:11
2

scales::percent has an accuracy argument.

library(ggplot2)

ggplot(mtcars, aes(factor(cyl))) + 
  geom_bar(color = "steelblue", fill = "#00AFBB", na.rm = T) +
  scale_fill_discrete(drop=FALSE) +
  scale_x_discrete(drop=FALSE) +
  geom_text(
    aes(label=scales::percent(round(..count../sum(..count..),4), accuracy = 0.01)),
        stat='count',vjust = -0.5, size = 4)
Fleur De Lys
  • 480
  • 2
  • 9
1

I would take matters into my own hands and create a function:

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

set.seed(123)
percent2(runif(1), accuracy = 0:5)
# "29%"       "28.8%"     "28.76%"    "28.758%"   "28.7578%"  "28.75775%"
bouncyball
  • 10,631
  • 19
  • 31