aman
aman

Reputation: 151

Finding interconnected neighbours in a 2d matrix

I have a similar matrix as below

  a| b | c | d | e 
1|1| 0 | 0 | 1 | 0
2|0| 0 | 1 | 0 | 1
3|0| 1 | 0 | 0 | 0
4|0| 1 | 0 | 1 | 0
5|0| 1 | 0 | 0 | 0
6|1| 0 | 0 | 0 | 0

I want to get the neighbors for each letter. Neighbours are defined as follows for example "a" and "d" are 1 for row 1 hence they are neighbours now "d" is 1 for row 1 and 4 hence any letter which is 1 for row 4 will be neighbour for "d" as well as "a". Here "b" is 1 for row 4 and hence will be neighbour to bot "a" and "d". And so on ...

the output should be

   a    | b     |  c    |  d    |  e 
   3    | 3     |  2    |  3    |  2
 abd    |abd    |     ce|    abd|     ce
 1,3,4,6|1,3,4,6|    2,5|1,3,4,6|    2,5

where second rows tells the number of neighbours (including the alphabet itself). third row tells the neighbours fourth row tells the rowname connecting these neighbours

Upvotes: 1

Views: 68

Answers (1)

ThomasIsCoding
ThomasIsCoding

Reputation: 102309

As mentioned by @Sotos in comments, you can use package igraph to visualize the matrix, and the code below is just to give you some idea how to make it

library(igraph)
M <- crossprod(m)
g <- graph_from_adjacency_matrix(M,mode = "undirected")
plot(g)

and you will see how the vertices are connected. enter image description here

Then, your expected output (except for the last row since I have no clue how you get it) can be achieved as below:

r <- clusters(g)

vtx <- names(r$membership)
len <- ave(seq(r$membership),r$membership,FUN = length)
cnm <- ave(vtx,r$membership,FUN = function(x) paste0(x,collapse = ","))

dfout <- setNames(as.data.frame(rbind(len,cnm)),vtx)

such that

> dfout
        a     b   c     d   e
len     3     3   2     3   2
cnm a,b,d a,b,d c,e a,b,d c,e

NOTE

I think you question might be for clustering (not neighboring), so you can use the commands like below:

> cluster_infomap(g)
IGRAPH clustering infomap, groups: 2, mod: 0.38
+ groups:
  $`1`
  [1] "a" "b" "d"

  $`2`
  [1] "c" "e"

or

> clusters(g)
$membership
a b c d e 
1 1 2 1 2 

$csize
[1] 3 2

$no
[1] 2

DATA

m <- structure(c(1L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 1L, 1L, 1L, 0L, 0L, 
1L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 1L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 
0L), .Dim = 6:5, .Dimnames = list(c("1", "2", "3", "4", "5", 
"6"), c("a", "b", "c", "d", "e")))

Upvotes: 1

Related Questions