farah
April 20, 2022, 12:59am
1
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)
farah
April 21, 2022, 3:43am
3
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]
.
farah
April 21, 2022, 4:07am
6
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
farah
April 21, 2022, 4:12am
8
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
system
Closed
April 28, 2022, 4:15am
10
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.