2

I got the following issue:

I have a large array "x" of the dimension dim(x)= (46, 13, 30). I'm trying to compute a new matrix "M"(30,598) which contains basically the first element of every "slice" in the first column, the second element in the second and so on... Eventually, I want to work with vectors (columns of M) containing all the elements of each grid cell.

With the following function I would be able to calculate my matrix M. However, it's not exactly a user-friendly solution considering the large array:

M <- cbind(x[1,1,],x[1,2,],x[1,3,],x[1,4,],x[2,1,],x[2,2,], x[2,3,],x[2,4,]......)

That's why I want to use a for-loop. Unfortunately I can't figure out how.

This is what I tried so far (unsuccessfully):

M  <- matrix(NA, nrow = 6, ncol = 20)
for (i in 1:120){
    M[i] <- cbind(x[,,i])
} 

This loop only creates the first vector (first element of every "slice" [1,1,]), than aborts.

Any ideas on how to get this done? Very much appreciate the help!

8
  • 4
    It would be helpful if you post some dummy data, e.g. a small array with 3 dimensions, so we can help you better. Commented Aug 11, 2017 at 16:01
  • Like set.seed(1) ; x <- array(rnorm(2*3*5), dim = c(2, 3, 5)) for instance. And a related desired output Commented Aug 11, 2017 at 16:02
  • In my example, is your desired output desired_output <- cbind(x[1,1,],x[1,2,],x[1,3,],x[2,1,],x[2,2,], x[2,3,])? Commented Aug 11, 2017 at 16:06
  • Exactly Aurèle, that's what I'm trying to get! Commented Aug 11, 2017 at 16:14
  • Then t(apply(x, 3, identity)) Commented Aug 11, 2017 at 16:17

1 Answer 1

5

Sample data:

set.seed(1) ; x <- array(rnorm(2*3*5), dim = c(2, 3, 5))

# , , 1
# 
# [,1]       [,2]       [,3]
# [1,] -0.6264538 -0.8356286  0.3295078
# [2,]  0.1836433  1.5952808 -0.8204684
# 
# , , 2
# 
# [,1]       [,2]      [,3]
# [1,] 0.4874291  0.5757814 1.5117812
# [2,] 0.7383247 -0.3053884 0.3898432
# 
# , , 3
# 
# [,1]        [,2]        [,3]
# [1,] -0.6212406  1.12493092 -0.01619026
# [2,] -2.2146999 -0.04493361  0.94383621
# 
# , , 4
# 
# [,1]      [,2]        [,3]
# [1,] 0.8212212 0.9189774  0.07456498
# [2,] 0.5939013 0.7821363 -1.98935170
# 
# , , 5
# 
# [,1]       [,2]       [,3]
# [1,]  0.61982575 -0.1557955 -0.4781501
# [2,] -0.05612874 -1.4707524  0.4179416

Then permutate dimensions, apply() identity (or, equivalently, as.vector or even c, see ?apply) to the 3rd dimension and transpose:

res <- t(apply(aperm(x, c(3, 2, 1)), 1, identity))

#            [,1]       [,2]        [,3]        [,4]        [,5]       [,6]
# [1,] -0.6264538 -0.8356286  0.32950777  0.18364332  1.59528080 -0.8204684
# [2,]  0.4874291  0.5757814  1.51178117  0.73832471 -0.30538839  0.3898432
# [3,] -0.6212406  1.1249309 -0.01619026 -2.21469989 -0.04493361  0.9438362
# [4,]  0.8212212  0.9189774  0.07456498  0.59390132  0.78213630 -1.9893517
# [5,]  0.6198257 -0.1557955 -0.47815006 -0.05612874 -1.47075238  0.4179416

Equivalently, per @Frank's suggestion: res <- matrix(aperm(x, c(3, 2, 1)), dim(x)[3])

Finally:

desired_output <- cbind(x[1,1,],x[1,2,],x[1,3,],x[2,1,],x[2,2,], x[2,3,])
all.equal(res, desired_output)

# [1] TRUE
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.