在地图键中的向量中查找多个字符串

时间:2017-03-15 13:21:33

标签: c++ r rcpp

我有一个键和值列表。还有另一个有一些键的向量。我想在列表中搜索这些键,并使用相应的值进行进一步的计算。

#Inside R environment
simil<-list("key"=c("A","B","C","D"),"val"=c(1.2,3.2,2.0,1.9)) 
someVec = c("B","D")

//CPP code
#include <RcppEigen>
#include <map>
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector someFunc(GenericVector simil, CharacterVector someVec){
  List sim(simil);
  std::map<std::string, double> mymap;
  std::map<std::string, double>::iterator it;
  CharacterVector keys = sim["key"];
  NumericVector vals = sim["val"];

  map[keys] = vals;

  for(int i=0;i<someVec.size();i++){
       it = mymap.find(someVec(i));

      if(it!=mymap.end()){
        // some logic here
  }

} 

我不确定map[keys] = vals是否会起作用,因为它看起来更像是R语句,但编译器不会在此行中引发任何错误。问题是在地图上使用.find()。 它抛出一个错误:没有匹配的成员函数来调用find。

如何搜索该地图中的按键?即使mymap.count(someVec(i))>0显示错误也是如此。

1 个答案:

答案 0 :(得分:3)

  

我不确定map [keys] = val是否可行,因为它看起来更像是R语句,但编译器不会在此行中引发任何错误。

我不确定为什么编译,但它绝对不会按照你的期望去做; std::map是一个C ++类,不遵守R的矢量化语义。它有few different constructors可用于用数据填充它,但在你的情况下,最简单的方法可能是循环输入并迭代填充它。

  

问题在于使用地图上的.find()。它抛出一个错误:没有匹配的成员函数来调用find。

我怀疑这与CharacterVector::operator[]返回string_proxy(或const_string_proxy,具体取决于上下文)这一事实有关。这不会隐式转换为std::string,但您可以使用Rcpp::as<std::string>执行显式转换。

一起,

#include <Rcpp.h>
#include <map>

using namespace Rcpp;

// [[Rcpp::export]]
NumericVector find_keys(List keyvals, CharacterVector morekeys) {
    std::map<std::string, double> mymap;
    std::map<std::string, double>::iterator it;

    CharacterVector keys = keyvals["key"];
    NumericVector vals = keyvals["val"];

    R_xlen_t i = 0, n = keys.size(), m = morekeys.size();
    NumericVector res(m, NA_REAL);

    // fill map
    for (; i < n; i++) {
        mymap[as<std::string>(keys[i])] = vals[i];
    }

    // look up potential keys
    for (i = 0; i < m; i++) {
        it = mymap.find(as<std::string>(morekeys[i]));
        if (it != mymap.end()) {
            res[i] = it->second;
        }
    }

    return res;
}

/*** R

keyvals <-list(
    key = c("A","B","C","D"),
    val = c(1.2,3.2,2.0,1.9)
)
morekeys = c("B", "D", "x")

find_keys(keyvals, morekeys)
# [1] 3.2 1.9  NA

*/

或者,Rcpp wrap / as专精知道如何处理开箱即用的CharacterVectorstd::vector<std::string>之间的转换“,即

// [[Rcpp::export]]
NumericVector find_keys2(List keyvals, const std::vector<std::string>& morekeys) {
    // ...

    std::vector<std::string> keys = as<std::vector<std::string> >(keyvals["key"]);
    // ...

    // fill map
    for (; i < n; i++) {
        mymap[keys[i]] = vals[i];
    }

    // look up potential keys
    for (i = 0; i < m; i++) {
        it = mymap.find(morekeys[i]);
        // ...
    }

    // ...
}