将每个对应的数组元素转换为r

时间:2017-10-26 16:10:29

标签: arrays r

我有大量的数组,并希望在向量中的所有这些数组中的特定位置转换所有元素。也就是说,如果我有2个arryas如下:

, , 39

            [,1]        [,2]       [,3]     [,4] [,5]
[1,]  0.00000000  0.00000000  0.0000000 0.000000    0
[2,]  0.06703875  0.00000000  0.0000000 0.000000    0
[3,]  0.60078853  0.48239226  0.0000000 0.000000    0
[4,] -0.41071928 -0.03397696 -1.3588026 0.000000    0
[5,] -0.27326482  0.84172740 -0.3139296 1.515104    0

, , 40

            [,1]       [,2]      [,3]    [,4] [,5]
[1,] 0.000000000  0.0000000 0.0000000 0.00000    0
[2,] 0.003862625  0.0000000 0.0000000 0.00000    0
[3,] 0.187788593 -0.1087561 0.0000000 0.00000    0
[4,] 0.186767234  0.2369021 0.2967447 0.00000    0
[5,] 1.008507457  0.7118111 0.1412379 1.02506    0

然后我想有10个向量如下(只有下三角形的值):

v1( 0.06703875 ,  0.003862625 ) 
v2(0.60078853  ,  0.187788593 )
       .  .  .
       .  .  .
v10(1.515104 , 1.02506)

所以位于相同位置的所有元素都将存储到向量中。 我有300个这样的数组,并希望在R中自动完成任何想法和帮助吗?

3 个答案:

答案 0 :(得分:3)

您可以使用apply子集到下三角形,但它会将其结果简化为矩阵(实际上可能是更好的数据结构)。要将该矩阵拆分为向量,您可以将split与行数的序列一起使用,这将按照您的需要进行循环,因为如果您只提供一个索引,则矩阵按列(如填充)进行子集化。一起来:

set.seed(47)

a <- array(rnorm(5 * 5 * 2), c(5, 5, 2))

lower_tris <- apply(a, 3, function(x){x[lower.tri(x)]}) 

list_of_pairs <- split(lower_tris, seq(nrow(lower_tris)))
# or with @lmo's cleaner approach,
# list_of_pairs <- split(lower_tris, row(lower_tris))

str(list_of_pairs)
#> List of 10
#>  $ 1 : num [1:2] 0.711 -1.608
#>  $ 2 : num [1:2] 0.185 -2.322
#>  $ 3 : num [1:2] -0.282 -1.967
#>  $ 4 : num [1:2] 0.1088 0.0275
#>  $ 5 : num [1:2] 0.0151 -1.2004
#>  $ 6 : num [1:2] -0.252 0.885
#>  $ 7 : num [1:2] -1.466 0.887
#>  $ 8 : num [1:2] -1.828 0.507
#>  $ 9 : num [1:2] 0.0915 0.5643
#>  $ 10: num [1:2] -0.0406 -0.4877

split通过分裂因子自动命名每个元素;如果你愿意,可以在unname中打电话。

答案 1 :(得分:2)

使用aperm和逻辑子集的替代方法是

# Use array provided in alistaire's answer, modified to set the upper triangle to 0
set.seed(47)
a <- array(rnorm(5 * 5 * 2), c(5, 5, 2))
for(i in 1:2) a[,,i][upper.tri(a[,,i], diag = TRUE)] <- 0

使用此数组,使用aperm对数据进行排序,以便第三维元素位于列中

tmp <- aperm(a, c(3, 2, 1))

现在,提取非零元素并将它们放在矩阵中:

myMat <- matrix(tmp[tmp != 0], 2)

如果您想要列表,请使用split

split(myMat, col(myMat))
$`1`
[1]  0.7111425 -1.6081599

$`2`
[1]  0.1854053 -2.3223723

$`3`
[1]  0.01513086 -1.20044063

...

答案 2 :(得分:0)

请参见comperes软件包和函数mat_to_long():

library(comperes)
long.dat <- mat_to_long(matrix, "row", "col", "val")