skoestlmeier
skoestlmeier

Reputation: 220

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

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

Answers (1)

phiver
phiver

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

Related Questions