mk9y
mk9y

Reputation: 390

Is it possible to use outer() to generate a Cartesian product?

To get a Cartesian product in R, we can use

library(tidyr)
x <- 1:2
y <- 1:3
expand_grid(x, y)

with output:

# A tibble: 6 x 2
      x     y
  <int> <int>
1     1     1
2     1     2
3     1     3
4     2     1
5     2     2
6     2     3

But I would like to output to be matrix-like, as with:

outer(x, y, FUN = "+")

which gives the output:

     [,1] [,2] [,3]
[1,]    2    3    4
[2,]    3    4    5

Is there a FUN = for outer() that will produce the Cartesian product:

           [,1]       [,2]       [,3]
[1,]    c(1, 1)    c(1, 2)    c(1, 3)
[2,]    c(2, 1)    c(2, 2)    c(2, 3)

Upvotes: 1

Views: 35

Answers (1)

akrun
akrun

Reputation: 887168

There is no FUN in expand_grid. An option is to use mutate to create a new column and then reshape back to 'wide' with pivot_wider

library(dplyr)
library(tidyr)
expand_grid(x, y) %>% 
     mutate(out = x + y) %>% 
     pivot_wider(names_from = y, values_from = out) %>%
     select(-x) %>%
     as.matrix %>% 
     `dimnames<-`(., NULL)

-output

      [,1] [,2] [,3]
[1,]    2    3    4
[2,]    3    4    5

Regarding the second question, it seems that the OP wanted to store each element of the matrix as a list

out1 <- outer(x, y, FUN = Vectorize(function(x, y) list(c(x, y))))

-output

out1
     [,1]      [,2]      [,3]     
[1,] integer,2 integer,2 integer,2
[2,] integer,2 integer,2 integer,2

Upvotes: 2

Related Questions