2009-09-15 9 views
6

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 avec 55 lignes et 4 colonnes.Générer rapidement le produit cartésien d'une matrice

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 
} 

Ainsi, 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 premiers sont une ligne de x et les 2 prochains sont une autre ligne 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 

Est y-a-t-il une manière plus rapide ou plus simple (ou les deux) de le faire dans R?

Répondre

7

La fonction 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> 

Maintenant, vous avez le « n * (n + 1)/2 'sous-ensembles et vous pouvez facilement indexer votre matrice d'origine.

2

Je ne suis pas vraiment en train de creuser ce que vous faites, alors je vais jeter quelque chose qui pourrait ou ne pourrait pas aider.

Voici ce que je pense que le produit cartésien des deux colonnes:

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

Je n'ai jamais entendu parler de expand.grid(). La réponse de Dirk apporte tout cela ensemble (comme toujours ...) –

2

Vous pouvez également essayer le package "relations". Here is the vignette. Il devrait fonctionner comme ceci:

relation_table(x %><% x) 
1

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 tout le monde!

Questions connexes