Created
August 22, 2016 18:17
-
-
Save fditraglia/5cf6e5029b2572cc4d858b15be37db38 to your computer and use it in GitHub Desktop.
A simple example of how to collapse a 3d array into a matrix in R
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ------------------------------------------------------------------------------ | |
# Here's a simple but slightly confusing task in R: collapsing a 3d array into a | |
# matrix. Specifically, we want to convert a 3d array of this form: | |
# ------------------------------------------------------------------------------ | |
# , , 1 | |
# | |
# [,1] [,2] [,3] | |
# [1,] "1.1.1" "1.2.1" "1.3.1" | |
# [2,] "2.1.1" "2.2.1" "2.3.1" | |
# | |
# , , 2 | |
# | |
# [,1] [,2] [,3] | |
# [1,] "1.1.2" "1.2.2" "1.3.2" | |
# [2,] "2.1.2" "2.2.2" "2.3.2" | |
# | |
# , , 3 | |
# | |
# [,1] [,2] [,3] | |
# [1,] "1.1.3" "1.2.3" "1.3.3" | |
# [2,] "2.1.3" "2.2.3" "2.3.3" | |
# | |
# , , 4 | |
# | |
# [,1] [,2] [,3] | |
# [1,] "1.1.4" "1.2.4" "1.3.4" | |
# [2,] "2.1.4" "2.2.4" "2.3.4" | |
# ------------------------------------------------------------------------------ | |
# into a matrix of this form: | |
# ------------------------------------------------------------------------------ | |
# [,1] [,2] [,3] | |
# [1,] "1.1.1" "1.2.1" "1.3.1" | |
# [2,] "2.1.1" "2.2.1" "2.3.1" | |
# [3,] "1.1.2" "1.2.2" "1.3.2" | |
# [5,] "2.1.2" "2.2.2" "2.3.2" | |
# [5,] "1.1.3" "1.2.3" "1.3.3" | |
# [6,] "2.1.3" "2.2.3" "2.3.3" | |
# [7,] "1.1.4" "1.2.4" "1.3.4" | |
# [8,] "2.1.4" "2.2.4" "2.3.4" | |
# ------------------------------------------------------------------------------ | |
# We can do this efficiently using two base R functions: aperm and dim. If you | |
# aren't familiar with it, aperm is a generalization of the tranpose function t | |
# for matrices to arbitrary arrays. | |
# ------------------------------------------------------------------------------ | |
collapse_3d_array <- function(myarray){ | |
out <- aperm(myarray, c(1, 3, 2)) | |
dim(out) <- c(dim(myarray)[1] * dim(myarray)[3], dim(myarray)[2]) | |
return(out) | |
} | |
# ------------------------------------------------------------------------------ | |
# Let's test it on the example from above: | |
# ------------------------------------------------------------------------------ | |
test_array <- structure(c("1.1.1", "2.1.1", "1.2.1", "2.2.1", "1.3.1", "2.3.1", | |
"1.1.2", "2.1.2", "1.2.2", "2.2.2", "1.3.2", "2.3.2", | |
"1.1.3", "2.1.3", "1.2.3", "2.2.3", "1.3.3", "2.3.3", | |
"1.1.4", "2.1.4", "1.2.4", "2.2.4", "1.3.4", "2.3.4"), | |
.Dim = c(2L, 3L, 4L)) | |
test_array | |
collapse_3d_array(test_array) | |
# ------------------------------------------------------------------------------ | |
# It works! But how efficient is this for large-scale problems? Let's test it | |
# with a large array of normal random variates: | |
# ------------------------------------------------------------------------------ | |
system.time(big_array <- array(rnorm(100 * 10 * 10000), c(100, 10, 10000))) | |
system.time(big_matrix <- collapse_3d_array(big_array)) | |
# ------------------------------------------------------------------------------ | |
# On my machine, the time required to create big_array is about 0.6 seconds | |
# compared to 0.06 to collapse it to big_array. Given that big_array is 76.3 Mb | |
# this is pretty fast! | |
# ------------------------------------------------------------------------------ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment