简体   繁体   中英

mapply for all arguments' combinations [R]

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM