简体   繁体   English

将矩阵组合成 R 中的数组

[英]Combining matrices into an array in R

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.我有 8 个矩阵,每个矩阵有 200 行和 200 列,我需要将它们组合成一个数组,dim = 200,200,8。 So I want each of my matrices to be a slice of my array.所以我希望我的每个矩阵都是我数组的一部分。

You can use the abind function from the abind package:您可以使用abind包中的abind函数:

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 )

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

The short version is that you can simplify-to-array a set of matrices using the function: simplify2array :简短的版本是您可以使用以下函数将一组矩阵简化为数组: 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.下面是我之前的答案,显示了如何使用sapplysimplify=参数执行此操作,因为当 'simplify' 不为 false 时'simplify2array()' 是从 'simplify()' 调用的实用程序- 请参阅?sapply帮助文件。

Here's a version similar to abind -ing, but without using any additional packages.这是一个类似于abind -ing 的版本,但没有使用任何额外的包。 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 ):将所有内容收集到一个list ,然后使用sapply的选项来simplify=到一个"array" ,在对列表的每个部分不做任何操作之后( identity只是返回对象,相当于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")

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.这类似于使用cbindrbind将向量组合成矩阵。 Because R stores matrices in column-major order, this is the easiest to accomplish:因为 R 以列优先顺序存储矩阵,所以这是最容易实现的:

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.新维度(在本例中为 2)将成为第 3 个维度。 Judging from the output of the print method, this looks accurate, because it splits the print by the last dimension:从print方法的输出来看,这看起来很准确,因为它是按照最后一个维度来分割print的:

> 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, eg:但是,有时您可能需要按第一个维度将它们组合起来,例如:

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, aka nrow have to match in the array and data frame:然后第一个维度,也就是nrow必须在数组和数据框中匹配:

 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
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

这个怎么样:

combmat <- array(dim=c(200,200,8), data=cbind(matrix1,matrix2,...,matrix8) )

Related: How to stack multiple matrices in R相关: 如何在 R 中堆叠多个矩阵

The problem with all solutions so far is that when matrices (not data.frame s - 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.到目前为止所有解决方案的问题是,当矩阵(不是data.frame s - 对于这个dplyrdata.table工作正常)没有相同的行和列顺序时,bind 会将不相关的值堆叠在一起.

If you want to check and take into account the names in each dimension, have a look at narray :如果要检查并考虑每个维度中的名称,请查看narray

在此处输入图片说明

(disclaimer: I wrote the package) (免责声明:我写了包)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM