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 ?

9voto

Dirk Eddelbuettel Points 134700

El expand.grid() utile pour cela :

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> 

Vous avez maintenant les sous-ensembles 'n*(n+1)/2' et vous pouvez simplement indexer votre matrice originale.

3voto

JD Long Points 20477

Je ne comprends pas très bien ce que vous faites, alors je vais juste vous proposer quelque chose qui peut, ou ne peut pas, vous aider.

Voici ce que je considère comme le produit cartésien des deux colonnes :

expand.grid(x[,1],x[,2])

2voto

Shane Points 40885

Vous pouvez également essayer le paquet "relations". Voici la vignette. Cela devrait fonctionner comme suit :

relation_table(x %><% x)

1voto

Josh Reich Points 2792

En utilisant la réponse de Dirk :

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

Merci à tous !

1voto

BondedDust Points 105234

Bien que la réponse construite soit en accord avec l'exemple mis en œuvre, elle n'est pas en accord avec la description du problème. Le nombre de combinaisons uniques de 10 éléments distincts pris deux par deux est de 45, et non de 55. Cet ensemble de 55 éléments n'est pas non plus le produit cartésien qui contiendrait 10 x 10 paires. Voici une solution qui donnerait 45 "combinaisons" uniques en utilisant la fonction R combn :

>  M <- data.frame(cbind(x[z[1,],], x[z[2,],])  )
>  nrow(M)
[1] 45
> head(M)
  X1 X2 X3 X4
1  1 11  2 12
2  1 11  3 13
3  1 11  4 14
4  1 11  5 15
5  1 11  6 16
6  1 11  7 17

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