PCK1992
PCK1992

Reputation: 213

Changing blocks of values in a large matrix in R

I have large matrix of 1000x1000 entries. The 1's are organized in blocks, they always seperated from the other blocks by not overlapping on the row or column of the next block. To give you an example with a 12x12 matrix that consists of 3 blocks of 1s:

      111100000000
      111100000000
      111100000000
      111100000000
      000011110000
      000011110000
      000011110000
      000011110000
      000000001111
      000000001111
      000000001111
      000000001111

I want R to transfer the matrix into something like this(no matter the size of the matrix):

      111100000000
      111100000000
      111100000000
      111100000000
      000022220000
      000022220000
      000022220000
      000022220000
      000000003333
      000000003333
      000000003333
      000000003333

Thanks in advance!

Data

structure(c(1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 
0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 
0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 
1), .Dim = c(12L, 12L))

Upvotes: 2

Views: 130

Answers (1)

Pierre L
Pierre L

Reputation: 28441

Multiply the matrix by the block group. 0's will remain the same and ones will take their group value:

len <- sum(mat[,1])
mat * rep(1:(nrow(mat)/len), each=len)
#       [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
# [1,]     1    1    1    1    0    0    0    0    0     0     0     0
# [2,]     1    1    1    1    0    0    0    0    0     0     0     0
# [3,]     1    1    1    1    0    0    0    0    0     0     0     0
# [4,]     1    1    1    1    0    0    0    0    0     0     0     0
# [5,]     0    0    0    0    2    2    2    2    0     0     0     0
# [6,]     0    0    0    0    2    2    2    2    0     0     0     0
# [7,]     0    0    0    0    2    2    2    2    0     0     0     0
# [8,]     0    0    0    0    2    2    2    2    0     0     0     0
# [9,]     0    0    0    0    0    0    0    0    3     3     3     3
# [10,]    0    0    0    0    0    0    0    0    3     3     3     3
# [11,]    0    0    0    0    0    0    0    0    3     3     3     3
# [12,]    0    0    0    0    0    0    0    0    3     3     3     3

Edit

If the block groups vary within the matrix we will have to differentiate one block ending and another beginning using this instead:

library(data.table)
mat * rleid(apply(mat, 1, paste, collapse=""))

Upvotes: 2

Related Questions