wush978
wush978

Reputation: 3174

How to use C api of xts package in Rcpp

The xts_API for C provided by xts-0.9-1 package cannot be directly used in C++.

For example, if one write

#include <Rcpp.h>
extern "C" {
#include <xts.h>
}

using namespace Rcpp;

RcppExport SEXP get_xts_index(SEXP x, SEXP value) {
  BEGIN_RCPP

  return SET_xtsIndexClass(x, value);

  END_RCPP
}

There will be following compiler time error:

How to invoke xts_API for C?

Upvotes: 5

Views: 713

Answers (2)

Dirk is no longer here
Dirk is no longer here

Reputation: 368261

What version of xts do you have? The following works for me:

library(xts)
library(inline)

inc <- '
extern "C" {
#define class xts_class
#include <xts.h>
#undef class
}


inline SEXP install(const char* x) {
  return Rf_install(x);
}

inline SEXP getAttrib(SEXP a, SEXP b) {
  return Rf_getAttrib(a, b);
}


inline SEXP setAttrib(SEXP a, SEXP b, SEXP c) {
  return Rf_setAttrib(a, b, c);
}

#include <Rcpp.h>
'

src <- '
   return GET_xtsIndexClass(x);
'

Sys.setenv("PKG_CXXFLAGS"="-I/usr/local/lib/R/site-library/xts/include")
xtsfun <- cxxfunction(signature(x="ANY"), body=src, inc=inc, plugin="Rcpp")

Which I can run:

R> xtsfun <- cxxfunction(signature(x="ANY"), body=src, inc=inc, plugin="Rcpp")
R> foo <- xts(1:5, order.by=Sys.time()+0:4)
R> xtsfun(foo)
[1] "POSIXct" "POSIXt" 
R> 

The include flag setting needs to be generalized, but that is something we could work on if you came over to the rcpp-devel list.

Edit: I started to experiment with an add-on package which interfaces with the (currently somewhat more limited) API of xts; see in the Rcpp SVN repo on R-Forge. I also added a new answer to the Rcpp Gallery which show how to access xts components from C++ code. There are much better ways to get to attributes (using the Rcpp API) then used here (based on R's C API).

Edit 2: There is now a new package RcppXts that helps with this.

Upvotes: 5

wush978
wush978

Reputation: 3174

The following guide is for R package development.

The key is to add necessary inline function and macro to make xts_API compatible with C++.

extern "C" {
#define class xts_class
#include <xts.h>
#undef class
}


inline SEXP install(const char* x) {
  return Rf_install(x);
}

inline SEXP getAttrib(SEXP a, SEXP b) {
  return Rf_getAttrib(a, b);
}


inline SEXP setAttrib(SEXP a, SEXP b, SEXP c) {
  return Rf_setAttrib(a, b, c);
}

#include <Rcpp.h>

RcppExport SEXP get_xts_index(SEXP x, SEXP value) {
  BEGIN_RCPP

  return GET_xtsIndexClass(x);

  END_RCPP
}

The above code should work for almost all xts_API except SET_xtsIndexClass.

The compiler will still report error: ‘xts_IndexvalueSymbol’ was not declared in this scope.

Here is my solution but I don't know if it is right or not.

Open <xts package root>/include/xts.h and change

#define  SET_xtsIndexClass(x,value)     setAttrib(x, xts_IndexvalueSymbol, value)

to

#define  SET_xtsIndexClass(x,value)     setAttrib(x, xts_IndexClassSymbol, value)

I guess that it is a typo.

Upvotes: 1

Related Questions