[Rcpp-devel] Using data-frames as sets of rows (e.g. using R data-frames as lookup tables in C++)

Romain Francois romain at r-enthusiasts.com
Thu Sep 12 11:56:22 CEST 2013


Hello,

I've had some time now to look into this code.
If you don't care about ordering, I'd suggest you to use a hash map 
instead of a map.

We have the RCPP_UNORDERED_MAP macro that should dispatch to either 
std::unordered_map<> or std::tr1::unordered_map<> depending on your 
compiler version, etc ...

Otherwise you can use the implementation from boost. This just requires 
you to depend on the BH package. RcppExtras does that.

Did you have a look at RcppExtras ?

Romain

Le 06/09/13 16:20, Mark Clements a écrit :
> By my understanding, Rcpp is better suited to working with data-frames
> as columns rather than working with data-frames as a set of rows.
> However, occasionally it may be useful to work with the set of rows. How
> have others considered this use case?
>
> [As a motivating example based on simulations in C++, we want to pass
> data-frames from R for use as look-up tables in C++ (cf. passing
> transformed data back to R). The STL container std::map is well suited
> to this task, particularly as it provides ordered keys.
>
> In the following code, we define a template class Table1D which reads in
> a data-frame and defines the map key with the first column and the map
> value with the second column. The only sophistication here is (i) using
> std::greater as a comparison function and (ii) using Rcpp traits. Note
> that calling the function from R is only shown for demonstration.
>
> require(inline)
>
> lookup <- rcpp(signature(df="data.frame",x="numeric"),
>
>              body="
>
>    Table1D<double,double> table = Table1D<double,double>(df);
>
>    return wrap(table(as<double>(x)));
>
> ",
>
>              includes="
>
> #include <map>
>
> #include <functional>
>
> template <class Index, class Outcome>
>
> class Table1D {
>
> public:
>
>    std::map<Index,Outcome,std::greater<Index> > data;
>
>    Table1D(DataFrame df, int iIndex = 0, int iOutcome = 1) {
>
>      Vector<Rcpp::traits::r_sexptype_traits<Index>::rtype> df0 = df[iIndex];
>
>      Vector<Rcpp::traits::r_sexptype_traits<Outcome>::rtype> df1 =
> df[iOutcome];
>
>      for (size_t i=0; i<df0.size(); i++) {
>
>        data[df0[i]] = df1[i];
>
>      }
>
>    }
>
>    virtual Outcome lookup(Index index) {
>
>      return data.lower_bound(index)->second;
>
>    }
>
>    virtual Outcome operator()(Index index) {
>
>      return lookup(index);
>
>    }
>
> };
>
> ")
>
> lookup(data.frame(as.numeric(1:1000000),10.0*as.numeric(1:1000000)),
> 12345.5)
>
> See also
> https://github.com/mclements/microsimulation/blob/master/src/rcpp_table.h for
> an extension to higher dimensions.]
>
> Sincerely, Mark.


-- 
Romain Francois
Professional R Enthusiast
+33(0) 6 28 91 30 30



More information about the Rcpp-devel mailing list