Using Rcpp to access the C API of xts
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
The xts package by Jeff Ryan and Josh Ulrich is an immensely powerful tool that is widely used for timeseries work with R. Recently, the question about how to use it from Rcpp came up on StackOverflow and in a thread on the rcpp-devel list.
In fact, xts has had an exposed API since 2008, but it wasn’t used and as I found out also not quite for two key functions. Jeff kindly gave me SVN access, and I updated init.c
(to export) and a new xtsAPI.h
header (access these).
This short post will show how to access this functionality using the new RcppXts package.
We start by repeating the (updated) createXts()
function from the previous post on xts and Rcpp. This helper function (or an improved version of it) should probably go into RcppXts.
#include <Rcpp.h> using namespace Rcpp; // [[Rcpp::export]] Rcpp::NumericVector createXts(int sv, int ev) { IntegerVector ind = seq(sv, ev); // values NumericVector dv(ind); // date(time)s are real values dv = dv * 86400; // scaled to days dv.attr("tzone") = "UTC"; // the index has attributes dv.attr("tclass") = "Date"; NumericVector xv(ind); // data her same index xv.attr("dim") = IntegerVector::create(ev-sv+1,1); xv.attr("index") = dv; CharacterVector klass = CharacterVector::create("xts", "zoo"); xv.attr("class") = klass; xv.attr(".indexCLASS") = "Date"; xv.attr("tclass") = "Date"; xv.attr(".indexTZ") = "UTC"; xv.attr("tzone") = "UTC"; return xv; } createXts(2,5) [,1] 1970-01-03 2 1970-01-04 3 1970-01-05 4 1970-01-06 5
Next, we show how to use this. Rcpp attributes will find the xts header file if use a depends()
attribute, and as the functions we access are registered with the surrounding R process, no linking is needed.
#include <Rcpp.h> // next two lines connect us to the xts API #include <xtsAPI.h> // [[Rcpp::depends(xts)]] using namespace Rcpp; // [[Rcpp::export]] Rcpp::NumericVector rbindXts(NumericMatrix ma, NumericMatrix mb, bool dup=true) { NumericMatrix mc = xtsRbind(ma, mb, wrap(dup)); return mc; }
Thanks to this new (tree-line !!) function, we can combine xts
object at the source level.
x1 <- createXts(2,5) x2 <- createXts(4,9) rbindXts(x1, x2) [,1] 1970-01-03 2 1970-01-04 3 1970-01-05 4 1970-01-06 5 1970-01-07 6 1970-01-08 7 1970-01-09 8 1970-01-10 9 rbindXts(x1, x2, FALSE) [,1] 1970-01-03 2 1970-01-04 3 1970-01-05 4 1970-01-05 4 1970-01-06 5 1970-01-06 5 1970-01-07 6 1970-01-08 7 1970-01-09 8 1970-01-10 9
Notice the difference between the results driven by the third argument about removal of duplicates which has a default value of TRUE
.
While this example was obviously very simple, we can see the power and promise of this. It derives from being able to work on large numbers of xts
objects directly at the C++ level without having to call back to R. So even though xts is about as efficient as it gets, we should be able to make nice gains (for simple enough tasks) by doing them at the C++ level.
R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.