在给定矢量的情况下生成5x5矩阵,并且反对角地排列0

时间:2016-07-18 07:22:14

标签: r matrix vectorization diagonal

鉴于以下向量:

v <- c(2, 4, 6, 8)

需要以下矩阵,其中行方向交替地从右到左和从左到右(通过从顶部到底部遍历矩阵)并且反对角线设置为零。

8  6  4  2  0
2  4  6  0  8
8  6  0  4  2
2  0  4  6  8
0  8  6  4  2

如何在R中有效地完成这项工作?

2 个答案:

答案 0 :(得分:3)

这个怎么样?

v <- c(2, 4, 6, 8)

首先创建一个方向为v的矩阵。因为矩阵是按列填充的,所以我们最后必须进行转置。

m <- matrix(0, length(v), length(v) + 1)
m[, c(FALSE, TRUE)] <- rev(v)
m[, c(TRUE, FALSE)] <- v

m <- t(m)

现在通过填充上下三角形然后反转列来创建零反对角线:

m1 <- matrix(0, length(v) + 1, length(v) + 1)
m1[upper.tri(m1)] <- m[upper.tri(m, TRUE)]
m1[lower.tri(m1)] <- m[lower.tri(m)]
m1[, rev(seq_len(ncol(m1)))]

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

我希望这对于更大尺寸的矢量来说是一种有效的解决方案。对于小型矢量,基于循环的解决方案可能更快。

答案 1 :(得分:0)

以下是解决此问题的更好方法:

rv <- rev(v)
f <- function(vec, pos){z<-rep(NA,length(vec)+1);z[pos]<-0;z[is.na(z)]<-vec;z;}

t(sapply(5:1, function(x) {if (x%%2==1) f(rv,x) else f(v,x)}))

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

功能f,将0插入指定位置vec的{​​{1}}。

<强> BENCHMARKING

pos