Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why apply() returns a transposed xts matrix?

Tags:

r

apply

xts

I want to run a function on all periods of an xts matrix. apply() is very fast but the returned matrix has transposed dimensions compared to the original object:

> dim(myxts)
[1] 7429   48
> myxts.2 = apply(myxts, 1 , function(x) { return(x) })
> dim(myxts.2)
[1]   48 7429
> str(myxts)
An 'xts' object from 2012-01-03 09:30:00 to 2012-01-30 16:00:00 containing:
  Data: num [1:7429, 1:48] 4092500 4098500 4091500 4090300 4095200 ...
 - attr(*, "dimnames")=List of 2
  ..$ : NULL
  ..$ : chr [1:48] "Open" "High" "Low" "Close" ...
  Indexed by objects of class: [POSIXlt,POSIXt] TZ: 
  xts Attributes:  
 NULL
> str(myxts.2)
 num [1:48, 1:7429] 4092500 4098500 4091100 4098500 0 ...
 - attr(*, "dimnames")=List of 2
  ..$ : chr [1:48] "Open" "High" "Low" "Close" ...
  ..$ : chr [1:7429] "2012-01-03 09:30:00" "2012-01-03 09:31:00" "2012-01-03 09:32:00" "2012-01-03 09:33:00" ...
> nrow(myxts)
[1] 7429
> head(myxts)
                       Open    High     Low   Close
2012-01-03 09:30:00 4092500 4098500 4091100 4098500
2012-01-03 09:31:00 4098500 4099500 4092000 4092000
2012-01-03 09:32:00 4091500 4095000 4090000 4090200 
2012-01-03 09:33:00 4090300 4096400 4090300 4094900
2012-01-03 09:34:00 4095200 4100000 4095200 4099900
2012-01-03 09:35:00 4100000 4100000 4096500 4097500 

How can I preserve myxts dimensions?

like image 608
Robert Kubrick Avatar asked Mar 01 '12 17:03

Robert Kubrick


1 Answers

That's what apply is documented to do. From ?apply:

Value:

 If each call to ‘FUN’ returns a vector of length ‘n’, then ‘apply’
 returns an array of dimension ‘c(n, dim(X)[MARGIN])’ if ‘n > 1’.

In your case, 'n'=48 (because you're looping over rows), so apply will return an array of dimension c(48, 7429).

Also note that myxts.2 is not an xts object. It's a regular array. You have a couple options:

  1. transpose the results of apply before re-creating your xts object:

    data(sample_matrix)
    myxts <- as.xts(sample_matrix)
    dim(myxts)    # [1] 180   4
    myxts.2 <- apply(myxts, 1 , identity)
    dim(myxts.2)  # [1]   4 180
    myxts.2 <- xts(t(apply(myxts, 1 , identity)), index(myxts))
    dim(myxts.2)  # [1] 180   4
    
  2. Vectorize your function so it operates on all the rows of an xts object and returns an xts object. Then you don't have to worry about apply at all.

Finally, please start providing reproducible examples. It's not that hard and it makes it a lot easier for people to help. I've provided an example above and I hope you can use it in your following questions.

like image 78
Joshua Ulrich Avatar answered Sep 28 '22 07:09

Joshua Ulrich