can we iterate over two lists with purrr (not simultaneously)?

1.8k Views Asked by At

Consider that I have a function f(x,y) that takes two argument and two lists

  • x_var = list('x','y','z')
  • and y_var = list('a','b')

Is there a purrr function that allows me to iterate every combination of one element in x_var and one element in y_var? That is, doing f(x,a), f(x,b), f(y,a), f(y,b) etc.

The usual solution would be to write a loop, but I wonder if there is more concise here (possibly with purrr.

Thanks!

4

There are 4 best solutions below

0
On BEST ANSWER

You can use one of the cross* functions along with map:

map(cross2(x_var, y_var), unlist)
0
On

The base R function expand.grid function works here

expand.grid(x=x_var, y=y_var) %>% {paste(.$x, .$y)}
1
On

If x_var and y_var are atomic vectors or arrays, and the function returns an atomic vector of known length, you can use the base R function outer:

outer(x_var, y_var, FUN = f)

This will return an array with dimensions c(dim(x_var), dim(y_var)). Dimension names are similarly combined. For example:

x_var <- setNames(1:3, c("a", "b", "c"))
y_var <- setNames(4:5, c("d", "e"))
outer(x_var, y_var, '+')
#   d e
# a 5 6
# b 6 7
# c 7 8
0
On

You can nest your calls to map

library(purrr)
map(x_var, function(x) {
  map(y_var, paste, x)
})
[[1]]

[[1]][[1]]
[1] "a x"

[[1]][[2]]
[1] "b x"


[[2]]
[[2]][[1]]
[1] "a y"

[[2]][[2]]
[1] "b y"


[[3]]
[[3]][[1]]
[1] "a z"

[[3]][[2]]
[1] "b z"