将值分配给"偏移"矩阵中的对角线

时间:2015-07-18 06:53:27

标签: r matrix

如果我有任意尺寸的矩阵x,对于此示例:

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

我希望从某个列开始将0更改为1,然后向下移动1,向右移动直到最后一列。因此,如果我从列[,3]开始,则更改将导致

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

我想也许是这样的x[,3:ncol(x)][1:ncol(x)] <- 1,但这给了我

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

3 个答案:

答案 0 :(得分:5)

您也可以使用rowcol

start_col <- 3
m[row(m) + start_col - 1 == col(m)] <- 1

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

m的位置:

m <- matrix(0, ncol = 5, nrow = 5)

答案 1 :(得分:2)

我们可以使用row/column索引。假设我们从中开始的任意列是&#39; n&#39;,创建一个从该列到最后一列的序列(&#39; n1&#39;),cbind这将是序列&#39; n1&#39;用于子集化&#39; x&#39;并用1替换值。

 n <- 3
 n1 <- n:ncol(x)
 x[cbind(seq(n1), n1)] <- 1
 x
 #     [,1] [,2] [,3] [,4] [,5]
 #[1,]    0    0    1    0    0
 #[2,]    0    0    0    1    0
 #[3,]    0    0    0    0    1
 #[4,]    0    0    0    0    0
 #[5,]    0    0    0    0    0

或另一种选择是

 x[seq(n1), n1] <- diag(ncol(x)-n+1)

或使用sparseMatrix

 library(Matrix)
 n <- 3
 rN <- 5
 cN <- 5
 n1 <- n:cN
 s1 <- sparseMatrix(seq_along(n1), n1, x=1)
 as.matrix(rbind(s1,matrix(0, nrow=rN-nrow(s1), ncol=ncol(s1))))

更新

稍微大一点的数据集

m1 <- matrix(0, nrow=1e6, ncol=100)
system.time({
  n <- 3
  n1 <- n:ncol(m1)
  m1[cbind(seq(n1), n1)] <- 1
 })
#  user  system elapsed 
# 0.117   0.096   0.212 
which(m1==1, arr.ind=TRUE)[,2]
#[1]   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21
#[20]  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36  37  38  39  40
#[39]  41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  57  58  59
#[58]  60  61  62  63  64  65  66  67  68  69  70  71  72  73  74  75  76  77  78
#[77]  79  80  81  82  83  84  85  86  87  88  89  90  91  92  93  94  95  96  97
#[96]  98  99 100

数据

 x <- matrix(0, 5, 5)

答案 2 :(得分:1)

如果修改了矩阵的各个条目,则不需要矢量化解。在这种情况下,可以有效地使用for循环:

m <- matrix(0,ncol=5, nrow=5)
loop_end <- min(ncol(m), nrow(m) + 2)
for (i in 3:loop_end){m[i-2,i] <- 1}

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