Home > Software engineering >  Pass arguments to labels function in scale_y_continuous() with do.call() yields error
Pass arguments to labels function in scale_y_continuous() with do.call() yields error

Time:03-24

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)))
  • Related