Custom as and wrap converters example

January 20, 2013
By

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

The RcppBDT package interfaces Boost.Date_Time with R. Both systems have their own date representations—and this provides a nice example of custom as<>() and wrap() converters. Here, we show a simplified example.

We start with the forward declarations:

#include <RcppCommon.h>

#include <boost/date_time/gregorian/gregorian_types.hpp> 	// Gregorian calendar types, no I/O

namespace Rcpp {

    // 'date' class boost::gregorian::date
    //
    // non-intrusive extension via template specialisation
    template <> boost::gregorian::date as(SEXP dt);
    //
    // non-intrusive extension via template specialisation
    template <> SEXP wrap(const boost::gregorian::date &d);
}

Given these forward declarations, we can now define the converters.

For as(), we first instantiate a date object and use it to obtain the year, month and day fields to create a boost::gregorian date.

Similarly, for the inverse operation, we construct an Rcpp date from these components.

#include <Rcpp.h>

// define template specialisations for as and wrap
namespace Rcpp {
    template <> boost::gregorian::date as(SEXP dtsexp) {
        Rcpp::Date dt(dtsexp);
        return boost::gregorian::date(dt.getYear(), dt.getMonth(), dt.getDay());
    }

    template <> SEXP wrap(const boost::gregorian::date &d) {
        boost::gregorian::date::ymd_type ymd = d.year_month_day();     // convert to y/m/d struct
        return Rcpp::wrap( Rcpp::Date( ymd.year, ymd.month, ymd.day ));
    }
}

With these converters, we can now use a Boost Date_Time function. As a simple example, we use the compute the first given weekday after a date function.

// [[Rcpp::export]]
Rcpp::Date getFirstDayOfWeekAfter(int weekday, SEXP date) {
    boost::gregorian::first_day_of_the_week_after fdaf(weekday);
    boost::gregorian::date dt = Rcpp::as<boost::gregorian::date>(date);
    return Rcpp::wrap( fdaf.get_date(dt) );
}

We can use this to, say, find the first Monday after New Year in 2020:

getFirstDayOfWeekAfter(1, as.Date("2020-01-01"))
[1] "2020-01-06"

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

R-bloggers.com offers daily e-mail updates about R news and tutorials on topics such as: 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.