Using Rcpp to access the C API of xts

[This article was first published on Rcpp Gallery, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
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 

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 

// next two lines connect us to the xts API
#include 
// [[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.

To leave a comment for the author, please follow the link and comment on their blog: Rcpp Gallery.

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.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)