从列表的所有 xts 对象的所有列中减去一个公共 xts 对象

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

我有一个清单。列表由 5 个 xts 对象组成。每个对象由 5 个 xts 系列组成。每个系列包含 183 个观察值。我想从所有这些系列中提取一个公共系列。我要减去的系列名为 risk_free。我制作了最小的例子。最后一行代码产生错误。

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)

在 xts 中,您不能只在所有列上减去某些内容,否则您会收到如下消息:

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

但是在 lapply 中使用 for 循环会让你到达那里:请注意 risk_free xts 的长度需要与列表中 xts 对象的长度相同( 183 条意见)。否则,您需要先合并,以便日期正确对齐,然后再减去。但是假设您的数据正确对齐,下面的代码会从列表中每个 xts 对象的每一列中减去 risk_free 数据。

编辑:通过为要在 lapply.

中使用的函数创建一个单独的函数,更改 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

您收到此错误是因为 xts 对象始终具有 dim 属性(即它们始终是矩阵)。这与动物园不同,如果动物园对象可以是向量,则 dim 将被删除。

因此,如果在从具有多列的 xts 对象中减去之前从 risk_free 中删除 dim 属性,则可以执行此操作。您可以使用 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