Subtracting a common xts object from all the columns of all xts objects of a list

Viewed 299

I have a list. List consists of 5 xts objects. Each object consists of 5 xts series. Each series consists of 183 observations. I want to extract one common series from all these series. The series I want to subtract is named risk_free. I have produced minimal example. In last line code produces error.

library(zoo)
library(xts)
library(PerformanceAnalytics)
managers_1 <- managers[,1:2]
manager_2 <- managers[,3:4]
list_managers <- list(managers_1,manager_2)
risk_free <- managers[,1]
## subtracting risk_free from all columns of all xts objects
list_managers_rf <- lapply(list_managers,"-",risk_free)
2 Answers

In an xts you can't just subtract something over all the columns, ohterwise you will get a message like below:

Error in `-.default`(X[[i]], ...) : non-conformable arrays

But using a for loop inside the lapply will get you there: Note that the length of the risk_free xts needs to be the same as the lengths of the xts objects in your list (183 observtions). Otherwise you need to merge first so the dates are aligned correctly and then subtract. But assuming your data is correctly aligned the code below subtracts the risk_free data from each column of each xts object in your list.

EDIT: changed lapply to become more readable by creating a separate function for the function to be used inside the lapply.

# helper function for inside the lapply. Makes things a bit more readable.
fun_substract_from_xts <- function(x) {
  # loop over all columns to substract the risk_free rate from each column
  for(i in seq_along(colnames(x))) {
    x[, i] <- x[, i] - risk_free
    }
  return(x)
}

list_managers_rf <- lapply(list_managers, fun_substract_from_xts)


tail(manager_2)
HAM3    HAM4
2006-07-31 0.0102 -0.0120
2006-08-31 0.0253 -0.0183
2006-09-30 0.0072  0.0197
2006-10-31 0.0183  0.0518
2006-11-30 0.0269  0.0373
2006-12-31 0.0110  0.0206

tail(list_managers_rf[[2]])
HAM3    HAM4
2006-07-31  0.0246  0.0024
2006-08-31  0.0092 -0.0344
2006-09-30  0.0004  0.0129
2006-10-31 -0.0244  0.0091
2006-11-30  0.0152  0.0256
2006-12-31 -0.0005  0.0091

You get this error because xts objects always have a dim attribute (i.e. they're always a matrix). This differs from zoo, where dim will be dropped if the zoo object can be a vector.

So you can do this if you remove the dim attribute from risk_free before subtracting from the xts object with multiple columns. You can do that easily with drop().

list_managers_rf <- lapply(list_managers, "-", drop(risk_free))
lapply(list_managers_rf, tail, 2)
## [[1]]
##            HAM1    HAM2
## 2006-11-30    0  0.0089
## 2006-12-31    0 -0.0177
##
## [[2]]
##               HAM3   HAM4
## 2006-11-30  0.0152 0.0256
## 2006-12-31 -0.0005 0.0091
Related