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!
This is typically done with outer
.
outer(1:5, 1:5, '-')
See ?outer
for details.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With