Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Invert an apply with rbind

Tags:

arrays

r

Lets say that I have an array, foo, in R that has dimensions == c(150, 40, 30). Now, if I:

bar <- apply(foo, 3, rbind)

dim(bar) is now c(6000, 30).

What is the most elegant and generic way to invert this procedure and go from bar to foo so that they are identical?

The trouble isn't getting the dimensions right, but getting the data back in the same order, within it's respected, original, dimension.

Thank you for taking the time, I look forward to your responses.

P.S. For those thinking that this is part of a larger problem, it is, and no, I cannot use plyr, quite yet.

like image 435
brews Avatar asked Nov 06 '11 05:11

brews


2 Answers

I think you can just call array again and specify the original dimensions:

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
like image 147
joran Avatar answered Nov 19 '22 04:11

joran


I'm wondering about your initial transformation. You call rbind from apply, but that won't do anything - you could just as well have called 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

So, what is it you really wanted to accomplish? I was under the assumption that you had a couple (30) matrix slices and wanted to stack them and then unstack them again. If so, the code would be more involved than @joran suggested. You need some calls to aperm (as @Patrick Burns suggested):

# 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

In any case, aperm is really powerful (and somewhat confusing). Well worth learning...

like image 42
Tommy Avatar answered Nov 19 '22 05:11

Tommy