[Rcpp-devel] Rcpp internal versions of lapply and sapply

Douglas Bates bates at stat.wisc.edu
Wed Jun 16 14:58:49 CEST 2010


Ever since I read Phil Spector's book on S I have been a fan of
functional programming in S and R.  When Jose Pinheiro and I were
working on the nlme package there was a joke between us that you could
tell which of us wrote which parts of the code because his parts
always had an object named "aux" and my parts always had
"unlist(lapply(list(...)))".

Even within C++ I like to use the std:: algorithms like
std::transform, but, of course, there are differences between a
strongly typed language like C++ and a dynamically typed language like
S.  Templates can get around these differences to some extent but I am
still a bit of a novice regarding templates.

Currently I want to apply some functions to lists but entirely within
the C++ code (i.e. I don't want to create Rcpp Function objects and
call back to R).  For the sake of argument, consider a function that
extracts the lengths of the components of the lists.


library(Rcpp)
library(inline)
inc <- '
class length {
public:
    R_len_t operator() (RObject const& x) {return Rf_length(SEXP(x));}
};
'
code <- '
List lst(ll);
IntegerVector ans(lst.size());
std::transform(lst.begin(), lst.end(), ans.begin(), length());
return ans;
'
ltst <- cxxfunction(signature(ll = "list"), code, "Rcpp", inc)
ll <- list(a = numeric(0), b = LETTERS[6:9], c = c)
ltst(ll)
sapply(ll, length)

I would like to create a templated sapply function like

template <int RTYPE>
Vector<RTYPE> sapply(List ll, ??) {
    Vector<RTYPE> ans(ll.size());
    CharacterVector nms = ll.names();
    if (nms.size() == ll.size()) ans.names() = nms;
    std::transform(ll.begin(), ll.end(), ans.begin(), ??);
    return ans;
}

but I don't know how to specify the second argument that is a function
that returns the atomic element type of a Vector<RTYPE> (is this as
simple as Vector<RTYPE>::value_type?) and has a single argument which
probably should be an RObject (although might be an SEXP, if that was
more convenient).  Can someone (probably Romain) provide some
guidance?


More information about the Rcpp-devel mailing list