Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vector to Matrix of Differences between elements

Tags:

r

vector

matrix

Given a vector:

vec <-1:5

What is an efficient way to create a matrix where the difference between the vector components are displayed in a matrix, a difference matrix, if you will. I could obviously do this with two for loops, but I need to do this with a much larger set of data. There is likely a term for this matrix I am trying to make, but I am not having any luck finding it. Here is what the result would look like.

m<-matrix(c(NA), ncol=5, nrow=5, byrow=TRUE)
rownames(m)<-1:5;colnames(m)<-1:5
for(i in 1:5){for(j in 1:5){m[i,j]<-(as.numeric(rownames(m)[i])-as.numeric(rownames(m)[j]))}}
m

Thanks for any help!

like image 392
Michael Davidson Avatar asked Nov 18 '13 02:11

Michael Davidson


2 Answers

This is typically done with outer.

outer(1:5, 1:5, '-')

See ?outer for details.

like image 163
John Avatar answered Oct 05 '22 08:10

John


The answers here may well do the job just fine, but I ended up just throwing together a function that should do this with some simple brute force base logic. Thought I'd share here in case anyone else might get use out of it.

diffmat = function(x){
  D = matrix(as.numeric(NA), NROW(x), NROW(x))
  for (i in 1:NROW(x)){
    d = x[[i]] - x[-i]
    D[i,-i] = d
  }
  if (!all(is.na(diag(D)))){
    stop("Not all diagonal elements zero")
  }
  diag(D) = 0
  if (!is.null(names(x))) colnames(D) = rownames(D) = names(x)
  return(D)
}

Use example:

> x = runif(5)
> names(x) = LETTERS[1:length(x)]
> x
         A          B          C          D          E
0.22095809 0.16006394 0.07402069 0.29795031 0.16199981
> diffmat(x)
            A            B          C           D            E
A  0.00000000  0.060894142 0.14693739 -0.07699223  0.058958278
B -0.06089414  0.000000000 0.08604325 -0.13788637 -0.001935864
C -0.14693739 -0.086043252 0.00000000 -0.22392962 -0.087979116
D  0.07699223  0.137886368 0.22392962  0.00000000  0.135950504
E -0.05895828  0.001935864 0.08797912 -0.13595050  0.000000000
like image 26
Jacob Amos Avatar answered Oct 05 '22 06:10

Jacob Amos