2011-11-06 8 views
5

Digamos que tengo una matriz, foo, en R que tiene dimensiones == c(150, 40, 30). Ahora, si yo:Invertir una aplicación con rbind

bar <- apply(foo, 3, rbind) 

dim(bar) es ahora c(6000, 30).

¿Cuál es la forma más elegante y genérica de invertir este procedimiento y pasar de bar a foo para que sean idénticos?

El problema no es obtener las dimensiones correctas, sino recuperar los datos en el mismo orden, dentro de su dimensión respetada y original.

Gracias por tomarse el tiempo, espero con interés sus respuestas.

P.S. Para aquellos que piensan que esto es parte de un problema mayor, lo es, y no, todavía no puedo usar plyr.

+0

¿Has mirado 'aaply'? Por lo general, hace un mejor trabajo al dar las dimensiones que esperas – hadley

+0

La llamada a 'rbind' no tiene sentido, ya que solo le das un argumento, no hará nada útil. 'identity' haría lo mismo ... Expandí esta observación en mi respuesta a continuación. – Tommy

Respuesta

7

Creo que sólo puede llamar array de nuevo y especificar las dimensiones originales:

m <- array(1:210,dim = c(5,6,7)) 
m1 <- apply(m, 3, rbind) 
m2 <- array(as.vector(m1),dim = c(5,6,7)) 
all.equal(m,m2) 
[1] TRUE 
+0

Hmm, pensé que probé esto, pero debe ser una de esas noches porque funciona bien. ¡Gracias por su amabilidad! – brews

+3

Dependiendo del orden de los datos, puede necesitar crear la matriz con las dimensiones en el orden incorrecto y luego usar 'aperm'. –

4

Me pregunto acerca de su transformación inicial. Llame al rbind desde apply, pero eso no hará nada; ¡podría haber llamado al identity!

foo <- array(seq(150*40*30), c(150, 40, 30)) 
bar <- apply(foo, 3, rbind) 
bar2 <- apply(foo, 3, identity) 
identical(bar, bar2) # TRUE 

Entonces, ¿qué es lo que realmente quería lograr? Estaba bajo la suposición de que tenía un par de (30) porciones de matriz y quería apilarlas y luego desapilarlas de nuevo. De ser así, el código sería más complicado de lo que se sugirió @joran. Es necesario algunas llamadas a aperm (como se sugiere @Patrick Burns):

# Make a sample 3 dimensional array (two 4x3 matrix slices): 
m <- array(1:24, 4:2) 

# Stack the matrix slices on top of each other 
m2 <- matrix(aperm(m, c(1,3,2)), ncol=ncol(m)) 

# Reverse the process 
m3 <- aperm(array(m2, c(nrow(m),dim(m)[[3]],ncol(m))), c(1,3,2)) 

identical(m3,m) # TRUE 

En cualquier caso, aperm es realmente de gran alcance (y algo confuso). Bien vale la pena aprender ...

+0

Buen punto, una ruptura de las dos primeras dimensiones es esencialmente lo que necesito. 'aperm' parece un poco extraño al principio, pero lo investigaré. Puede ser el mejor método. Gracias amablemente por la sugerencia. – brews