将StringVector与Rcpp连接起来

use*_*085 3 c++ r concatenation rcpp

我无法弄清楚如何用Rcpp连接2个字符串; 当我怀疑有一个明显的答案时,文档没有帮助我.

http://gallery.rcpp.org/articles/working-with-Rcpp-StringVector/

http://gallery.rcpp.org/articles/strings_with_rcpp/

StringVector concatenate(StringVector a, StringVector b)
{
 StringVector c;
 c= ??;
 return c;
}
Run Code Online (Sandbox Code Playgroud)

我希望这个输出:

a=c("a","b"); b=c("c","d");
concatenate(a,b)
[1] "ac" "bd"
Run Code Online (Sandbox Code Playgroud)

nru*_*ell 7

可能有几种不同的方法来解决这个问题,但这里有一个选项std::transform:

#include <Rcpp.h>
using namespace Rcpp;

struct Functor {
    std::string
    operator()(const std::string& lhs, const internal::string_proxy<STRSXP>& rhs) const
    {
        return lhs + rhs;
    }
};

// [[Rcpp::export]]
CharacterVector paste2(CharacterVector lhs, CharacterVector rhs)
{
    std::vector<std::string> res(lhs.begin(), lhs.end());
    std::transform(
        res.begin(), res.end(),
        rhs.begin(), res.begin(),
        Functor()
    );
    return wrap(res);
}

/*** R

lhs <- letters[1:2]; rhs <- letters[3:4]

paste(lhs, rhs, sep = "")
# [1] "ac" "bd"

paste2(lhs, rhs)
# [1] "ac" "bd"

*/ 
Run Code Online (Sandbox Code Playgroud)

首先将左手表达式复制到a中的原因std::vector<std::string>internal::string_proxy<>该类 提供operator+了签名

std::string operator+(const std::string& x, const internal::string_proxy<STRSXP>& y) 
Run Code Online (Sandbox Code Playgroud)

而不是,例如

operator+(const internal::string_proxy<STRSXP>& x, const internal::string_proxy<STRSXP>& y) 
Run Code Online (Sandbox Code Playgroud)

如果您的编译器支持C++ 11,则可以稍微清理一下:

// [[Rcpp::plugins(cpp11)]]
#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
CharacterVector paste3(CharacterVector lhs, CharacterVector rhs)
{
    using proxy_t = internal::string_proxy<STRSXP>;

    std::vector<std::string> res(lhs.begin(), lhs.end());
    std::transform(res.begin(), res.end(), rhs.begin(), res.begin(),
        [&](const std::string& x, const proxy_t& y) {
            return x + y;
        }
    );

    return wrap(res);
}

/*** R

lhs <- letters[1:2]; rhs <- letters[3:4]

paste(lhs, rhs, sep = "")
# [1] "ac" "bd"

paste3(lhs, rhs)
# [1] "ac" "bd"

*/
Run Code Online (Sandbox Code Playgroud)


use*_*085 5

一个有效的解决方案是使用:

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
CharacterVector concatenate(std::string x, std::string y)
{
               return wrap(x + y);
}
Run Code Online (Sandbox Code Playgroud)

然后 :

Vconcatenate=Vectorize(concatenate)
Vconcatenate(letters[1:2],letters[3:4])
Run Code Online (Sandbox Code Playgroud)

要么 :

// [[Rcpp::export]]
CharacterVector concatenate(std::vector<std::string> x,std::vector<std::string> y)
{
  std::vector<std::string> res(x.size());
  for (int i=0; i < x.size(); i++)
  {
    res[i]=x[i]+y[i];
  }
  return wrap(res);
}
Run Code Online (Sandbox Code Playgroud)