Как использовать C API пакета xts в Rcpp

xts_API для C, предоставляемый пакетом xts-0.9-1, нельзя напрямую использовать в C++.

Например, если написать

#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
}

Будет следующая ошибка времени компиляции:

  • error: expected identifier before ‘)’ token
  • error: ‘install’ was not declared in this scope
  • error: ‘getAttrib’ was not declared in this scope
  • error: ‘setAttrib’ was not declared in this scope
  • error: ‘xts_IndexvalueSymbol’ was not declared in this scope

Как вызвать xts_API для C?


person wush978    schedule 11.01.2013    source источник


Ответы (2)


Какая у вас версия хтс? Для меня работает следующее:

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")

Что я могу запустить:

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> 

Настройка флага включения должна быть обобщена, но мы могли бы над этим поработать, если бы вы перешли к списку rcpp-devel.

Редактировать: я начал экспериментировать с дополнительным пакетом, который взаимодействует с (в настоящее время несколько более ограниченным) API xts; см. в репозитории Rcpp SVN на R-Forge. Я также добавил новый ответ в галерею Rcpp, который показывает, как получить доступ к xts компоненты из кода C++. Есть гораздо лучшие способы доступа к атрибутам (используя Rcpp API), чем здесь (на основе C API R).

Редактировать 2: теперь есть новый пакет RcppXts, который помогает с этим.

person Dirk Eddelbuettel    schedule 11.01.2013

Следующее руководство предназначено для разработки пакета R.

Ключевым моментом является добавление необходимой встроенной функции и макроса, чтобы сделать xts_API совместимым с 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
}

Приведенный выше код должен работать практически для всех xts_API, кроме SET_xtsIndexClass.

Компилятор по-прежнему будет сообщать error: ‘xts_IndexvalueSymbol’ was not declared in this scope.

Вот мое решение, но я не знаю, правильное оно или нет.

Откройте <xts package root>/include/xts.h и измените

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

to

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

Я предполагаю, что это опечатка.

person wush978    schedule 11.01.2013