Using Rcpp to access the C API of xts

Dirk Eddelbuettel — written Jan 19, 2013 — source

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.

tags: xts 

Related Articles