RとC++:Rの処理をそのままC++化(Standard Template Libraryでやる方法)

  • 参考は以下のようにして出るvignett記事の"Using Standard Template Library algorithms"
library(Rcpp)
library(inline)
vignette( "Rcpp-introduction" )
  • この記事の例題をなぞってみる
src <- '
Rcpp::List input(data);
Rcpp::Function f(fun);
Rcpp::List output(input.size());
std::transform(input.begin(), input.end(), output.begin(), f);
output.names() = input.names();
return output;
'
cpp_lapply <- cxxfunction(signature(data = "list", fun = "function"),src, plugin = "Rcpp")
cpp_lapply(faithful, summary)
    • signature(data = "list", fun = "function")
      • Rのリストをdataという名前で、Rの関数をfunという名前でcxxfunction()関数に入力し、RからC++化する
    • Rcpp::List input(data);
      • Cppのオブジェクト inputを作る。それはRcpp::ListとあるようにRのリストに相当するC++のオブジェクト。input(data)とあるように、入力dataを持ってinputというオブジェクトにする
    • Rcpp::Function f(fun);
      • 同様にRの関数として入力されてくる fun をCppにおけるRの関数相当のオブジェクトとして fという関数オブジェクトを作る
    • Rcpp::List output(input.size());
      • 出力はリストで返すので、それを作る。サイズは、入力したリストのlengthなので(リストの要素ごとの処理を考えているから)、input.size()を大きさとして作る
    • std::transform(input.begin(),input.end(),output.begin(),f);
      • 入力したリストinputの初めから、最後までを処理する。処理したらoutputとして作った格納用オブジェクトの初めから入れていく。その処理はfである→これによりoutputの中身ができる
    • output.names() = input.names();
      • 入力リストの項目の名前をoutputに継承する
    • return output;
      • 返す。outputはR対応オブジェクトなのでwrapしなくてよいようだ
  • 実際に実行すれば、RでやってもCppでやっても、同じ値、同じ形式
> lapply(faithful,summary)
$eruptions
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  1.600   2.163   4.000   3.488   4.454   5.100 

$waiting
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   43.0    58.0    76.0    70.9    82.0    96.0 

> cpp_lapply(faithful, summary)
$eruptions
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  1.600   2.163   4.000   3.488   4.454   5.100 

$waiting
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   43.0    58.0    76.0    70.9    82.0    96.0