I want to make a ggplot for which the y-axis labels are formatted by a pre-made list. I have found that if I pass arguments to the labels
option in scale_y_continuous()
function in ggplot directly it works fine, but if I pass them via do.call
it throws an error, even though (I think) these are equivalent.
Here is an example:
library(scales)
# make the list of arguments
fn_args = list(prefix = "$", big.mark = ",", decimal.mark = ".")
# print an example of a number formatted with these arguments using do.call()
do.call(number, as.list(append(x=10001, fn_args)))
##> [1] "P10,001S"
# print the same number but put the arguments directly in the function
number(10001, prefix = "P", suffix = "S", big.mark = ",", decimal.mark = ".")
##> [1] "P10,001S"
# Great -- they're identical, as expected.
# Now, let's make plots:
library(ggplot2)
# this works and produces a plot with the y-axis formatted nicely
ggplot(mtcars, aes(mpg, cyl))
geom_line()
scale_y_continuous(labels=function(s) number(x = s, prefix = "P", suffix = "S", big.mark = ",", decimal.mark = "."))
# But this one doesn't work:
ggplot(mtcars, aes(mpg, cyl))
geom_line()
scale_y_continuous(labels=function(s) do.call(number, as.list(append(x=s, fn_args))))
##> Error in `f()`:
##> ! Breaks and labels are different lengths
I don't understand why I'm getting this error, since I thought those two formulations were identical.
I'd appreciate anyone's insights!
Thank you.
CodePudding user response:
We need a flattened list
- In the OP's code, the append
first argument is x
, thus x=s
, assumes it is the value passed for the 'x' argument and not a named vector. We may need scale_y_continuous(labels=function(s) do.call(number, append(list(c(x=s)), fn_args)))
library(ggplot2)
ggplot(mtcars, aes(mpg, cyl))
geom_line()
scale_y_continuous(labels=function(s)
do.call(number, c(list(x=s), fn_args)))