Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Counting the number of ordered pairs in matrix in R

Given matrix m as follows (row-wise permutations of 1-5):

    # [,1] [,2] [,3] [,4] [,5]
 # [1,]    1    5    2    4    3
 # [2,]    2    1    4    3    5
 # [3,]    3    4    1    2    5
 # [4,]    4    1    3    2    5
 # [5,]    4    3    1    2    5
 # [6,]    1    4    2    3    5
 # [7,]    4    3    2    5    1
 # [8,]    4    1    3    5    2
 # [9,]    1    2    3    4    5
# [10,]    4    3    2    1    5

I'd like to know the number of times each element 1-5 is preceded another element per row (i.e. considering all possible pairs)

For example, for the pair (1, 5), 1 precedes 5, 9 times among all rows. Another example, for the pair (3, 1), 3 precedes 1, 4 times among all rows. I would like to have the same results for all possible pairs among all rows. That is,

# (1, 2), (1, 3), (1, 4), (1, 5)
# (2, 1), (2, 3), (2, 4), (2, 5)
# (3, 1), (3, 2), (3, 4), (3, 5)
# (4, 1), (4, 2), (4, 3), (4, 5)
# (5, 1), (5, 2), (5, 3), (5, 4)

m <- structure(c(1L, 2L, 3L, 4L, 4L, 1L, 4L, 4L, 1L, 4L, 5L, 1L, 4L, 
1L, 3L, 4L, 3L, 1L, 2L, 3L, 2L, 4L, 1L, 3L, 1L, 2L, 2L, 3L, 3L, 
2L, 4L, 3L, 2L, 2L, 2L, 3L, 5L, 5L, 4L, 1L, 3L, 5L, 5L, 5L, 5L, 
5L, 1L, 2L, 5L, 5L), .Dim = c(10L, 5L))

How one can do that efficiently in R?

EDIT

How would you do the same for this matrix?

      # [,1] [,2] [,3] [,4] [,5]
 # [1,]    3    4    1    5    0
 # [2,]    1    2    5    3    0
 # [3,]    3    5    0    0    0
 # [4,]    4    5    0    0    0
 # [5,]    3    4    1    5    2
 # [6,]    3    1    2    0    0
 # [7,]    4    1    5    2    0
 # [8,]    4    3    5    2    0
 # [9,]    5    2    0    0    0
# [10,]    5    4    2    0    0

m <- structure(c(3, 1, 3, 4, 3, 3, 4, 4, 5, 5, 4, 2, 5, 5, 4, 1, 1, 
3, 2, 4, 1, 5, 0, 0, 1, 2, 5, 5, 0, 2, 5, 3, 0, 0, 5, 0, 2, 2, 
0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0), .Dim = c(10L, 5L))
like image 817
989 Avatar asked Dec 18 '22 15:12

989


1 Answers

Here is a vectorized solution, without apply:

func <- function(a,b) sum((which(!t(m-b)) - which(!t(m-a)))>0)

#> func(1,5)
#[1] 9
#> func(5,1)
#[1] 1

And to generate all the wanted combinations you can simply do:

N = combn(1:5, 2)
cbind(N, N[nrow(N):1,])

You then need only one loop to iterate over columns and apply the function.

like image 59
Colonel Beauvel Avatar answered Dec 28 '22 07:12

Colonel Beauvel