2

My matrice is like this:

  [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
 [1,]    0    0    0    0    0    0    0    0    0
 [2,]    0    0    0    0    0    0    0    0    0
 [3,]    0    0    0    0    0    0    0    0    0
 [4,]    0    0    0    0    0    0    0    1    1
 [5,]    0    0    0    0    0    0    1    1    0
 [6,]    0    0    0    0    0    1    0    0    0
 [7,]    0    0    0    0    1    1    0    0    0
 [8,]    0    0    0    0    1    0    0    0    0
 [9,]    0    0    0    0    1    0    0    0    0
[10,]    0    0    0    0    1    1    0    0    0
[11,]    0    0    0    0    0    1    0    0    0
[12,]    0    0    0    0    0    1    1    1    1
[13,]    0    0    0    0    0    0    0    0    0
[14,]    0    0    0    0    0    0    0    0    0
[15,]    0    0    0    0    0    0    0    0    0
[16,]    0    0    0    0    0    0    0    0    0
[17,]    0    0    0    0    0    0    0    0    0
      [,10] [,11] [,12] [,13] [,14] [,15] [,16] [,17]
 [1,]     0     0     0     0     0     0     0     0
 [2,]     0     0     0     0     0     0     0     0
 [3,]     0     0     0     0     0     0     0     0
 [4,]     1     1     0     0     0     0     0     0
 [5,]     0     1     0     0     0     0     0     0
 [6,]     0     1     0     0     0     0     0     0
 [7,]     0     1     0     0     0     0     0     0
 [8,]     0     1     0     0     0     1     0     0
 [9,]     0     1     0     0     0     1     0     0
[10,]     1     1     0     0     0     1     0     0
[11,]     1     1     0     1     1     0     0     0
[12,]     1     1     1     1     0     0     0     0
[13,]     0     0     0     0     0     0     0     0
[14,]     0     0     0     0     0     0     0     0
[15,]     0     0     0     0     0     0     0     0
[16,]     0     0     0     0     0     0     0     0
[17,]     0     0     0     0     0     0     0     0
      [,18]
 [1,]     0
 [2,]     0
 [3,]     0
 [4,]     0
 [5,]     0
 [6,]     0
 [7,]     0
 [8,]     0
 [9,]     0
[10,]     0
[11,]     0
[12,]     0
[13,]     0
[14,]     0
[15,]     0
[16,]     0
[17,]     0

How can I find the number of values which has 1 in neighbour? (neighbour of a pixel is the value above the value, below the value, to the right, to the left, top right, top left, below left, below right).

I just need to get a way of devising how I can even find the number of values which has 1 above/below it. If I get that, I'll be able to solve the other variables of the problem (top right and such).

I've been experimenting around with which such as which(imageMatrix == 1, arr.ind = TRUE)[1,1]. But I cannot figure it out. (ImageMatrix is the name of the matrix)

Can anyone lend me a hand on how I can begin with the problem so I get a jump?

Dennis Main
  • 133
  • 6
  • I could try doing a loop to go through each values of the matrice and then compare with the values around it? But how do I find the row & column of let's say *I* if I use *for (i in ImageMatrix)* – Dennis Main Mar 14 '22 at 18:20
  • 1
    Looking through [the answers here](https://stackoverflow.com/q/29105175/903061) should give you some ideas. – Gregor Thomas Mar 14 '22 at 18:42

1 Answers1

5

In the following we use the example matrix m generated reproducibly in the Note at the end.

1) Append a row and column of zeros on each end and then apply rollsum , transpose, apply it again and transpose again. Finally subtract the original matrix so that only neighbors are counted. This solution is the most compact of those here.

library(zoo)

m2 <- rbind(0, cbind(0, m, 0), 0)
t(rollsum(t(rollsum(m2, 3)), 3)) - m
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    2    3    5    3    2
## [2,]    3    5    6    4    2
## [3,]    2    6    5    5    2
## [4,]    2    5    2    2    1
## [5,]    1    3    2    2    1

2) A second approach is the following. It would be much faster than the others here.

nr <- nrow(m)
nc <- ncol(m)

mm <- cbind(m[, -1], 0) + m + cbind(0, m[, -nc]) 
rbind(mm[-1, ], 0) + mm + rbind(0, mm[-nr, ]) - m
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    2    3    5    3    2
## [2,]    3    5    6    4    2
## [3,]    2    6    5    5    2
## [4,]    2    5    2    2    1
## [5,]    1    3    2    2    1

3) Using loops we can write the following. It is probably the most straight forward. Note that subscripting by 0 omits that element and i %% 6 equals i if i is in 1, 2, 3, 4, 5 and equals 0 if i equals 0 or 6.

nr <- nrow(m); nr1 <- nr + 1
nc <- ncol(m); nc1 <- nc + 1

mm <- 0 * m  # initialize result
for(i in seq_len(nr)) 
  for(j in seq_len(nc)) 
    mm[i, j] <- sum(m[seq(i-1, i+1) %% nr1, seq(j-1, j+1) %% nc1]) - m[i,j]
mm
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    2    3    5    3    2
## [2,]    3    5    6    4    2
## [3,]    2    6    5    5    2
## [4,]    2    5    2    2    1
## [5,]    1    3    2    2    1

Note

set.seed(123)
m <- +matrix(rnorm(25) > 0, 5)

m
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    0    1    1    1    0
## [2,]    0    1    1    1    0
## [3,]    1    0    1    0    0
## [4,]    1    0    1    1    0
## [5,]    1    0    0    0    0
G. Grothendieck
  • 254,981
  • 17
  • 203
  • 341
  • Hello, thank you for the answer! I'm a bit new to R, I'm sorry. Could you help in explaining through the code so I can understand how it works? How can we then find only neighbours, let's say we want from the left side only? Just trying to understand so I can work on this. – Dennis Main Mar 14 '22 at 19:16
  • 1
    In (1) the `rollsum` takes a rolling sum using a window of 3 acting on each column separately. If you just want the left side then replace the `m[i,j]<-` line in (3) with `mm[i, j] <- sum(m[seq(i-1, i+1) %% nr1, j-1])` – G. Grothendieck Mar 15 '22 at 00:02