I'm trying to create some sort of sapply function in Rcpp, which works as follows:
apply_cpp_fun(x, fun, ...)function takes two arguments: vector of any typex, and any cpp functionfun, plus optional arguments needed infun(eg.bool na_rm). In example I keep it simple, justxandfun.I want
funto be applied on selected elements ofx(possiblefunoutputs - bool, int, double, string). I wan't apply to be called multiple times insideapply_cpp_fun.Output of
apply_cpp_funis a vector of any type dependent onfunoutput (can be different thanx).funis called n-times, to produce each element of output vectorres.
I'm trying to achieve this by but each time output turns to be a Rcpp::List instead of Rcpp::Vector<double>.
Here is a code, I didn't write whole body of apply_cpp_fun to keep example shorter. As you can see, even if I pass <double>function, template gets Vector described as double (*)(Rcpp::Vector<14, Rcpp::PreserveStorage>).
#include <Rcpp.h>
double cpp_sum(Rcpp::NumericVector x) {
int n = x.size();
double cursum = 0;
for (int i = 0; i < n; i++) {
cursum += x(i);
}
return cursum;
}
template <int ITYPE, typename ftype>
Rcpp::Vector<Rcpp::traits::r_sexptype_traits<ftype>::rtype>
apply_cpp_fun(Rcpp::Vector<ITYPE>& x,
ftype fun) {
int n = x.size();
double xx = 5.0;
# typenames
Rcpp::Rcout << "type of xx: " << demangle(typeid(xx).name()).c_str() << std::endl;
Rcpp::Rcout << "function type: " << demangle(typeid(ftype).name()).c_str() << std::endl;
const int OTYPE = Rcpp::traits::r_sexptype_traits<ftype>::rtype;
Rcpp::Rcout << "SEXP type: " << OTYPE << std::endl;
# apply fun n-times
Rcpp::Vector<OTYPE> res(n);
for (int i = 0; i < n; i++) {
res(i) = fun(x);
}
return res; # return vector
}
// [[Rcpp::export]]
SEXP cumsum_cpp(Rcpp::NumericVector x) {
return apply_cpp_fun(x, cpp_sum);
}
Call function to see result
cumsum_cpp(as.numeric(1:2))
# type of xx: double
# function type: double (*)(Rcpp::Vector<14, Rcpp::PreserveStorage>)
# SEXP type: 19
# [[1]]
# NULL
#
# [[2]]
# NULL
How to fix this to keep applier flexible for input type and output? Thanks for any advice.
RCPP_RETURN_VECTORmacro a try. There have been several questions about it here on SO. - Ralf Stubner