June 24, 2016

(This article was first published on Rcpp Gallery, and kindly contributed to R-bloggers)


A while back I saw a post on StackOverflow where the user was trying to use Rcpp::sugar::sum() on an RcppParallel::RVector.
Obviously this doesn’t work and it raised the question “Why doesn’t something more generic exist to provide functions with R
semantics that can be used on arbitrary data structures?” As a result, I set out to create a set of such functions following
the pattern of std::algorithm in Rcpp::algorithm.


Currently Rcpp::algorithm contains only a few simple functions, but if they are found to be useful, more will be added.
Examples of using the currently implemented iterator-based functions are below.

sum, sum_nona, prod, and prod_nona


using namespace Rcpp;

// [[Rcpp::export]]
double sum_of_matrix_row(NumericMatrix m, int row) {
    NumericMatrix::Row r = m.row(row);

    return algorithm::sum(r.begin(), r.end());

min, max, and mean


using namespace Rcpp;

// [[Rcpp::export]]
double mean_of_matrix_row(NumericMatrix m, int row) {
    NumericMatrix::Row r = m.row(row);

    return algorithm::mean(r.begin(), r.end());

log, exp, and sqrt


using namespace Rcpp;

// [[Rcpp::export]]
NumericVector log_of_matrix_row(NumericMatrix m, int row) {
    NumericMatrix::Row r = m.row(row);

    NumericVector retval(m.cols());
    algorithm::log(r.begin(), r.end(), retval.begin());

    return retval;

Additional Benefits

Through the coding of these simple “algorithms”, a few needs arose.

First, the ability to deduce the appropriate C numeric type
given an Rcpp iterator was necessary. This gave birth to the Rcpp::algorithm::helpers::decays_to_ctype and
Rcpp::algorithm::helpers::ctype type traits. Given a type, these allow you to determine whether it can be cast to a C numeric
type and which type that would be.

Second, the need arose for more information about R types. This gave birth to the Rcpp::algorithm::helpers::rtype traits. These
are defined as follows:

template< typename T >
struct rtype_helper {};

struct rtype_helper< double > {
    typedef double type;
    static inline double NA() { return NA_REAL; }
    static inline RCPP_CONSTEXPR double ZERO() { return 0.0; }
    static inline RCPP_CONSTEXPR double ONE() { return 1.0; }

struct rtype_helper< int > {
    typedef int type;
    static inline int NA() { return NA_INTEGER; }
    static inline RCPP_CONSTEXPR int ZERO() { return 0; }
    static inline RCPP_CONSTEXPR int ONE() { return 1; }

template< typename T >
struct rtype {
    typedef typename rtype_helper< typename ctype< T >::type >::type type;
    typedef rtype_helper< typename ctype< T >::type > helper_type;
    static RCPP_CONSTEXPR int RTYPE = helper_type::RTYPE;
    static inline T NA() { return helper_type::NA(); }
    static inline RCPP_CONSTEXPR T ZERO() { return helper_type::ZERO(); }
    static inline RCPP_CONSTEXPR T ONE() { return helper_type::ONE(); }

These additional benefits may actually prove more useful than the algorithms themselves. Only time will tell.

Wrapping Up

There are now some simple iterator-based algorithms that can be used with any structure that supports iterators. They apply the same semantics
as the analogous Rcpp::sugar functions but give us more flexibility in their usage. If you find these to be useful, feel free to request more.

To leave a comment for the author, please follow the link and comment on their blog: Rcpp Gallery.

R-bloggers.com offers daily e-mail updates about R news and tutorials on topics such as: Data science, Big Data, R jobs, visualization (ggplot2, Boxplots, maps, animation), programming (RStudio, Sweave, LaTeX, SQL, Eclipse, git, hadoop, Web Scraping) statistics (regression, PCA, time series, trading) and more...

If you got this far, why not subscribe for updates from the site? Choose your flavor: e-mail, twitter, RSS, or facebook...

Comments are closed.

Search R-bloggers


Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)