35

If I have several matrices that I have created, how can I combine them into one array? I have 8 matrices that each have 200 rows and 200 columns and I need to combine them into an array with dim = 200,200,8. So I want each of my matrices to be a slice of my array.

4

7 に答える 7

37

You can use the abind function from the abind package:

library(abind)
newarray <- abind( mat1, mat2, mat3, mat4, along=3 )

## or if mats are in a list (a good idea)

newarray <- abind( matlist, along=3 )
于 2013-03-05T00:17:53.100 に答える
25

here's the example for two. you can easily extend this to eight

# create two matricies with however many rows and columns
x <- matrix( 1:9 , 3 , 3 )
y <- matrix( 10:18 , 3 , 3 )
# look at your starting data
x
y

# store both inside an array, with the same first two dimensions,
# but now with a third dimension equal to the number of matricies
# that you are combining
z <- array( c( x , y ) , dim = c( 3 , 3 , 2 ) )

# result
z
于 2013-03-05T00:03:24.737 に答える
12

The short version is that you can simplify-to-array a set of matrices using the function: simplify2array:

simplify2array(list(x,y))

Below is my previous answer showing how to do this with sapply's simplify= argument, since ‘simplify2array()’ is the utility called from ‘sapply()’ when ‘simplify’ is not false - see the ?sapply help file.

Here's a version similar to abind-ing, but without using any additional packages. Collect everything into a list and then use sapply's option to simplify= to an "array", after doing nothing to each part of the list (identity just returns the object and is equivalent to function(x) x ):

sapply(list(x,y), identity, simplify="array")
# similarly to save a couple of keystrokes, the following is usually identical
sapply(list(x,y), I, simplify="array")

#, , 1
#
#     [,1] [,2] [,3]
#[1,]    1    4    7
#[2,]    2    5    8
#[3,]    3    6    9
#
#, , 2
#
#     [,1] [,2] [,3]
#[1,]   10   13   16
#[2,]   11   14   17
#[3,]   12   15   18

If you want to retain the names of each original matrix in your new array as identifiers, try:

sapply(mget(c("x","y")), identity, simplify="array")
于 2016-04-06T02:14:02.373 に答える
3

It depends on whether you want to combine them column-major or row-major. This is analogous to using cbind and rbind for combining vectors into matrix. Because R stores matrices in column-major order, this is the easiest to accomplish:

matrices <- list(
  matrix( 1:9 , 3 , 3 ),
  matrix( 10:18 , 3 , 3 )
);

#it is assumed all matrices in the list have equal dimensions
array1 <- array(
  data = do.call(cbind, matrices), 
  dim = c(dim(matrices[[1]]), length(matrices))
);

The new dimension (2 in this case) will become the 3rd dimension. Judging from the output of the print method, this looks accurate, because it splits the print by the last dimension:

> print(array1)
, , 1

     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9

, , 2

     [,1] [,2] [,3]
[1,]   10   13   16
[2,]   11   14   17
[3,]   12   15   18

However, sometimes you might need to combine them by the first dimension instead, e.g:

array2 <- array (
  data = do.call(rbind, lapply(matrices, as.vector)), 
  dim = c(length(matrices), dim(matrices[[1]]))
);

print(array2[1,,])

     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9 

For example, say you want to assign these matrices to a data frame with column; one matrix for each row. Then the first dimensions, a.k.a nrow have to match in the array and data frame:

 mydf <- data.frame(foo = 1:2, row.names=c("first", "second"))
 mydf$bar <- array1
  Error in `$<-.data.frame`(`*tmp*`, "bar", value = 1:18) : 
    replacement has 3 rows, data has 2

 mydf$bar <- array2
 mydf$bar
于 2013-12-23T04:15:02.503 に答える
1
library('abind')
abind(m1, m2, m3, along = 2.5)
abind(m1, m2, m3, along = 3)

m4 <- list(m1, m2, m3)
abind(m4, along = 3) 

       along        input = matrix + matrix                       output 
----------------------------------------------------------------------------
        0         split columns and row bind them                 array
        0.5       same as 0                                       array
        1         combine matrices into one matrix by rowwise     matrix
        1.5       split columns and column bind them              array
        2         combine matrices into one matrix by columnwise  matrix
        2.5       Form an array with matrices                     array
        3         Same as 2.5                                     array
于 2017-02-06T12:05:27.017 に答える
0

How about this:

combmat <- array(dim=c(200,200,8), data=cbind(matrix1,matrix2,...,matrix8) )
于 2013-03-05T00:08:40.220 に答える
0

Related: How to stack multiple matrices in R

The problem with all solutions so far is that when matrices (not data.frames - for this dplyr and data.table work fine) do not have the same order of rows and columns, bind will stack values over each other that do not relate.

If you want to check and take into account the names in each dimension, have a look at narray:

enter image description here

(disclaimer: I wrote the package)

于 2017-01-08T22:47:52.183 に答える