Consider this toy function that receives 3 arguments:
toy <- function(x, y, z){
paste(x, y, z)
}
For each argument I have a number of values (not necessarily the same number for each argument) and I want to apply the toy
function to the different combinations of those arguments.
So I thought, ok, let's use the multivariate version of the apply functions mapply
.
mapply(FUN = toy, x = 1:2, y = c("#", "$"), z = c("a", "b"))
[1] "1 # a" "2 $ b"
But this is not quite what I wanted. Indeed, according to the help mapply
"applies FUN to the first elements of each ... argument, the second elements, the third elements, and so on.". And what I want is to apply FUN to all the different combinations of all the arguments.
So, instead of
[1] "1 # a" "2 $ b"
The result I would like is rather:
[1] "1 # a" "1 # b" "1 $ a" "1 $ b" "2 # a" "2 # b" "2 $ a" "2 $ b"
So, my question is what is the clever way to do this?
Of course, I can prepare the combinations beforehand and arrange the arguments for mapply
so they include -rowwise- all the combinations. But I just thought this may be a rather common task and there might be already a function, within the apply-family, that can do that.
You could combine do.call
with expand.grid
to work with unlimited amount of input as follows
toy <- function(...) do.call(paste, expand.grid(...))
Then, you could do
x = 1:2 ; y = c("#", "$") ; z = c("a", "b")
toy(x, y, z)
# [1] "1 # a" "2 # a" "1 $ a" "2 $ a" "1 # b" "2 # b" "1 $ b" "2 $ b"
This will work for any input. You could try stuff like toy(x, y, z, y, y, y, z)
, for instance in order to validate.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With