Search code examples
rmatrixvectorsimilaritysna

Transform attribute vector into a matrix with differences of elements


Similarly to this previous post I need to transfrom an attribute vector into a matrix. This time with differences between pairs of elements using R.

For example I have a vector which reports the age of N people (from 18 to 90 years). I need to convert this vector into a NxN matrix named A (with people names on rows and columns), where each cell Aij has the value of |age_i-age_j|, representing the absolute difference in age between the two people i and j.

Here is an example with 3 persons, first 18 yo, second 23 yo, third 60 yo, which produce this vector:

c(18, 23, 60) 

I want to transform it into this matrix:

A = matrix( c(0, 5, 42, 5, 0, 37, 42, 37, 0), nrow=3, ncol=3, byrow = TRUE) 

Solution

  • tmp <- c(18, 23, 60)
    

    You can use dist with a couple of arguments:

    dist(tmp, upper=TRUE, diag=TRUE)
       1  2  3
    1  0  5 42
    2  5  0 37
    3 42 37  0
    

    Note that the dist function returns a "dist" object, so you might want to coerce it to a matrix with as.matrix. Then you can drop the arguments:

    as.matrix(dist(tmp))
       1  2  3
    1  0  5 42
    2  5  0 37
    3 42 37  0
    

    Or again use outer. Feed it the subtraction operator, then take the absolute value.

    abs(outer(tmp, tmp, "-"))
    
         [,1] [,2] [,3]
    [1,]    0    5   42
    [2,]    5    0   37
    [3,]   42   37    0
    

    Presumably, dist will be faster than outer, since the algorithm can take advantage of the symmetry that is present in such a calculation, while outer is more general.