Rから受け取ったオブジェクトを C++ でデータフレームに返すコードだけど,
Rdefines.h の場合だと以下のようになるけど,Rcpp だと,その下のようにまとまる.Namespace が厄介だけど,コードは読みやすくなって,確かに吉.
Rでの伝統的なインターフェイス (R.h) を使う
(ちょっと余計な手順があるかもしれないけど)
#include <R.h> #include <Rinternals.h> extern int utf8locale; SEXP dfmake(SEXP x, SEXP y, SEXP z){ int pc=0; SEXP df, varlabels, tmp, row_names;//DataTypes; const char* xx = CHAR(STRING_ELT(x, 0)); const char* yy = CHAR(STRING_ELT(y, 0)); const char* zz = CHAR(STRING_ELT(z, 0)); PROTECT(df = allocVector(VECSXP, 2));// ベクトル要素を二つ持つ data.frame pc++; // df内第一ベクトルは三つの要素からなる 文字ベクトル SET_VECTOR_ELT(df, 0, allocVector(STRSXP, 3)); SET_STRING_ELT(VECTOR_ELT(df,0), 0, mkCharCE(xx, (utf8locale)?CE_UTF8:CE_NATIVE)); SET_STRING_ELT(VECTOR_ELT(df,0), 1, mkCharCE(yy, (utf8locale)?CE_UTF8:CE_NATIVE)); SET_STRING_ELT(VECTOR_ELT(df,0), 2, mkCharCE(zz, (utf8locale)?CE_UTF8:CE_NATIVE)); // df内第二ベクトルは三つの要素からなる 整数ベクトル SET_VECTOR_ELT(df, 1, allocVector(INTSXP, 3)); INTEGER(VECTOR_ELT(df,1))[0] = 10; INTEGER(VECTOR_ELT(df,1))[1] = 20; INTEGER(VECTOR_ELT(df,1))[2] = 30; PROTECT(varlabels = allocVector(STRSXP, 2));//df 内ベクトルの名前を用意 pc++; SET_STRING_ELT(varlabels, 0, mkCharCE("Name", (utf8locale)?CE_UTF8:CE_NATIVE)); SET_STRING_ELT(varlabels, 1, mkCharCE("Age", (utf8locale)?CE_UTF8:CE_NATIVE)); PROTECT(tmp = mkString("data.frame")); pc++; PROTECT(row_names = allocVector(STRSXP, 3)); pc++; SET_STRING_ELT(row_names, 0, mkCharCE("1", (utf8locale)?CE_UTF8:CE_NATIVE)); SET_STRING_ELT(row_names, 1, mkCharCE("2", (utf8locale)?CE_UTF8:CE_NATIVE)); SET_STRING_ELT(row_names, 2, mkCharCE("3", (utf8locale)?CE_UTF8:CE_NATIVE)); setAttrib(df, R_ClassSymbol, tmp); setAttrib(df, R_NamesSymbol, varlabels); setAttrib(df, R_RowNamesSymbol, row_names); UNPROTECT(pc); return(df); }
Rcpp.h を使ってデータフレームを返す
#include "Rcpp.h" using namespace Rcpp; RcppExport SEXP dfMake2 (SEXP x, SEXP y, SEXP z){ CharacterVector cv = CharacterVector::create(as<std::string>(x), as<std::string>(y), as<std::string>(z)); IntegerVector nv = IntegerVector::create(10,20,30); return DataFrame::create(Named("Name") = cv, Named ("Age") = nv, Named("stringsAsFactors") = false ); }