简体   繁体   English

在第3个暗区中分离矩阵。 R中的3D数组

[英]Separate the matrices in the 3rd dim. of a 3D array in R

I have a list of 3D arrays which looks like this: 我有一个3D数组的列表,看起来像这样:

my.arrs <- list(array(1:5, c(5,4,2)),array(1:5, c(5,4,2)),array(1:5, c(5,4,2))); 
my.arrs

What I wish to have is a new list with each matrix contained in my list of arrays separated (ideally it should look like this): 我希望有一个新列表,其中每个矩阵都包含在我的数组列表中,每个矩阵分开(理想情况下应如下所示):

my.new.matrices (list of 6)
my.array[[1]][1]
my.array[[1]][2]
my.array[[2]][1]
my.array[[2]][2]
my.array[[3]][1]
my.array[[3]][2]

Before having this issue, I worked on something very similar. 在遇到这个问题之前,我从事过非常相似的工作。 I had this as the result of a simulation I run in R: 我在R中运行的模拟结果是这样的:

    > TBM
    , , 1

                 [,1]         [,2]        [,3]        [,4]         [,5]         [,6]         [,7]        
     [1,]  0.05151012  0.345498935  0.26056614  0.04567956  0.073153163 -0.070264403  0.158124924

, , 2

             [,1]        [,2]         [,3]        [,4]        [,5]        [,6]        [,7]         
 [1,] -0.65883235 -0.43591955 -0.116739746 -0.28835563  0.04351086 -0.03692388  0.60592379

, , 3

           [,1]      [,2]      [,3]      [,4]       [,5]         [,6]        [,7]       
 [1,] 0.2816988 0.3726166 0.4434252 0.4204302  0.2684518  0.454951339  0.64363895 

And I wrote this for() loop: 我写了这个for()循环:

TBM.vector3 <- list()
for(i in 1:dim(TBM)[3]) {
  print(i)
  TBM.vector3[[i]] <- as.vector(TBM[,,i])
}
TBM.vector3

which makes exactly what I want ie, separate each matrix in the third dimension and store them in a list of vector. 这正是我想要的,即在三维中分离每个矩阵并将它们存储在向量列表中。 I want to automatize this process a list of array like my.arrs . 我想自动执行此过程,例如my.arrs这样的数组列表。

1) tapply Each of 3 arrays is made up of 2 5x4 matrices so create a long vector out of it all and then grab successive vectors of 5*4 components and turn them into a matrix of the desired shape: 1)轻触 3个数组中的每一个都由2个5x4矩阵组成,因此要从中全部创建一个长向量,然后获取5 * 4分量的连续向量并将它们转换为所需形状的矩阵:

tapply(unlist(my.arrs), gl(3*2, 5*4), matrix, 5)

or more generally: 或更一般而言:

dims <- dim(my.arrs[[1]])  # c(5, 4, 2)
tapply(unlist(my.arrs), gl(length(my.arrs) * dims[3], prod(dims[1:2])), matrix, dims[1])

2) sapply/lapply Another possibility (where dims is defined above): 2)sapply / lapply另一种可能性(其中dims如上文所定义):

c(sapply(my.arrs, function(x) lapply(1:dims[3], function(i) x[,,i])))

If I understand what you are asking for, here is one approach: 如果我了解您的要求,可以采用以下一种方法:

unlist(lapply(my.arrs, function(x) {
    lapply(1:dim(x)[3], function(y) {
        x[,,y]
    })
}), recursive = FALSE)
#[[1]]
#     [,1] [,2] [,3] [,4]
#[1,]    1    1    1    1
#[2,]    2    2    2    2
#[3,]    3    3    3    3
#[4,]    4    4    4    4
#[5,]    5    5    5    5
## ...
## ...
#[[6]]
#     [,1] [,2] [,3] [,4]
#[1,]   11   11   11   11
#[2,]   12   12   12   12
#[3,]   13   13   13   13
#[4,]   14   14   14   14
#[5,]   15   15   15   15

  • The outer lapply iterates over each array 外部lapply遍历每个数组
  • The inner lapply iterates over each slice (3rd dimension) of each array, so that 2 is not hardcoded into the function 内部lapply遍历每个数组的每个切片(第3维),因此不会将2硬编码到函数中
  • Calling unlist with recursive = FALSE (which is not the default behavior) expands the lapply(lapply(...)) result from a length 3 list of length 2 lists into a single length 6 list. 使用recursive = FALSE (这不是默认行为)调用unlist会将lapply(lapply(...))结果从长度2列表的长度3列表扩展为单个长度6列表。

