TheGoat
TheGoat

Reputation: 2877

Convert a matrix back to xts

I have a matrix which represents the eigenvalues of a bunch of correlation matrices over time.

My matrix has a column with the time referenced in it but it's not a time series or an xts object as far as I can tell.

Ultimately I wish to convert this matrix into a format be it data frame or xts object which allows me to plot the N largest eigenvalues over time.

How can I convert this matrix into such a format, I guess XTS is preferable since it is a time series representation?

I have tried the following but I can't get it to work:

time.index <- as.POSIXct(colnames(eigen))
eigenXTS <- as.xts(eigen, order.by = time.index)

but I got an error back referring to

Error in xts(x, order.by = order.by, frequency = frequency, ...) : 
  NROW(x) must match length(order.by)

My data looks as follows:

> class(eigen)
[1] "matrix"

> str(eigen)
 num [1:12, 1:1334] 4.461 2.292 2.216 1.425 0.839 ...
 - attr(*, "dimnames")=List of 2
  ..$ : NULL
  ..$ : chr [1:1334] "2017-01-20 18:45:00" "2017-01-20 19:00:00" "2017-01-20 19:15:00" "2017-01-20 19:30:00" ...

> dim(eigen)
[1]   12 1334

> eigen[1:4,1:4]
     2017-01-20 18:45:00 2017-01-20 19:00:00 2017-01-20 19:15:00 2017-01-20 19:30:00
[1,]            4.461059            4.774866            4.658013            4.841987
[2,]            2.291520            2.330239            2.101630            2.145122
[3,]            2.215749            2.183941            1.935904            1.861954
[4,]            1.424662            1.277794            1.750168            1.762004

Can anyone point me in the direction of how to best approach solving this problem?

Upvotes: 1

Views: 478

Answers (2)

Joshua Ulrich
Joshua Ulrich

Reputation: 176718

as.xts expects the rownames of the matrix to be the timestamps. In your case, the colnames of eigen contain the timestamps. Therefore, you need to transpose eigen before calling as.xts.

xeigen <- as.xts(t(eigen))
xeigen
#                         [,1]     [,2]     [,3]     [,4]
# 2017-01-20 18:45:00 4.461059 2.291520 2.215749 1.424662
# 2017-01-20 19:00:00 4.774866 2.330239 2.183941 1.277794
# 2017-01-20 19:15:00 4.658013 2.101630 1.935904 1.750168
# 2017-01-20 19:30:00 4.841987 2.145122 1.861954 1.762004

Since an xts object is just a matrix with a time index, there's no need to coerce your matrix to a data.frame. Doing that would mean as.xts would have to coerce it back to a matrix.

Upvotes: 1

raymkchow
raymkchow

Reputation: 949

I think you need to transpose the matrix and convert to data.frame before converting it to xts so you can have rows as records (observations) and columns as variables.

> dput(eigen)
structure(list(`2017-01-20 18:45:00` = c("4.461059", "2.291520", 
"2.215749", "1.424662"), `2017-01-20 19:00:00` = c("4.774866", 
"2.330239", "2.183941", "1.277794"), `2017-01-20 19:15:00` = c("4.658013", 
"2.101630", "1.935904", "1.750168"), `2017-01-20 19:30:00` = c("4.841987", 
"2.145122", "1.861954", "1.762004")), .Names = c("2017-01-20 18:45:00", 
"2017-01-20 19:00:00", "2017-01-20 19:15:00", "2017-01-20 19:30:00"
), row.names = c(NA, 4L), class = "data.frame")

> eigen <- as.data.frame(t(eigen))
                          V1       V2       V3       V4
2017-01-20 18:45:00 4.461059 2.291520 2.215749 1.424662
2017-01-20 19:00:00 4.774866 2.330239 2.183941 1.277794
2017-01-20 19:15:00 4.658013 2.101630 1.935904 1.750168
2017-01-20 19:30:00 4.841987 2.145122 1.861954 1.762004

> xts_eigen <- xts::xts(eigen,order.by = as.POSIXct(rownames(eigen)))
                          V1       V2       V3       V4
2017-01-20 18:45:00 4.461059 2.291520 2.215749 1.424662
2017-01-20 19:00:00 4.774866 2.330239 2.183941 1.277794
2017-01-20 19:15:00 4.658013 2.101630 1.935904 1.750168
2017-01-20 19:30:00 4.841987 2.145122 1.861954 1.762004

> class(xts_eigen)
[1] "xts" "zoo"

Upvotes: 1

Related Questions