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!!!

ReplyDeleteI am definitely enjoying your website. You definitely have some great insight and great stories.

ReplyDeleteinfinite logo design

logo design app

This is an awesome post. Really very informative and creative contents. This concept is a good way to enhance knowledge. I like it and help me to development very well. Thank you for this brief explanation and very nice information. Well, got good knowledge.

ReplyDeletebest web design company in Chennai