r - Assign values to an "offset" diagonal in a matrix -
if have matrix x
of arbitrary dimensions, example:
[,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
and want change 0s 1s starting column , moving 1 down , 1 right until end last column. if start column [,3]
change result in
[,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
i thought maybe x[,3:ncol(x)][1:ncol(x)] <- 1
gave me
[,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
we use row/column
indexing. suppose if arbitrary column start 'n', create sequence column last column ('n1'), cbind
sequence of 'n1', use subsetting 'x' , replace values 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
or option is
x[seq(n1), n1] <- diag(ncol(x)-n+1)
or using 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))))
update
on bigger dataset
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
data
x <- matrix(0, 5, 5)
Comments
Post a Comment