Reputation: 220
I have to two XTS-objects in R, one large object A
and a single column object B
with the following structures:
| 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 |
| ... | .. | .. | ... | ... | .. |
I would like to subtract the values of B
from any column of A
, resulting in:
| 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 | ...
| ... | .. | .. | ...
Since the number of columns in both objects do not match, a simple subtraction results in the error 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
Question:
How to subtract a single value for each time (i.e. B
) from each value of a large XTS-Object (i.e. A
) where the date matches?
Upvotes: 2
Views: 453
Reputation: 23608
If you want to do calculations where the dates match, the best thing to do with xts objects is to merge them. Then you can use columns calculations, but make sure to replace the NA's with 0. I created a reproducible example below, where xts B has a missing date compared to 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
Upvotes: 1