8 votes

Générer rapidement le produit cartésien d'une matrice

Disons que j'ai une matrice x qui contient 10 lignes et 2 colonnes. Je veux générer une nouvelle matrice M qui contient chaque paire unique de lignes de x - c'est-à-dire une nouvelle matrice de 55 lignes et 4 colonnes.

Par exemple,

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
}

Donc, x est :

      [,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

Et puis M a 4 colonnes, les deux premières sont une rangée de x et les 2 suivants sont un autre rang de 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

Existe-t-il un moyen plus rapide ou plus simple (ou les deux) de faire cela en R ?

1voto

Inspiré des autres réponses, voici une fonction implémentant le produit cartésien de deux matrices, dans le cas de deux matrices, le produit cartésien complet, pour un seul argument, en omettant une de chaque paire :

cartesian_prod <- function(M1, M2) {
if(missing(M2)) {  M2 <- M1
     ind  <- expand.grid(1:NROW(M1), 1:NROW(M2))
     ind <- ind[ind[,1] >= ind[,2],] } else {
                                          ind  <- expand.grid(1:NROW(M1), 1:NROW(M2))}
rbind(cbind(M1[ind[,1],], M2[ind[,2],]))

}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X