【问题标题】:R expand matrix dimensions using applyR使用apply扩展矩阵维度
【发布时间】:2018-02-21 07:45:51
【问题描述】:

我希望通过对矩阵的每一行应用一个函数并返回一个矩阵来将我的 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 对角矩阵 diag(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

【问题讨论】:

    标签: r matrix


    【解决方案1】:

    您可以简单地使用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
    

    [编辑] 正如@Tom 所建议的那样,我已经用diag 替换了原来的apply 函数。当然,您可以将diag 替换为任何更复杂的函数。

    【讨论】:

    • 也许你想用diag替换apply.fun
    【解决方案2】:

    我们可以创建一个listmatrixes

    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
    

    【讨论】:

    • 这很酷,但我更喜欢 3D 数组,正如我在编辑中解释的那样,有没有办法转换它?
    猜你喜欢
    • 2017-10-31
    • 2016-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-19
    • 2018-01-18
    • 2021-12-06
    • 1970-01-01
    相关资源
    最近更新 更多