R使用apply扩展矩阵尺寸

时间:2018-02-21 07:45:52

标签: r matrix

我希望通过将函数应用于矩阵的每一行并返回矩阵来将我的2D矩阵扩展为3D,这样我就可以拥有一个3D矩阵。

我能想到再现的最简单的例子是,比如我有一个3x3矩阵A,我想将A的每一行转换成对角矩阵,这样我现在就有了一个3D矩阵。

testmat <- matrix(c(1,2,3,4,5,6,7,8,9), nrow = 3, byrow = TRUE) #create matrix
tesmatapply <- apply(testmat, 1, function(r) matrix(c(r[1], 0, 0, 0, r[2], 0, 0, 0, r[3]), nrow = 3, byrow= TRUE))

我想要的是testmatapply是一个3x3x3矩阵,以便tesmatapply [,, 1]给我一个3x3对角矩阵诊断(1,2,3)对应第一行

但是apply会返回一个展平的向量。导致9x3矩阵如何避免这种情况?

编辑:

基本上,我的预期输出是一个数组:

testapply[,,1]
      [,1] [,2] [,3]
 [1,]    1    0    0
 [2,]    0    2    0
 [3,]    0    0    3

testapply[,,2]
      [,1] [,2] [,3]
 [1,]    4    0    0
 [2,]    0    5    0
 [3,]    0    0    6

testapply[,,3]
      [,1] [,2] [,3]
 [1,]    7    0    0
 [2,]    0    8    0
 [3,]    0    0    9

但是我得到一个9x3矩阵:

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

2 个答案:

答案 0 :(得分:2)

您只需使用指定维度数量的array函数(3x3x3):

## The data
testmat <- matrix(c(1,2,3,4,5,6,7,8,9), nrow = 3, byrow = TRUE) #create matrix
## The array
array(apply(testmat, 1, diag), dim = c(3,3,3))

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

[编辑] 我已将apply函数替换为diag作为@Tom建议的righlty。当然,您可以用任何更复杂的函数替换diag

答案 1 :(得分:1)

我们可以创建list matrix es

lapply(split(testmat, row(testmat)), `*`, diag(3))
#$`1`
#     [,1] [,2] [,3]
#[1,]    1    0    0
#[2,]    0    2    0
#[3,]    0    0    3

#$`2`
#     [,1] [,2] [,3]
#[1,]    4    0    0
#[2,]    0    5    0
#[3,]    0    0    6

#$`3`
#     [,1] [,2] [,3]
#[1,]    7    0    0
#[2,]    0    8    0
#[3,]    0    0    9

如果我们需要array作为输出,则另一个选项是

a1 <- replicate(3, diag(3))
replace(a1, a1==1, t(testmat))
#, , 1

#     [,1] [,2] [,3]
#[1,]    1    0    0
#[2,]    0    2    0
#[3,]    0    0    3

#, , 2

#     [,1] [,2] [,3]
#[1,]    4    0    0
#[2,]    0    5    0
#[3,]    0    0    6

#, , 3

#     [,1] [,2] [,3]
#[1,]    7    0    0
#[2,]    0    8    0
#[3,]    0    0    9