statquant
statquant

Reputation: 14390

How to pass a map<double,T> from C++ to R with Rcpp

looking at Rcpp authors's paper, I see on page 6 and 7 that map<T> and map<string,T> can be passed from C++ to R as long as T is "wrappable". I have a map<double,vector<double> > that I wouls like to pass to R. I was hoping the double keys could be casted to string in the wrap or something but I understand it is not magic.

Do you have a suggestion that would allow me to output such map without copying the whole map to another map<string, vector<double>> (this might well be a C++ question after all)?

Find bellow an example of a map<double,string> for reproductible example.

cCode <- '
    map<double,string> myMap;
    myMap[10.01] = "A1";
    myMap[14.62] = "B1";
    myMap[16.33] = "C1";

    return wrap(myMap); //this failed
';
mapRet <- cxxfunction(signature(), includes='using namespace std;', plugin="Rcpp", body=cCode)

PS: I know about rcpp-devel list but my stuff looks like noob question so I do not want to spam.

Upvotes: 2

Views: 1371

Answers (1)

Dirk is no longer here
Dirk is no longer here

Reputation: 368439

You can't even test for equality on a double (see the R FAQ 7.31) so I don't see how you could index a map or hash on a double.

In general, "automatic" conversion happens for implicit forms of as<>() and wrap() where C++ and R have corresponding types on both sides (ie vectors, lists, ... of double, int, ...) and explicit where you create your own converters. You can still do that for your containers, it just cannot be automatic as we do not deliver magic wands.

Edit: Ok, just noodled with this on the train. You can build it both ways in C++, but you can only (automagically) have it mapped back to R as there is only on possible representation: doubles with string labels. Witness:

#include <Rcpp.h>

// [[Rcpp::export]]
std::map<std::string, double> bar() {
  std::map<std::string, double> s;
  s["quick"]  = 3.14;
  s["brown"] = 2.22;
  s["fox"]    = 1.11;
  return s;
}

// [[Rcpp::export]]
std::map<double, std::string> foo() {
  std::map<double, std::string> s;
  s[3.14] = "quick";
  s[2.22] = "brown";
  s[1.11] = "fox";
  return s;
}

and both functions compile, but only the first is accessible from R / exportable. It even works:

R> Rcpp::sourceCpp('/tmp/maptest.cpp')
R> bar()
brown   fox quick 
 2.22  1.11  3.14 
R>

Upvotes: 4

Related Questions