0

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) 
Forinstance
  • 413
  • 4
  • 17

1 Answers1

1
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.

lmo
  • 37,904
  • 9
  • 56
  • 69
  • I'm also wondering if there is an easy way to do the opposite: transform a matrix of distances into an attribute array. Is there a reverse command for outer? – Forinstance Nov 03 '17 at 13:02
  • I can't think of something off the top of my head. This might be worth asking in a separate question. If you do, make sure to include a reproducible example. – lmo Nov 03 '17 at 18:51