R: Recode cells in matrix with no symmetric match

Viewed 44

I have an adjacency matrix of 0s and 1s that indicate tie nominations. Some nominations are not reciprocated, so the matrix is asymmetrical.

I would like to recode the cell values from 1 to 0 if they do not have a symmetrical match.

Sample small matrix:

     [,1] [,2] [,3] [,4]
[1,]    0    1    0    1
[2,]    0    0    1    0
[3,]    0    0    0    1
[4,]    1    0    1    0

Output desired:

     [,1] [,2] [,3] [,4]
[1,]    0    0    0    1
[2,]    0    0    0    0
[3,]    0    0    0    1
[4,]    1    0    1    0
3 Answers

First the data, then a one-liner will do it. Treat 0/1 as logical and AND the matrix with its transpose. +() coerces to integer and the trick is done.

x <- scan(text="    0    1    0    1
    0    0    1    0
    0    0    0    1
    1    0    1    0")
x <- matrix(x, nrow = 4, byrow = TRUE)

y <- +(x & t(x))
y
#>      [,1] [,2] [,3] [,4]
#> [1,]    0    0    0    1
#> [2,]    0    0    0    0
#> [3,]    0    0    0    1
#> [4,]    1    0    1    0

Created on 2022-02-09 by the reprex package (v2.0.1)

We can use pmin like below

> pmin(x,t(x))
     [,1] [,2] [,3] [,4]
[1,]    0    0    0    1
[2,]    0    0    0    0
[3,]    0    0    0    1
[4,]    1    0    1    0

Here is another way for this specific case. This is slower than @ThomasIsCoding's solution, and would not work for numbers other than 1, 0. If your matrix allows an inverse, then:

A <- structure(c(0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0), .Dim = c(4L, 4L))

A_inv <- solve(A)
A_inv + t(A_inv)

     [,1] [,2] [,3] [,4]
[1,]    0    0    0    1
[2,]    0    0    0    0
[3,]    0    0    0    1
[4,]    1    0    1    0
Related