How to pass a vector to the dots (…) argument of a function
Clash 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
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.
?do.call
, e.g.,do.call(what = paste, args = ...)
. Though I still don't think that will work so well inside aggplot
aesthetic mapping -paste
returns a character string aaes()
expects unquoted column names.– Gregor
Aug 8 at 17:16