Pregunta

Digamos que tengo una matriz x que contiene 10 filas y 2 columnas. Quiero generar una nueva matriz M que contenga cada par único de filas de x , es decir, una nueva matriz con 55 filas y 4 columnas.

Por ejemplo,

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
}

Entonces, x es:

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

Y luego M tiene 4 columnas, las dos primeras son una fila de x y las siguientes 2 son otra fila 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 una forma más rápida o más simple (o ambas) de hacer esto en R?

¿Fue útil?

Solución

La función expand.grid () útil para esto:

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> 

Ahora tiene los subconjuntos 'n * (n + 1) / 2' y puede indexar su matriz original.

Otros consejos

No estoy realmente asimilando lo que estás haciendo, así que simplemente tiraré algo que puede o no ayudar.

Esto es lo que considero como el producto cartesiano de las dos columnas:

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

También puede probar las "relaciones" paquete. Aquí está la viñeta. Debería funcionar así. :

relation_table(x %><% x)

Usando la respuesta 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

¡Gracias a todos!

Inspirado en las otras respuestas, aquí hay una función que implementa el producto cartesiano de dos matrices, en el caso de dos matrices, el producto cartesiano completo, para un solo argumento, omitiendo uno de cada par:

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],]))

}

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top