Say we want to get a square matrix into a vector. We can do:
to.upper<-function(X) X[upper.tri(X,diag=TRUE)]
but this will give us our upper triangular matrix as a vector by column, i.e.:
> X
[,1] [,2] [,3] [,4] [,5]
[1,] -0.329 -0.825 -0.906 0.834 0.702
[2,] 1.195 -0.237 -1.132 -0.827 0.150
[3,] -0.097 -1.270 -1.397 0.450 0.791
[4,] 0.883 -0.574 1.538 -2.632 0.135
[5,] 1.993 -0.520 -0.071 0.094 -0.064
> to.upper(X)
[1] -0.329 -0.825 -0.237 -0.906 -1.132 -1.397 0.834 -0.827 0.450 -2.632 0.702 0.150 0.791 0.135 -0.064
[,1] [,2] [,3] [,4] [,5]
[1,] -0.329 -0.825 -0.906 0.834 0.702
[2,] 1.195 -0.237 -1.132 -0.827 0.150
[3,] -0.097 -1.270 -1.397 0.450 0.791
[4,] 0.883 -0.574 1.538 -2.632 0.135
[5,] 1.993 -0.520 -0.071 0.094 -0.064
> to.upper(X)
[1] -0.329 -0.825 -0.237 -0.906 -1.132 -1.397 0.834 -0.827 0.450 -2.632 0.702 0.150 0.791 0.135 -0.064
If we want to get our upper triangular matrix as a vector by row (as I did), we can use:
to.upper<-function(X) t(X)[lower.tri(X,diag=TRUE)]
which works just as we'd hoped, i.e.:
> X
[,1] [,2] [,3] [,4] [,5]
[1,] -0.329 -0.825 -0.906 0.834 0.702
[2,] 1.195 -0.237 -1.132 -0.827 0.150
[3,] -0.097 -1.270 -1.397 0.450 0.791
[4,] 0.883 -0.574 1.538 -2.632 0.135
[5,] 1.993 -0.520 -0.071 0.094 -0.064
> to.upper(X)
[1] -0.329 -0.825 -0.906 0.834 0.702 -0.237 -1.132 -0.827 0.150 -1.397 0.450 0.791 -2.632 0.135 -0.064
[,1] [,2] [,3] [,4] [,5]
[1,] -0.329 -0.825 -0.906 0.834 0.702
[2,] 1.195 -0.237 -1.132 -0.827 0.150
[3,] -0.097 -1.270 -1.397 0.450 0.791
[4,] 0.883 -0.574 1.538 -2.632 0.135
[5,] 1.993 -0.520 -0.071 0.094 -0.064
> to.upper(X)
[1] -0.329 -0.825 -0.906 0.834 0.702 -0.237 -1.132 -0.827 0.150 -1.397 0.450 0.791 -2.632 0.135 -0.064
(Note that if we have a symmetric matrix than the upper triangular matrix by row & the lower triangular matrix by column are the same. Here I used a non-symmetric square matrix so that we could tell these apart.)
Similarly, here's a function that puts a vector into the upper diagonal of a matrix - by row:
ReplyDeleteupper.diag<-function(x){
m<-(-1+sqrt(1+8*length(x)))/2
X<-lower.tri(matrix(NA,m,m),diag=TRUE)
X[X==TRUE]<-x
t(X)
}
Hi
DeleteCould you please explain why m<-(-1+sqrt(1+8*length(x)))/2
thanks
Hmmm. This is a very old post. Must be the solution for the number of elements in the upper diagonal of a square matrix of dimension m x m. In particular, x=m*(m-1)/2 solved for m.
DeleteThank you so much for you post! I just need this!!!
ReplyDelete