How to pass a vector to the dots (…) argument of a function

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP



How to pass a vector to the dots (…) argument of a function



Several R functions have and arguement ... that allows you to pass an arbitrary number of arguments. A example of this is the paste function, to which you can provide an arbitrary number of arguements. But sometimes, you don't know ahead of time how many arguements you want to pass.


...


paste



For example, say I want to produce a plot in ggplot, where I want to color points by the combination of two columns:


df <- data.frame(x=rnorm(100),
y=rnorm(100),
cat1=sample(c(TRUE, FALSE), 100),
cat2=sample(c(TRUE, FALSE), 100),
cat3=sample(c(TRUE, FALSE), 100))
ggplot(df) + aes(x=x, y=y, col=paste(cat1,cat2) + geom_point()



But now consider that I want to the list of columns to be colour by to be determined at run-time. I would like to write a function that did something like:


library(rlang)
color_plot <- function(df, color_by)
color_by = lapply(color_by, sym)
ggplot(df) + aes(x=x, y=y, col=paste(...=color_by)) + geom_point()


color_plot(df, list("cat1"))
color_plot(df, list("cat2", "cat3"))
color_plot(df, list("cat1", "cat2", "cat3"))



I guess i'm look for something equivalent to pythons *args as in:


*args


args =[1,2,3]
my_fun(*args)





?do.call, e.g., do.call(what = paste, args = ...). Though I still don't think that will work so well inside a ggplot aesthetic mapping - paste returns a character string a aes() expects unquoted column names.
– Gregor
Aug 8 at 17:16



?do.call


do.call(what = paste, args = ...)


ggplot


paste


aes()





I think you're missing a parenthesis for aes
– avid_useR
Aug 8 at 17:27


aes




2 Answers
2



Use syms:


syms


color_plot <- function(df, color_by)
color_by <- syms(color_by)
ggplot(df) + aes(x=x, y=y, col=paste(!!!color_by)) + geom_point()





thanks, !!! was what I was looking for!
– Ian Sudbery
Aug 8 at 17:34


!!!





This only works if used in a tidyeval aware environment. So I can't just do x <- paste(!!!color_by), even if all the variables in color_by are in the current env.
– Ian Sudbery
Aug 8 at 18:19





Yes, that is how rlang works and your question did include library(rlang) so that was the assumption you were making. A base solution would be: color_by <- do.call("paste", df[unlist(color_by)]) and then use col=color_by in the last line. of the function.
– G. Grothendieck
Aug 8 at 18:39


color_by <- do.call("paste", df[unlist(color_by)])


col=color_by





Yeah, the particular problem I was trying to solve was a ggplot one, so this is what I was looking for and I had an idea rlang would be the way to do it, but once I'd come across it I was like 'wow, this is great, where else can I use it'.
– Ian Sudbery
Aug 9 at 8:39



Another method would be to use quos if you prefer passing in unquoted column names instead of a list:


quos


library(ggplot2)
library(rlang)

color_plot <- function(df, ...)
color_by = quos(...)
ggplot(df) + aes(x=x, y=y, col=paste(!!!color_by)) + geom_point()


color_plot(df, cat1, cat2, cat3)






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

How to determine optimal route across keyboard