Quickly create a Cartesian matrix product

Let's say I have a matrix x that contains 10 rows and 2 columns. I want to create a new matrix M that contains each unique pair of rows from x , i.e. a new matrix with 55 rows and 4 columns.

eg.

 x <- matrix (nrow=10, ncol=2, 1:20) M <- data.frame(matrix(ncol=4, nrow=55)) k <- 1 for (i in 1:nrow(x)) for (j in i:nrow(x)) { M[k,] <- unlist(cbind (x[i,], x[j,])) k <- k + 1 } 

So x :

  [,1] [,2] [1,] 1 11 [2,] 2 12 [3,] 3 13 [4,] 4 14 [5,] 5 15 [6,] 6 16 [7,] 7 17 [8,] 8 18 [9,] 9 19 [10,] 10 20 

And then M has 4 columns, the first two are one row from x , and the next 2 are another row from x :

 > head(M,10) X1 X2 X3 X4 1 1 11 1 11 2 1 11 2 12 3 1 11 3 13 4 1 11 4 14 5 1 11 5 15 6 1 11 6 16 7 1 11 7 17 8 1 11 8 18 9 1 11 9 19 10 1 11 10 20 

Is there a faster or easier (or both) way to do this in R?

+6
matrix r cartesian
source share
4 answers

The expand.grid() function is useful for this:

 R> GG <- expand.grid(1:10,1:10) R> GG <- GG[GG[,1]>=GG[,2],] # trim it to your 55 pairs R> dim(GG) [1] 55 2 R> head(GG) Var1 Var2 1 1 1 2 2 1 3 3 1 4 4 1 5 5 1 6 6 1 R> 

Now you have the subsets n * (n + 1) / 2 ', and you can just index the original matrix.

+7
source share

I don’t quite understand what you are doing, I’ll just throw away something that may or may not help.

Here is what I consider the Cartesian product of two columns:

 expand.grid(x[,1],x[,2]) 
+2
source share

You can also try the relationship package. Here is a vignette. It should work as follows:

 relation_table(x %><% x) 
+2
source share

Using Dirk's answer:

 idx <- expand.grid(1:nrow(x), 1:nrow(x)) idx<-idx[idx[,1] >= idx[,2],] N <- cbind(x[idx[,2],], x[idx[,1],]) > all(M == N) [1] TRUE 

Thanks everyone!

+1
source share

All Articles