Reputation: 1472
I have empty xts object and I would like to fill columns with simple calculation (predified date - xts index (date) / 365). I have been able to fill first one, problem is that I have 46 and in future more columns, so my way of doing this is not optimal. Here is what I can do. How can I fill rest of the 4 (46 in real sample) without having to merge every column as in this example.
Create empty xts
xts <- xts(order.by=index(xts))
merge(xts, col1 = (dt[1] - index(xts))/365)
col1
2010-12-31 6.512329
2011-01-03 6.504110
2011-01-04 6.501370
2011-01-05 6.498630
2011-01-06 6.495890
2011-01-07 6.493151
Final result should look like this.
col1 col2 col3 col4 col5
2010-12-31 6.512329 6.789041 7.016438 7.153425 7.287671
2011-01-03 6.504110 6.780822 7.008219 7.145205 7.279452
2011-01-04 6.501370 6.778082 7.005479 7.142466 7.276712
2011-01-05 6.498630 6.775342 7.002740 7.139726 7.273973
2011-01-06 6.495890 6.772603 7.000000 7.136986 7.271233
2011-01-07 6.493151 6.769863 6.997260 7.134247 7.268493
here is data with dt variable of 5 predetermined dates.
dput(xts)
structure(numeric(0), index = structure(c(1293753600, 1294012800,
1294099200, 1294185600, 1294272000, 1294358400), tzone = "UTC", tclass = "Date"), class = c("xts",
"zoo"), .indexCLASS = "Date", tclass = "Date", .indexTZ = "UTC", tzone = "UTC")
dput(dt)
structure(c(17351L, 17452L, 17535L, 17585L, 17634L), class = "Date")
Upvotes: 1
Views: 1116
Reputation: 176668
Rather than create a bunch of xts objects and then merge them recursively via Reduce
, you can just make one xts object directly.
mat <- sapply(dt, function(d) (d-index(x))/365)
res <- xts(mat, index(x))
colnames(res) <- paste0("col", seq(ncol(res)))
I personally find this more straight forward.
Upvotes: 1
Reputation: 3597
The key is to use Reduce
to merge large list ojects
#Read Data
#main index for first series
mainIndex = as.Date(c("2010-12-31","2011-01-03","2011-01-04","2011-01-05","2011-01-06","2011-01-07"),format="%Y-%m-%d")
referenceDates = as.Date(c("2017-07-04","2017-10-13","2018-01-04","2018-02-23","2018-04-13"),format="%Y-%m-%d")
#Create subsequent xts objects and save as list object
TS_List = lapply(1:length(referenceDates),function(x) {
tsObj =xts((referenceDates[x] - mainIndex)/365,order.by=mainIndex);
colnames(tsObj)=paste0("col",x);
return(tsObj)
})
#General syntax for Reduce : function(x, y) merge(x, y,by="column_column")
#here merge uses merge.xts and common column is index of xts objects
mergeXTSfun = function(x, y) merge(x, y)
merged_TS = Reduce(mergeXTSfun, TS_List )
merged_TS
# col1 col2 col3 col4 col5
#2010-12-31 6.512329 6.789041 7.016438 7.153425 7.287671
#2011-01-03 6.504110 6.780822 7.008219 7.145205 7.279452
#2011-01-04 6.501370 6.778082 7.005479 7.142466 7.276712
#2011-01-05 6.498630 6.775342 7.002740 7.139726 7.273973
#2011-01-06 6.495890 6.772603 7.000000 7.136986 7.271233
#2011-01-07 6.493151 6.769863 6.997260 7.134247 7.268493
DesiredOutput= read.table(text="col1 col2 col3 col4 col5
2010-12-31 6.512329 6.789041 7.016438 7.153425 7.287671
2011-01-03 6.504110 6.780822 7.008219 7.145205 7.279452
2011-01-04 6.501370 6.778082 7.005479 7.142466 7.276712
2011-01-05 6.498630 6.775342 7.002740 7.139726 7.273973
2011-01-06 6.495890 6.772603 7.000000 7.136986 7.271233
2011-01-07 6.493151 6.769863 6.997260 7.134247 7.268493",header=TRUE,stringsAsFactors=FALSE)
DesiredOutput = xts(DesiredOutput,order.by=as.Date(rownames(DesiredOutput),format="%Y-%m-%d"))
all.equal(merged_TS,DesiredOutput)
#[1] "Mean relative difference: 3.67637e-08"
Upvotes: 0