Reputation: 45
How can I shrink matrix in R?
I have matrix of random numbers
a = 5
myMatrix <- matrix(rnorm(a*a),ncol=a)
diag(myMatrix) <- 0
myMatrix
[,1] [,2] [,3] [,4] [,5]
[1,] 0.00000000 -0.6610853 -0.7072980 1.1899888 0.8607588
[2,] -0.68123068 0.0000000 0.6870920 -1.1284451 -1.6981509
[3,] 0.88768478 1.3605526 0.0000000 -0.4632346 1.2166078
[4,] 0.01453834 2.1967867 0.3330623 0.0000000 -0.6867518
[5,] -0.09157931 -0.7998323 -0.8322993 1.4207877 0.0000000
How can I shrink (simplify) this matrix. For example
myMatrix[1,2]
[1] -0.6610853
myMatrix[2,1]
[1] -0.6812307
So this pair gets simplified to one number (eg., myMatix[2,1] - myMatix[1,2]
). How to do this for all pairs (like 1,3;1,4)?
I am not from mathematics background and I don't know specific terminology, but I hope that there is simple solution in R for what I want.
PS. This is not homework.
Upvotes: 1
Views: 128
Reputation: 887223
You could try
myMatrix[lower.tri(myMatrix)] - t(myMatrix)[lower.tri(t(myMatrix))]
#[1] -0.02014538 1.59498278 -1.17545046 -0.95233811 0.67346060 3.32523180
#[7] 0.89831860 0.79629690 -2.04890710 2.10753950
Or it could be written as
(myMatrix-t(myMatrix))[lower.tri(myMatrix)]
#[1] -0.02014538 1.59498278 -1.17545046 -0.95233811 0.67346060 3.32523180
#[7] 0.89831860 0.79629690 -2.04890710 2.10753950
myMatrix <- structure(c(0, -0.68123068, 0.88768478, 0.01453834,
-0.09157931,
-0.6610853, 0, 1.3605526, 2.1967867, -0.7998323, -0.707298, 0.687092,
0, 0.3330623, -0.8322993, 1.1899888, -1.1284451, -0.4632346,
0, 1.4207877, 0.8607588, -1.6981509, 1.2166078, -0.6867518, 0
), .Dim = c(5L, 5L))
Upvotes: 0
Reputation: 35314
Here's one possible solution using combn()
and then sapply()
:
a <- 5;
m <- matrix(c(0,-0.68123068,0.88768478,0.01453834,-0.09157931,-0.6610853,0,1.3605526,2.1967867,-0.7998323,-0.707298,0.687092,0,0.3330623,-0.8322993,1.1899888,-1.1284451,-0.4632346,0,1.4207877,0.8607588,-1.6981509,1.2166078,-0.6867518,0),a);
c <- combn(a,2);
sapply(1:ncol(c),function(x) m[c[2,x],c[1,x]]-m[c[1,x],c[2,x]]);
## [1] -0.02014538 1.59498278 -1.17545046 -0.95233811 0.67346060 3.32523180 0.89831860 0.79629690 -2.04890710 2.10753950
Edit: Actually, here's a better vectorized approach, using c
from above:
m[c[2,]+(c[1,]-1)*a]-m[c[1,]+(c[2,]-1)*a];
## [1] -0.02014538 1.59498278 -1.17545046 -0.95233811 0.67346060 3.32523180 0.89831860 0.79629690 -2.04890710 2.10753950
Upvotes: 1