rxts

vectorization in xts is there a simple solution


set.seed(2)
library(xts)

x <- sample(1:5,10,replace = T)
x.xts <- xts(x, order.by = seq(as.POSIXct(Sys.time()), length = 10, by = "min"))

I have xts object x.xts and i want apply to him vectorized operation something like this

x[1] > x

[1] FALSE  TRUE FALSE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE

but when i do this i get not what i expect

x.xts[1] > x.xts

                       e1
2023-12-06 10:13:16 FALSE

I can get what i want if i convert x.xts[1] to vector

as.vector(zoo::coredata(x.xts[1])) > x.xts

                     [,1]
2023-12-06 10:13:16 FALSE
2023-12-06 10:14:16  TRUE
2023-12-06 10:15:16 FALSE
2023-12-06 10:16:16  TRUE
2023-12-06 10:17:16  TRUE
2023-12-06 10:18:16 FALSE
2023-12-06 10:19:16  TRUE
2023-12-06 10:20:16  TRUE
2023-12-06 10:21:16  TRUE
2023-12-06 10:22:16  TRUE

but this as.vector(zoo::coredata(x.xts[1])) looks bulky and there are a lot of conversions in it, I would like to reduce this if possible because I will be running the code many times.

is there a way to make the expression as.vector(zoo::coredata(x.xts[1])) > x.xts closer to x.xts[1] > x.xts


And the performance looks terrible

 f <- function(x.xts) { xx = as.vector(coredata(x.xts)); xx < xx[1L] }

> microbenchmark::microbenchmark(
+   x[1] > x , 
+   as.vector(zoo::coredata(x.xts[1])) > x.xts,
+   f(x.xts))
Unit: nanoseconds
                                       expr    min       lq     mean   median     uq     max neval
                                   x[1] > x    570   1141.0   2229.6   2281.0   2851    5702   100
 as.vector(zoo::coredata(x.xts[1])) > x.xts 526830 535382.5 565658.3 545075.5 562180  872919   100
                                   f(x.xts)  29078  30789.0 116358.9  34495.0  37916 8096878   100
> 

Solution

  • If you are looking to get an xts object back then:

    x.xts[[1L]] > x.xts
    ##                      [,1]
    ## 2023-12-06 08:24:29 FALSE
    ## 2023-12-06 08:25:29  TRUE
    ## 2023-12-06 08:26:29 FALSE
    ## 2023-12-06 08:27:29  TRUE
    ## 2023-12-06 08:28:29  TRUE
    ## 2023-12-06 08:29:29 FALSE
    ## 2023-12-06 08:30:29  TRUE
    ## 2023-12-06 08:31:29  TRUE
    ## 2023-12-06 08:32:29  TRUE
    ## 2023-12-06 08:33:29  TRUE
    

    If you want to get a plain vector back and speed matters then this is slightly faster than f in the question:

    x.xts[[1L]] > structure(x.xts, class = NULL)[, 1L]
    ## [1] FALSE  TRUE FALSE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE
    

    Update

    Fixed some copy and paste errors.