如果我有任意尺寸的矩阵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
答案 0 :(得分:5)
您也可以使用row
和col
:
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