Если вы открыты для перехода с C на C ++, вы получаете дополнительный слой Rcpp бесплатно.Вот пример со страницы (все еще довольно неполного) пакета RcppExample:
#include <RcppClassic.h>
#include <cmath>
RcppExport SEXP newRcppVectorExample(SEXP vector) {
BEGIN_RCPP
Rcpp::NumericVector orig(vector); // keep a copy
Rcpp::NumericVector vec(orig.size()); // create vector same size
// we could query size via
// int n = vec.size();
// and loop over the vector, but using the STL is so much nicer
// so we use a STL transform() algorithm on each element
std::transform(orig.begin(), orig.end(), vec.begin(), ::sqrt);
return Rcpp::List::create(Rcpp::Named( "result" ) = vec,
Rcpp::Named( "original" ) = orig) ;
END_RCPP
}
Как видите, нет явного выделения памяти, освобождения, PROTECT/UNPROTECT
и т. Д., И вы получите список первого класса RВозврат
Есть еще много примеров, включенных в другие вопросы SO, такие как этот .
Редактировать: И вы действительно не сказали, чтовы бы это сделали, но в качестве простой иллюстрации приведем код на C ++ с использованием дополнений Rcpp cumsum()
и rpois()
, которые ведут себя так же, как и в R:
R> library(inline)
R>
R> fun <- cxxfunction(signature(ns="integer", lambdas="numeric"),
+ plugin="Rcpp",
+ body='
+ int n = Rcpp::as<int>(ns);
+ double lambda = Rcpp::as<double>(lambdas);
+
+ Rcpp::RNGScope tmp; // make sure RNG behaves
+
+ Rcpp::NumericVector vec = cumsum( rpois( n, lambda ) );
+
+ return vec;
+ ')
R> set.seed(42)
R> fun(3, 0.3)
[1] 1 2 2
R> fun(4, 0.4)
[1] 1 1 1 2
И в качестве доказательства вернемсяв R, если мы устанавливаем начальное число, мы можем генерировать точно такие же числа:
R> set.seed(42)
R> cumsum(rpois(3, 0.3))
[1] 1 2 2
R> cumsum(rpois(4, 0.4))
[1] 1 1 1 2
R>