Rcpp中是否有基本功能:
NA
值。我使用NumericVector
作为示例,将以上标准编写为下面的函数。如果在Rcpp中没有执行所述操作的基本函数,那么应该有一种模板函数的方法,以便给定任何类型的向量(例如numeric
,character
等)以上逻辑将能够被执行。
// [[Rcpp::export]]
NumericVector cppvectorize(NumericVector x,NumericVector y) {
NumericVector y_out(y.size());
if(x.size() == 1) {
for(int i = 0; i < y_out.size(); i++) {
y_out[i] = x[0];
}
} else if(x.size() == y_out.size()) {
for(int i = 0; i < y_out.size(); i++) {
y_out[i] = x[i];
}
} else {
for(int i = 0; i < y_out.size(); i++) {
y_out[i] = NA_REAL;
}
}
return y_out;
}
答案 0 :(得分:2)
不幸的是,你最接近这种功能的是Rcpp支持的rep
变种之一。但是,没有一种变体符合所需的输出。因此,唯一的选择是真正实现所需功能的模板化版本。
要创建模板化函数,我们将首先创建一个处理SEXP
objects调度的路由函数。路由功能背后的基本原理是SEXP
objects能够使用Rcpp属性从 R 中检索并映射到 R ,而模板化版本不是。因此,我们需要指定可能的SEXTYPE (used as RTYPE)个调度。 TYPEOF()
宏检索编码的数字。使用switch
语句,我们可以将此号码发送到适当的案例中。
调度后,我们到达模板化函数。模板化函数使用Rcpp的基类Vector
类来简化数据流。从这里开始,显着的新颖性是使用::traits::get_na<RTYPE>()
动态检索适当的NA
值并填充它。
有了这个计划,让我们来看看代码:
#include <Rcpp.h>
using namespace Rcpp;
// ---- Templated Function
template <int RTYPE>
Vector<RTYPE> vec_helper(const Vector<RTYPE>& x, const Vector<RTYPE>& y) {
Vector<RTYPE> y_out(y.size());
if(x.size() == 1){
y_out.fill(x[0]);
} else if (x.size() == y.size()) {
y_out = x;
} else {
y_out.fill(::traits::get_na<RTYPE>());
}
return y_out;
}
// ---- Dispatch function
// [[Rcpp::export]]
SEXP cppvectorize(SEXP x, SEXP y) {
switch (TYPEOF(x)) {
case INTSXP: return vec_helper<INTSXP>(x, y);
case REALSXP: return vec_helper<REALSXP>(x, y);
case STRSXP: return vec_helper<STRSXP>(x, y);
default: Rcpp::stop("SEXP Type Not Supported.");
}
// Need to return a value even though this will never be triggered
// to quiet the compiler.
return R_NilValue;
}
这里我们对每个支持的数据进行一些样本测试
# Case 1: x == 1
x = 1:5
y = 2
cppvectorize(x, y)
## [1] NA
# Case 2: x == y
x = letters[1:5]
y = letters[6:10]
cppvectorize(x, y)
## [1] "a" "b" "c" "d" "e"
# Case 3: x != y && x > 1
x = 1.5
y = 2.5:6.5
cppvectorize(x, y)
## [1] 1.5 1.5 1.5 1.5 1.5