沿矩阵的对角线设置值

时间:2019-02-04 04:00:10

标签: r matrix

我正在尝试使用matrix()diag()函数创建以下模式,但使用100 x 100矩阵而不是5 x 5。

5 x 5矩阵:

| 0 1 0 0 0 |
| 1 0 1 0 0 |
| 0 1 0 1 0 |
| 0 0 1 0 1 |
| 0 0 0 1 0 |

换句话说,我想有两个对角线,其值为1,一个在主对角线的左侧,一个在主对角线的右侧。

3 个答案:

答案 0 :(得分:2)

对于主对角线,行索引和列索引相同。对于其他对角线,行索引和列索引之间存在1之间的差异。直接生成这些索引并在这些索引中分配值。

sz = 5
m = matrix(0, sz, sz)
inds1 = cbind(r = 1:(sz-1), c = 2:sz)
inds2 = cbind(r = 2:sz, c = 1:(sz-1))
m[inds1] = 1
m[inds2] = 1
m

# OR, to make it concise
m = matrix(0, sz, sz)
inds = rbind(cbind(1:(sz-1), 2:sz), cbind(2:sz, 1:(sz-1)))
replace(m, inds, 1)

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

答案 1 :(得分:2)

diag()函数(实际上是diag<-函数)可用于分配:

mat <- matrix( 0, 100,100)
diag(mat) <- 1
mat[1:10,1:10]
#-----------
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
 [1,]    1    0    0    0    0    0    0    0    0     0
 [2,]    0    1    0    0    0    0    0    0    0     0
 [3,]    0    0    1    0    0    0    0    0    0     0
 [4,]    0    0    0    1    0    0    0    0    0     0
 [5,]    0    0    0    0    1    0    0    0    0     0
 [6,]    0    0    0    0    0    1    0    0    0     0
 [7,]    0    0    0    0    0    0    1    0    0     0
 [8,]    0    0    0    0    0    0    0    1    0     0
 [9,]    0    0    0    0    0    0    0    0    1     0
[10,]    0    0    0    0    0    0    0    0    0     1

但是,您希望为子对角线和超对角线分配值,因此请对colrow使用逻辑表达式:

mat <- matrix( 0, 100,100)
mat[row(mat)==col(mat)-1] <- 1 
mat[row(mat)==col(mat)+1] <- 1
mat[1:10,1:10]
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
 [1,]    0    1    0    0    0    0    0    0    0     0
 [2,]    1    0    1    0    0    0    0    0    0     0
 [3,]    0    1    0    1    0    0    0    0    0     0
 [4,]    0    0    1    0    1    0    0    0    0     0
 [5,]    0    0    0    1    0    1    0    0    0     0
 [6,]    0    0    0    0    1    0    1    0    0     0
 [7,]    0    0    0    0    0    1    0    1    0     0
 [8,]    0    0    0    0    0    0    1    0    1     0
 [9,]    0    0    0    0    0    0    0    1    0     1
[10,]    0    0    0    0    0    0    0    0    1     0

(此方法不依赖于具有正方形矩阵。我记忆模糊,有一种更快的方法不需要使用rowcol。对于非常大的对象,每个对象函数返回的矩阵尺寸与其参数相同。)

答案 2 :(得分:1)

我们可以使用数学技巧创建一个适用于所有方阵的函数。

get_off_diagonal_1s <- function(n) {
  #Create a matrix with all 0's
  mat <- matrix(0, ncol = n, nrow = n)
  #Subtract row indices by column indices
  inds = row(mat) - col(mat)
  #Replace values where inds is 1 or -1
  mat[inds == 1 | inds == -1] = 1
  mat
}

get_off_diagonal_1s(5)
#     [,1] [,2] [,3] [,4] [,5]
#[1,]    0    1    0    0    0
#[2,]    1    0    1    0    0
#[3,]    0    1    0    1    0
#[4,]    0    0    1    0    1
#[5,]    0    0    0    1    0

get_off_diagonal_1s(8)
#     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
#[1,]    0    1    0    0    0    0    0    0
#[2,]    1    0    1    0    0    0    0    0
#[3,]    0    1    0    1    0    0    0    0
#[4,]    0    0    1    0    1    0    0    0
#[5,]    0    0    0    1    0    1    0    0
#[6,]    0    0    0    0    1    0    1    0
#[7,]    0    0    0    0    0    1    0    1
#[8,]    0    0    0    0    0    0    1    0