1
votes

I have the following original code

prices <- c(11.44, 12.64, 13.12, 11.98, 19.34)
dates <- seq(as.Date("2011-07-01"), by=1, len=length(prices))
ts.prices <- xts(prices, order.by =dates)

covariance <- function(x, convert.to.vec=FALSE) {
  if (convert.to.vec == TRUE)
    x <- as.vector(x)

  xbar <- mean(x)
  N <- length(x)
  i <- 1
  covariance <- sum((x[1:(N-i)]-xbar)*(x[(1+i):N]-xbar))

  return(covariance)
}

The output of the covariance function will be different whether convert.to.vec is TRUE or FALSE:

> covariance(ts.prices, TRUE)
[1] -5.679376
> covariance(ts.prices, FALSE)
[1] 4.445328

After adding some variables and prints to make debugging the code easier:

covariance <- function(x, convert.to.vec=FALSE) {
  if (convert.to.vec == TRUE)
    x <- as.vector(x)
  xbar <- mean(x)
  N <- length(x)
  i <- 1

  term.1 <- x[1:(N-i)]-xbar
  term.2 <- x[(1+i):N]-xbar
  term.3 <- term.1*term.2
  covariance <- sum(term.3)
  print(term.1)
  print(term.2)
  print(term.3)
  print(covariance)
  #covariance <- sum((x[1:(N-i)]-xbar)*(x[(1+i):N]-xbar))
  #return(covariance)
 }

We can see that the value of term.3 is the one that is different:

> covariance(ts.prices, TRUE)
[1] -2.264 -1.064 -0.584 -1.724
[1] -1.064 -0.584 -1.724  5.636
[1]  2.408896  0.621376  1.006816 -9.716464
[1] -5.679376
> covariance(ts.prices, FALSE)
             [,1]
2011-07-01 -2.264
2011-07-02 -1.064
2011-07-03 -0.584
2011-07-04 -1.724
             [,1]
2011-07-02 -1.064
2011-07-03 -0.584
2011-07-04 -1.724
2011-07-05  5.636
                 e1
2011-07-02 1.132096
2011-07-03 0.341056
2011-07-04 2.972176
[1] 4.445328

When convert.to.vec is TRUE, term.3 contains 4 floating numbers, whereas it contains 3 floating numbers when convert.to.vec is FALSE. So I'm assuming that the different value is caused by the multiplication of two xts objects vs. two vector'ed xts objects. Why is this the case ?

DC

1
I believe Joshua's answer here is relevant. Ops.xts seems to use merge.xts to account for overlapping "index"es before any arithmetic operation takes place. - alexis_laz
@alexis_laz Thanks for the link. Can you post it as an answer so that I can accept it ? - DivineComedy
I'm not fully aware of xts documentation, so not sure how to compose a formal answer. If the linked QA is sufficient, I guess, it could be marked as a duplicate - alexis_laz

1 Answers

1
votes

Based on @alexis_laz's comment, when an Ops.xts function such as + or * is used on two xts objects, both objects are first merged with each other if their indexes are not identical, as we can see in xts`s sourcecode:

if( NROW(e1)==NROW(e2) && identical(.index(e1),.index(e2)) ) {
  .Class <- "matrix"
  NextMethod(.Generic)
} else {
  tmp.e1 <- merge.xts(e1, e2, all=FALSE, retclass=FALSE, retside=c(TRUE,FALSE))
  e2 <- merge.xts(e2, e1, all=FALSE, retclass=FALSE, retside=c(TRUE,FALSE))
  e1 <- tmp.e1
  .Class <- "matrix"
  NextMethod(.Generic)
}

In my example, term.1 and term.2 have not identical indexes, thus both objects are merged, and the Ops function * returns an object containing overlapping dates only. One solution is to call coredata on the original x object.