Data: 数据:

my.arrs <- list(
    array(1:5, c(5,4,2)),
    array(6:10, c(5,4,2)),
    array(11:15, c(5,4,2))
)

Thank you @G. 谢谢@G。 Grothendieck and @nrussell for your answers, Grothendieck和@nrussell为您解答,

I was also working on my one meanwhile, had simular results with unlist() and found what is my actual problem. 同时,我也在做我的一个,用unlist()得到了类似的结果,发现我的实际问题是什么。

The output of the simulation I run for n <- 2 , gives a list of this format (later I want to make it run for a larger data set and 100 of realizations, so let's start small): 我为n <- 2运行的模拟输出给出了这种格式的列表(后来我想让它针对较大的数据集和100个实现运行,因此让我们从小处开始):

TBM List of 3
tbm1: num [1:29, 1:28, 1:2] ...
tbm2: num [1:29, 1:28, 1:2] ...
tbm3: num [1:29, 1:28, 1:2] ... 

... being my output data. ...是我的输出数据。

Because I will have a large data set and n <- 100, I can not unlist manually. 因为我的数据集很大且n <-100,所以不能手动取消列出。 Thus I wrote this: 因此,我这样写:

TBM.n <- rep(list(matrix(nrow=29, ncol=28)),6)

for(j in 1:length(TBM)){

for(jj in 1:dim(TBM[[i]])[3]){
    print(jj) 

    print(unlist(TBM[[j]][,,jj]))
    TBM.n[[j]] <- unlist(TBM[[j]][,,jj])
  }

}

print(jj) gives: print(jj)给出:

1
2
1
2
1
2

print(unlist(TBM[[j]][,,jj])) gives my data split as I want. print(unlist(TBM[[j]][,,jj]))根据需要拆分数据。 And there here come my actual problem, the storage. 这就是我的实际问题,存储。 When I write: 当我写:

TBM.n[[j]] <- unlist(TBM[[j]][,,jj])

or 要么

TBM.n[[jj]] <- unlist(TBM[[j]][,,jj])

I got the data stored for tbm1[,,2] , tbm2[,,2] , tbm3[,,2] and tbm2[,,2] , tbm3[,,2] repectively. 我分别存储了tbm1[,,2]tbm2[,,2]tbm3[,,2]tbm2[,,2]tbm3[,,2] Until now I did not find a solution for storing the whole 6 matrices. 到目前为止,我还没有找到用于存储全部6个矩阵的解决方案。 I have the feeling it is an indexing problem, still trying, not solving. 我觉得这是一个索引问题,仍在尝试,而不是解决。 Do you have any suggestions ? 你有什么建议吗 ?

Thank you Marion H 谢谢玛莉安·H


EDIT Here is my final code I adapted from @nrussel: 编辑这是我从@nrussel改编的最终代码:

TBM.n <- list()
for (i3 in 1){ #in length(TBM)
  TBM.n[[i3]] <- unlist(lapply(TBM, function(x){
    lapply(1:dim(x)[3], function(y){
      x[,,y]
    })
  }), recursive = FALSE
  )
}

The output gives me the desired results: 输出给了我想要的结果:

TBM.n List of 1
  :List of 6
  ..$ tbm11: num[1:29, 1:28] ...
  ..$ tbm12: num[1:29, 1:28] ...
  ..$ tbm21: num[1:29, 1:28] ...
  ..$ tbm22: num[1:29, 1:28] ...
  ..$ tbm31: num[1:29, 1:28] ...
  ..$ tbm32: num[1:29, 1:28] ...

Again thank you for your help ! 再次感谢您的帮助!

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

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