Bart
Bart

Reputation: 759

converting an std::map to an Rcpp::List?

What would be the correct way of returning an std::map< std::string, double > as an Rcpp::List object? The default wrap() method results in a named vector being returned to R.

Upvotes: 1

Views: 1197

Answers (1)

nrussell
nrussell

Reputation: 18612

In the future, include what you have tried in your question. It will be much more beneficial to you when others are able to explain why what you were trying was not working. Also, R lists (and Rcpp::Lists) are much more versatile than std::maps, so I'm not quite sure how you are trying to store the map's data in the list. Presumably the map's keys correspond to the list's names; and the values to the list's values? Here's one way to do this:

#include <Rcpp.h>

// [[Rcpp::export]]
Rcpp::List map_to_list(Rcpp::CharacterVector cv, Rcpp::NumericVector nv) {
  std::map<std::string, double> my_map;

  for (R_xlen_t i = 0; i < cv.size(); i++) {
    my_map.insert(std::make_pair(Rcpp::as<std::string>(cv[i]), nv[i]));
  }

  Rcpp::List my_list(my_map.size());
  Rcpp::CharacterVector list_names(my_map.size());
  std::map<std::string, double>::const_iterator lhs = my_map.begin(), rhs = my_map.end();

  for (R_xlen_t i = 0; lhs != rhs; ++lhs, i++) {
    my_list[i] = lhs->second;
    list_names[i] = lhs->first;
  }

  my_list.attr("names") = list_names;
  return my_list;
}

/*** R

.names <- letters[1:20]
.values <- rnorm(20)

(res <- map_to_list(.names, .values))
#$a
#[1] -0.8596328

#$b
#[1] 0.1300086

#$c
#[1] -0.1439214

#$d
#[1] -1.017546

## etc...

*/ 

Starting with Rcpp::List my_list(my_map.size());, I'm initializing the return object to the size of the std::map; and likewise for an Rcpp::CharacterVector which will be used as the return object's names. Using a map iterator and an auxiliary index variable, the map's values (iterator->second) are assigned to the corresponding position in the list, whereas its keys (iterator->first) are assigned to the temporary name vector. Finally, assign this to the resulting list, and return it.

Upvotes: 7

Related Questions