如何从索引匹配的大型 XTS 对象的每个值中减去 XTS 向量?

How to subtract an XTS-vector from each value of a large XTS-object where the index matches?

我必须在 R 中创建两个 XTS 对象,一个大对象 A 和一个具有以下结构的单列对象 B

| Object A | V1 | V2 | ...        | Object B | V1 |
---------------------------       -----------------
|2016-01-01| 1  | 6  | ...        |2016-01-01| 4  |
|2016-01-02| 2  | 7  | ...        |2016-01-02| 8  |
|2016-01-03| 3  | 8  | ...        |2016-01-03|10  |
|2016-01-04| 4  | 9  | ...        |2016-01-04|-3  |
|2016-01-05| 5  | 10 | ...        |2016-01-05| 6  |
|   ...    | .. | .. | ...        |    ...   | .. |

我想从 A 的任意列中减去 B 的值,得到:

| Object C | V1 | V2 | ...
---------------------------
|2016-01-01|-3  | 2  | ...
|2016-01-02|-6  |-1  | ...
|2016-01-03|-7  |-2  | ...
|2016-01-04| 7  |12  | ...
|2016-01-05|-1  | 4  | ...
|   ...    | .. | .. | ...

由于两个对象中的列数不匹配,简单的减法会导致错误 non-conformable arrays:

set.seed(1234)

# set up date structure
dates <- seq(as.Date("2016-01-01"), length = 5, by = "days")

# create object A and B
A <- xts(x = matrix(seq(1:10), ncol = 2), order.by = dates)
B <- xts(x = rnorm(5), order.by = dates)

A-B
Error in `-.default`(A, B) : non-conformable arrays

问题:

如何从日期匹配的大型 XTS 对象(即 A)的每个值中减去每个时间(即 B)的单个值?

如果您想在日期匹配的地方进行计算,对 xts 对象执行的最佳操作是合并它们。然后您可以使用列计算,但请确保将 NA 替换为 0。我在下面创建了一个可重现的示例,其中 xts B 与 A 相比缺少日期。

library(xts)

set.seed(1234)

# set up date structure
dates <- seq(as.Date("2016-01-01"), length = 5, by = "days")

# create object A and B
A <- xts(x = matrix(seq(1:10), ncol = 2), order.by = dates)
# B is has 1 date less than A
B <- xts(x = rnorm(4), order.by = dates[c(1:2, 4:5)]) 

# name the xts columns 
names(A) <- paste0("A", 1:ncol(A))
names(B) <- "B"

# merge data on date
x <- merge(A,B)

# set NA values in column "B" to 0
x[, "B"] <- na.fill(x[, "B"], 0)

# substract B from all A columns
for (i in names(A)) {
  x[, i] <- x[, i] - x[, "B"]
}

# drop column "B"
z <- x[, names(A)]
z
                   A1        A2
2016-01-01  1.8371717  6.837172
2016-01-02 -0.4158352  4.584165
2016-01-03  3.0000000  8.000000
2016-01-04  3.8659118  8.865912
2016-01-05  5.4906859 10.490686