Set condition in R, aij=aji,i!=j

Hi. I have a simple problem (i think so) but I can't get the answer out of me.

For example, I have a simple matrix

0 0 1 0 1
0 0 0 1 0
1 0 0 0 1
1 0 0 0 0
0 0 1 1 0

I want to set a condition where aij=aji and i!=j.

How do I do that in R? Thank you in advance!

Let's unpack the conditions. Aij == Aji means the matrix is symmetric for that element, or in other words that element stays the same if you transpose. i != j means you want to exclude the diagonal. So you can obtain it as follows:

A <- read.table(text = "0 0 1 0 1
0 0 0 1 0
1 0 0 0 1
1 0 0 0 0
0 0 1 1 0") |>
  as.matrix()


cond <- A == t(A)
diag(cond) <- FALSE
cond
#>         V1    V2    V3    V4    V5
#> [1,] FALSE  TRUE  TRUE FALSE FALSE
#> [2,]  TRUE FALSE  TRUE FALSE  TRUE
#> [3,]  TRUE  TRUE FALSE  TRUE  TRUE
#> [4,] FALSE FALSE  TRUE FALSE FALSE
#> [5,] FALSE  TRUE  TRUE FALSE FALSE
A
#>      V1 V2 V3 V4 V5
#> [1,]  0  0  1  0  1
#> [2,]  0  0  0  1  0
#> [3,]  1  0  0  0  1
#> [4,]  1  0  0  0  0
#> [5,]  0  0  1  1  0

Created on 2022-04-20 by the reprex package (v2.0.1)

Thank you! This really helps.

But what if I just want the element with value 1 is true for the condition?

I am so sorry if I deliver my question badly.

No sorry, I don't understand. What is "the element with value 1"?

Do you want to find all i,j such that Aij == 1, Aij == Aji, and i != j?

Or do you want to "mask" the matrix? In that case you can multiply it by cond:

cond
#>         V1    V2    V3    V4    V5
#> [1,] FALSE  TRUE  TRUE FALSE FALSE
#> [2,]  TRUE FALSE  TRUE FALSE  TRUE
#> [3,]  TRUE  TRUE FALSE  TRUE  TRUE
#> [4,] FALSE FALSE  TRUE FALSE FALSE
#> [5,] FALSE  TRUE  TRUE FALSE FALSE
A
#>      V1 V2 V3 V4 V5
#> [1,]  0  0  1  0  1
#> [2,]  0  0  0  1  0
#> [3,]  1  0  0  0  1
#> [4,]  1  0  0  0  0
#> [5,]  0  0  1  1  0
cond*A
#>      V1 V2 V3 V4 V5
#> [1,]  0  0  1  0  0
#> [2,]  0  0  0  0  0
#> [3,]  1  0  0  0  1
#> [4,]  0  0  0  0  0
#> [5,]  0  0  1  0  0

notice how in A*cond the element [1,5] has become 0, as A[1,5] != A[5,1].

I actually want to know the first one. But the latter is the best solution for my problem. I did not see that. Thank you so much!

1 Like

In that case, I believe A * cond as in my previous post is doing exactly what you want.

In R, * between two matrices means element-wise multiplication, and FALSE is interpreted as 0 (while TRUE is interpreted as 1). So:

1  2       *      FALSE  TRUE    =     0  2
3  4              TRUE  FALSE          3  0

So when you do

cond <- A == t(A)
diag(cond) <- FALSE

You get a matrix cond which is TRUE iff Aij == Aji and i != j

then when you do A * cond you get a matrix which is Aij if cond is TRUE, and 0 otherwise.

If you want a binary matrix which is 1 if cond is TRUE and Aij == 1, you can do:

cond <- A == t(A)
diag(cond) <- FALSE
B <- A * cond
C <- A == 1

That matrix C is what you want.

1 Like

I see. Thank you so much for your help! I learnt something new from you!

I'm glad it helped! Matrix arithmetics can be really confusing.

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.