Suppose I have a symmetric matrix:

> mat <- matrix(c(1,0,1,0,0,0,1,0,1,1,0,0,0,0,0,0), ncol=4, nrow=4)
> mat
     [,1] [,2] [,3] [,4]
[1,]    1    0    1    0
[2,]    0    0    1    0
[3,]    1    1    0    0
[4,]    0    0    0    0

which I would like to analyse:

> which(mat==1, arr.ind=T)
     row col
[1,]   1   1
[2,]   3   1
[3,]   3   2
[4,]   1   3
[5,]   2   3

now the question is: how am I not considering duplicated cells? As the resulting index matrix shows, I have the rows 2 and 4 pointing respectively to (3,1) and (1,3), which is the same cell.

How do I avoid such a situation? I only need a reference for each cell, even though the matrix is symmetric. Is there an easy way to deal with such situations?

EDIT:

I was thinking about using upper.tri or lower.tri but in this case what I get is an vector version of the matrix and I am not able to get back to the (row, col) notation.

> which(mat[upper.tri(mat)]==1, arr.ind=T)
[1] 2 3

EDIT II

expected output would be something like an unique over the couple of (row, col) and (col, row):

     row col
[1,]   1   1
[2,]   3   1
[3,]   3   2

1 Answers

2
Ronak Shah On Best Solutions

Since you have symmetrical matrix you could do

which(mat == 1 & upper.tri(mat, diag = TRUE), arr.ind = TRUE)

#     row col
#[1,]   1   1
#[2,]   1   3
#[3,]   2   3

OR

which(mat == 1 & lower.tri(mat, diag = TRUE), arr.ind = TRUE)