用于子集字符串的 Rcpp 函数

sah*_*ahn 5 c++ r rcpp

我想知道是否有一个Rcpp函数将Rcpp::String数据类型作为输入并返回字符串的给定字符(按索引)。例如,提取字符串索引 0 处的字符。这相当于c++ 中标头中string::at的方法string。我写过这个:

#include <vector>
#include <string>
#include <Rcpp.h>

using namespace Rcpp;

typedef std::vector<std::string> stringList;

int SplitGenotypesA(std::string s) {
    char a = s.at(0);
    int b = a - '0';
    return b;
}
Run Code Online (Sandbox Code Playgroud)

但不想在Rcpp::Stringstd::string类型之间进行转换。

All*_*ron 6

您可以使用 .R 字符串向量直接向 C++ 提供Rcpp::StringVector。这显然也可以处理单个元素。

获取向量第 i 个元素的第 n 个字符就像 一样简单vector[i][n]

所以,不使用std::string你可以这样做:

#include<Rcpp.h>

// [[Rcpp::export]]
Rcpp::NumericVector SplitGenotypesA(Rcpp::StringVector R_character_vector)
{
  int number_of_strings = R_character_vector.size();
  Rcpp::NumericVector result(number_of_strings);
  for(int i = 0; i < number_of_strings; ++i)
  {
    char a = R_character_vector[i][0];
    result[i] = a - '0';
  }
  return result;
}
Run Code Online (Sandbox Code Playgroud)

现在在 R 中你可以这样做:

SplitGenotypesA("9C")
# [1] 9
Run Code Online (Sandbox Code Playgroud)

或者更好的是,

SplitGenotypesA(c("1A", "2B", "9C"))
# [1] 1 2 9
Run Code Online (Sandbox Code Playgroud)

这甚至比执行相同操作的原生 R 方法还要快一些:

microbenchmark::microbenchmark(
  R_method    = as.numeric(substr(c("1A", "2B", "9C"), 1, 1)), 
  Rcpp_method = SplitGenotypesA(c("1A", "2B", "9C")),
  times = 1000)

# Unit: microseconds
#         expr   min    lq     mean median    uq    max neval
#     R_method 3.422 3.765 4.076722  4.107 4.108 46.881  1000
#  Rcpp_method 3.080 3.423 3.718779  3.765 3.765 32.509  1000

Run Code Online (Sandbox Code Playgroud)