简体   繁体   中英

How to use data from two XTS to create a new XTS?

Suppose I have the following two XTS...

a <- c(1,2,3,4)
b <- c(2,4,6,8)
x <- xts(cbind(a,b),order.by = as.Date(c("2015-01-02","2015-01-05","2015-01-06","2015-01-07")))
x

and

c <- c("a","b","b","a","a","b")
d <- c(10,20,10,30,20,40)
y <- xts(cbind(c,d),order.by = as.Date(c("2015-01-02","2015-01-02","2015-01-05","2015-01-06","2015-01-07","2015-01-07")))
y

These give me...

           a b
2015-01-02 1 2
2015-01-05 2 4
2015-01-06 3 6
2015-01-07 4 8

and

           c   d   
2015-01-02 "a" "10"
2015-01-02 "b" "20"
2015-01-05 "b" "10"
2015-01-06 "a" "30"
2015-01-07 "a" "20"
2015-01-07 "b" "40"

I'd like to get the following XTS...

            a  b
2015-01-02 10 20
2015-01-05 NA 10
2015-01-06 30 NA
2015-01-07 20 40

I tried a couple of different methods such as using the functions match and coredata but wasn't able to get the exact answer. I think maybe starting with the first XTS with blank values and then filling it in with the values from the second XTS will work best. Not sure how to do that though.

The issue is that xts object is also a matrix

is.matrix(x)
#[1] TRUE

According to ?matrix

as.matrix is a generic function. The method for data frames will return a character matrix if there is only atomic columns and any non-(numeric/logical/complex) column, applying as.vector to factors and format to other non-character columns. Otherwise, the usual coercion hierarchy (logical < integer < double < complex) will be used, eg, all-logical data frames will be coerced to a logical matrix, mixed logical-integer will give a integer matrix, etc.

and matrix can hold only a single class. If there is single character element, it will change the whole dataset to character class

This looks like reshaping of y object. It would be simple to do that if you convert it into dataframe, do reshaping/pre-processing with the dataframe and then convert it back to xts object.

library(tidyverse)
library(xts)

data.frame(y) %>%
  rownames_to_column('date') %>%
  mutate(date = as.Date(date, "X%Y.%m.%d")) %>%
  pivot_wider(names_from = c, values_from = d) %>%
  #For old tidyr use spread instead of pivot_wider
  #spread(c, d) %>%
  mutate_at(vars(a, b), ~as.integer(as.character(.)))  %>%
  column_to_rownames('date') %>%
  as.xts 

#            a  b
#2015-01-02 10 20
#2015-01-05 NA 10
#2015-01-06 30 NA
#2015-01-07 20 40

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM