ggplot() scaling with scale::percent_format() producing strange results
Solution 1
First, it doesn't need to be precisely specified as an integer (i.e. 5
works just fine).
Second, you can do ?scales::percent_format
at any time in an R console (it's free!). Doing so tells you this about the function:
percent_format(
accuracy = NULL, scale = 100, prefix = "", suffix = "%",
big.mark = " ", decimal.mark = ".", trim = TRUE, ...
)
So, it takes many possible parameters all of which have defaults and some are options (via ...
).
The default for the accuracy
parameter is NULL
. If we scroll down just a bit on the help page for the function we see:
accuracy
: Number to round to,NULL
for automatic guess.
If we type the function name without parens or a ?
prefix, we can see the entire source. Doing so shows that it ultimately calls scales::number()
which is defined as:
function (x, accuracy = 1, scale = 1, prefix = "", suffix = "",
big.mark = " ", decimal.mark = ".", trim = TRUE, ...) {
if (length(x) == 0) return(character())
accuracy <- accuracy %||% precision(x)
x <- round_any(x, accuracy/scale)
nsmall <- -floor(log10(accuracy))
nsmall <- min(max(nsmall, 0), 20)
ret <- format(scale * x, big.mark = big.mark, decimal.mark = decimal.mark,
trim = trim, nsmall = nsmall, scientific = FALSE, ...)
ret <- paste0(prefix, ret, suffix)
ret[is.infinite(x)] <- as.character(x[is.infinite(x)])
ret[is.na(x)] <- NA
ret
}
This:
accuracy <- accuracy %||% precision(x)
says if accuracy
is not NULL
use it otherwise guess by using the precision()
function.
The next line after that is the ultimate answer to your question.
Solution 2
For 5 digits after comma
library(ggplot2)
library(tidyverse)
mtcars %>%
count(cyl) %>%
mutate(prop = n / sum(n)) %>%
ggplot(aes(x = cyl, y = prop)) +
geom_point() +
scale_y_continuous(labels = scales::percent_format(accuracy=.00001))
stackinator
Updated on June 14, 2022Comments
-
stackinator almost 2 years
library(tidyverse) mtcars %>% count(cyl) %>% mutate(prop = n / sum(n)) %>% ggplot(aes(x = cyl, y = prop)) + geom_point() + scale_y_continuous(labels = scales::percent_format(accuracy = 5L))
If I use
scales::percent()
above instead ofscales::percent_format(accuracy = 5L)
I get decimal places in my percentage labels, which I don't want.The question - what does 5L do in my example above? Why do I need to use the integer 5L instead of 5? And why does 6L change the highest y-value from 40% to 42%? That's just plain strange.