Search code examples
rsapply

How I can compare in R two columns of a matrix with two others and generate at the same time a new matrix?


I have a dataset:

time   delta
0.47   0
0.01   1
0.30   1
0.07   0
0.38   0
0.68   1
0.13   0
0.09   1
0.08   1
0.04   0
0.13   0
0.41   1
0.22   0
0.11   0
0.85   0
0.26   0

I'm using R and I need to compare this matrix with itself. I want to generate a new matrix 16*16 with values:

1 time_i > time_j  &  delta_i= delta_j != 0;

0 otherwise.

where i, j = 1,..., 16.

I tried to use the sapply() function, but it is useful only if I want to compare with respect one condition.

Could someone help me? Thank you in advance.


Solution

  • You can use outer to apply a function to every pair of elements in two vectors, so you could do one outer for each of the two logical comparisons, combine them with a logical AND, then convert to numeric. Here I am assuming your matrix is called m:

    1*(outer(m[,1], m[,1], `>`) & outer(m[,2], m[,2], function(x, y) x == y & x != 0))
    

    This gives the following output:

    #>      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14]
    #> [1,]    0    0    0    0    0    0    0    0    0     0     0     0     0     0
    #> [2,]    0    0    0    0    0    0    0    0    0     0     0     0     0     0
    #> [3,]    0    1    0    0    0    0    0    1    1     0     0     0     0     0
    #> [4,]    0    0    0    0    0    0    0    0    0     0     0     0     0     0
    #> [5,]    0    0    0    0    0    0    0    0    0     0     0     0     0     0
    #> [6,]    0    1    1    0    0    0    0    1    1     0     0     1     0     0
    #> [7,]    0    0    0    0    0    0    0    0    0     0     0     0     0     0
    #> [8,]    0    1    0    0    0    0    0    0    1     0     0     0     0     0
    #> [9,]    0    1    0    0    0    0    0    0    0     0     0     0     0     0
    #>[10,]    0    0    0    0    0    0    0    0    0     0     0     0     0     0
    #>[11,]    0    0    0    0    0    0    0    0    0     0     0     0     0     0
    #>[12,]    0    1    1    0    0    0    0    1    1     0     0     0     0     0
    #>[13,]    0    0    0    0    0    0    0    0    0     0     0     0     0     0
    #>[14,]    0    0    0    0    0    0    0    0    0     0     0     0     0     0
    #>[15,]    0    0    0    0    0    0    0    0    0     0     0     0     0     0
    #>[16,]    0    0    0    0    0    0    0    0    0     0     0     0     0     0
    #>       [,15] [,16]
    #> [1,]     0     0
    #> [2,]     0     0
    #> [3,]     0     0
    #> [4,]     0     0
    #> [5,]     0     0
    #> [6,]     0     0
    #> [7,]     0     0
    #> [8,]     0     0
    #> [9,]     0     0
    #>[10,]     0     0
    #>[11,]     0     0
    #>[12,]     0     0
    #>[13,]     0     0
    #>[14,]     0     0
    #>[15,]     0     0
    #>[16,]     0     0
    

    You can more easily check that the elements of the matrix are in the correct position by making a matrix of the rows and columns where a 1 is to be found:

    which(res == 1, arr.ind = TRUE)
    #>       row col
    #>  [1,]   3   2
    #>  [2,]   6   2
    #>  [3,]   8   2
    #>  [4,]   9   2
    #>  [5,]  12   2
    #>  [6,]   6   3
    #>  [7,]  12   3
    #>  [8,]   3   8
    #>  [9,]   6   8
    #> [10,]  12   8
    #> [11,]   3   9
    #> [12,]   6   9
    #> [13,]   8   9
    #> [14,]  12   9
    #> [15,]   6  12
    

    The first entry in this table tells us that the criteria were met for row 3 of the original matrix when compared to row 2 of the original matrix. It is easy to confirm that this is indeed the case.