Edited at

Rcppの4様態

More than 5 years have passed since last update.

某ドキュメントのほぼまんまなんだけど,Rcppでコードを生成する場合,大まかに四つの方法に分けられるかと


ソースに書いてコンパイルし,Rでロードする

C/C++のまんまの関数コードだけのファイル


fibonacci00.cpp


int fibonacci(const int x){
if(x==0)return(0);
if(x==1)return(1);
return fibonacci(x-1)+fibonacci(x-2);
}

これをRcpp/Rで利用するためラッパー関数コードだけのファイル


fibonacci0.cpp

#include <Rcpp.h>

extern int fibonacci(const int x);

extern "C" SEXP fibWrapper ( SEXP xs ) {
int x = Rcpp::as<int>(xs);
int fib = fibonacci (x);
return Rcpp::wrap(fib);
}


んでもって二つをR CMD でコンパイル

$ R CMD SHLIB fibonacci0.cpp fibonacci00.cpp 

g++ -shared -L/usr/local/lib -o fibonacci0.so fibonacci0.o fibonacci00.o -L/R/libs/Rcpp/lib -lRcpp -Wl,-rpath,/R/libs/Rcpp/lib -L/usr/local/lib/R/lib -lR

Rでロードして利用

> dyn.load ("fibonacci0.so")

> .Call ("fibWrapper", 10)
[1] 55
> dyn.unload ("fibonacci0.so")



inlineパッケージを使ってコードもRのスクリプトに書き込む


R.R

> library (inline)

> library (Rcpp)
> incltxt <- '
+ int fibonacci(const int x){
+ if(x==0)return(0);
+ if(x==1)return(1);
+ return fibonacci(x-1)+fibonacci(x-2);
+ }'

> fibRcpp <- cxxfunction(signature(xs = 'int'),
+ plugin = 'Rcpp',
+ incl = incltxt,
+ body = '
+ int x = Rcpp::as<int>(xs);
+ return Rcpp::wrap(fibonacci(x));
+ '
)
> fibRcpp(10)
[1] 55




attriburesを使う.ラッパーを定義する必要なし


fibonacci.cpp

#include<Rcpp.h>

using namespace Rcpp;

// [[Rcpp::export]]
int fibonacci(const int x){
if(x < 2)
return x;
else
return(fibonacci(x - 1))+fibonacci(x-2);
}


sourceCpp()でコンパイルする.ラッパーを定義する必要なし

> sourceCpp ("fibonacci.cpp")

> fibonacci(10)
[1] 55


まだある


cppFuncitonを使う.これまたRのスクリプトにコードを書く

> txt <- '

+ int fibonacci (const int x) {
+ if ( x < 2) return ( x ) ;
+ return ( fibonacci ( x - 1) ) + fibonacci ( x - 2) ;
+ }'
> fib <- cppFunction(txt)
> fib (10)
[1] 55

Rcppは進化が激しいので,追って整理するのが大変...