将单个Rcpp :: IntegerVector元素转换为字符

时间:2018-02-27 18:32:10

标签: r rcpp

我必须将Rcpp :: IntegerVector的各个元素转换为它们的字符串形式,这样我就可以为它们添加另一个字符串。我的代码如下所示:

   #include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
Rcpp::String int_to_char_single_fun(int x){
  // Obtain environment containing function
  Rcpp::Environment base("package:base");

  // Make function callable from C++
  Rcpp::Function int_to_string = base["as.character"];

  // Call the function and receive its list output
  Rcpp::String res = int_to_string(Rcpp::_["x"] = x); // example of original param

  // Return test object in list structure
  return (res);
}

//[[Rcpp::export]]
Rcpp::CharacterVector add_chars_to_int(Rcpp::IntegerVector x){
  int n = x.size();
  Rcpp::CharacterVector BASEL_SEG(n);
  for(int i = 0; i < n; i++){
  BASEL_SEG[i] = "B0" +  int_to_char_single_fun(x[i]);
  }
  return BASEL_SEG;
}

/*** R
int_vec <- as.integer(c(1,2,3,4,5))
BASEL_SEG_char <- add_chars_to_int(int_vec)
*/

我收到以下错误:

no match for 'operator+'(operand types are 'const char[3]' and 'Rcpp::String')

我无法导入任何像Boost这样的C ++库来执行此操作,并且只能使用Rcpp功能来执行此操作。如何在Rcpp中将字符串添加到整数?

2 个答案:

答案 0 :(得分:4)

当我们在Rcpp Gallery中涵盖Boost时,我们基本上在example for lexical_cast覆盖了这一点(尽管那个是另一种方式)。因此,快速重写它会产生这样的结果:

代码

// We can now use the BH package
// [[Rcpp::depends(BH)]]

#include <Rcpp.h>
#include <boost/lexical_cast.hpp>   

using namespace Rcpp;

using boost::lexical_cast;
using boost::bad_lexical_cast;

// [[Rcpp::export]]
std::vector<std::string> lexicalCast(std::vector<int> v) {

    std::vector<std::string> res(v.size());

    for (unsigned int i=0; i<v.size(); i++) {
        try {
            res[i] = lexical_cast<std::string>(v[i]);
        } catch(bad_lexical_cast &) {
            res[i] = "(failed)";
        }
    }

    return res;
}


/*** R
lexicalCast(c(42L, 101L))
*/

输出

R> Rcpp::sourceCpp("/tmp/lexcast.cpp")

R> lexicalCast(c(42L, 101L))
[1] "42"  "101"
R> 

替代

因为将数字转换为字符串与计算本身一样古老,您也可以使用:

  • itoa()
  • snprintf()
  • 可能还有一些我一直在忘记。

答案 1 :(得分:3)

正如其他人所指出的,有几种方法可以做到这一点。以下是两种非常简单的方法。

1。 std::to_string

Rcpp::CharacterVector add_chars_to_int1(Rcpp::IntegerVector x){
    int n = x.size();
    Rcpp::CharacterVector BASEL_SEG(n);
    for(int i = 0; i < n; i++){
        BASEL_SEG[i] = "B0" +  std::to_string(x[i]);
    }
    return BASEL_SEG;
}

2。创建新的Rcpp::CharacterVector

Rcpp::CharacterVector add_chars_to_int2(Rcpp::IntegerVector x){
    int n = x.size();
    Rcpp::CharacterVector BASEL_SEG(n);
    Rcpp::CharacterVector myIntToStr(x.begin(), x.end());
    for(int i = 0; i < n; i++){
        BASEL_SEG[i] = "B0" +  myIntToStr[i];
    }
    return BASEL_SEG;
}

打电话给他们:

add_chars_to_int1(int_vec) ## using std::to_string
[1] "B01" "B02" "B03" "B04" "B05"

add_chars_to_int2(int_vec) ## converting to CharacterVector
[1] "B01" "B02" "B03" "B04" "B05"