R中的方形到“对角线”矩阵

问题描述 投票:2回答:5

我有一组向量,并希望将它们堆叠在一起以创建矩阵的对角条目。

从c1和c2创建example_out矩阵的简单方法是什么?

c1 <- seq(1, 4)
c2 <- seq(5, 8)


example_out <- matrix(c(1,0,0,0,5,2,0,0,0,6,3,0,0,0,7,4,0,0,0,8), nrow=5, byrow=T)
example_out
r matrix
5个回答
6
投票

0s创建一个矩阵,然后用c1填充主对角线,用c2填充子对角线。

example_out <- matrix(rep(0, 20), 5, 4)
diag(example_out) <- c1
diag(example_out[-1, ]) <- c2

生产

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

数据

c1 <- seq(1, 4)
c2 <- seq(5, 8)

3
投票

另一个简单的方法,增加两个0行的对角矩阵并添加它们:

rbind(diag(c1), 0) + rbind(0, diag(c2))
#      [,1] [,2] [,3] [,4]
# [1,]    1    0    0    0
# [2,]    5    2    0    0
# [3,]    0    6    3    0
# [4,]    0    0    7    4
# [5,]    0    0    0    8

3
投票

这是一个替代方法replaceing条目在numeric矢量铸造之前作为matrix

matrix(unlist(sapply(seq_along(c1), function(i)
    replace(rep(0, length(c1) + 1), i:(i+1), c(c1[i], c2[i])))),
    ncol = length(c1))
#    [,1] [,2] [,3] [,4]
#[1,]    1    0    0    0
#[2,]    5    2    0    0
#[3,]    0    6    3    0
#[4,]    0    0    7    4
#[5,]    0    0    0    8

更新

我很想知道不同的方法在性能/运行时方面的比较。这是一个简短的microbenchmark分析使用两个更大的vectors c1c2

set.seed(2017)
c1 <- sample(1000)
c2 <- sample(1000)

library(microbenchmark)
library(Matrix)

res <- microbenchmark(
    method_jaySF = {
        example_out <- matrix(0, length(c1) + 1, length(c2))
        diag(example_out) <- c1
        diag(example_out[-1, ]) <- c2
    },
    method_Roland = {
        bandSparse(length(c1) + 1, length(c2), 0:-1, list(c1, c2))
    },
    method_Onyambu = {
        a = matrix(0,length(c1)+1,length(c2))
        a[row(a)==col(a)]=c1
        a[row(a)==col(a)+1]=c2
    },
    method_Gregor = {
        rbind(diag(c1), 0) + rbind(0, diag(c2))
    },
    method_Maurits = {
        matrix(unlist(sapply(seq_along(c1), function(i)
    replace(rep(0, length(c1) + 1), i:(i+1), c(c1[i], c2[i])))),
    ncol = length(c1))
    }
)
res;
#Unit: microseconds
#           expr       min       lq      mean    median         uq        max
#   method_jaySF 31894.439 37850.81  58452.41 40560.992  46224.579 208862.631
#  method_Roland   940.535  1342.32   1675.29  1457.928   1869.621   8228.287
# method_Onyambu 55033.797 66083.67 124364.44 73143.798 195886.534 274383.132
#  method_Gregor 37784.977 44049.87  69918.85 47539.793  53122.162 243774.715
# method_Maurits 14961.924 21378.77  42834.89 23536.966  27270.953 186088.146

autoplot(res)

enter image description here


2
投票

您应该创建一个稀疏矩阵。使用Matrix包:

c1 <- seq(1, 4)
c2 <- seq(5, 8)

library(Matrix)
bandSparse(5, 4, 0:-1, list(c1, c2))
#5 x 4 sparse Matrix of class "dgCMatrix"
#            
#[1,] 1 . . .
#[2,] 5 2 . .
#[3,] . 6 3 .
#[4,] . . 7 4
#[5,] . . . 8

1
投票
 a = matrix(0,length(c1)+1,length(c2))
 a[row(a)==col(a)]=c1
 a[row(a)==col(a)+1]=c2
 a
     [,1] [,2] [,3] [,4]
[1,]    1    0    0    0
[2,]    5    2    0    0
[3,]    0    6    3    0
[4,]    0    0    7    4
[5,]    0    0    0    8
© www.soinside.com 2019 - 2024. All rights reserved.