我一直在研究有关模板问题的解决方案(即参见@Sameer 回复)。
所以我写了另一个函数,现在模板机制起作用了。
在外部.cpp
文件中:
#include <Rcpp.h>
template <int RTYPE, class T>
Vector<RTYPE> na_omit_template(const Vector<RTYPE>& x) {
typedef typename Vector<RTYPE>::iterator rvector_it;
if (x.size() == 0) {
return x;
}
std::vector<T> out;
rvector_it it = x.begin();
for (; it != x.end(); ++it) {
if (!Vector<RTYPE>::is_na(*it)) {
out.push_back(*it);
}
}
return wrap(out);
}
// [[Rcpp::export(na_omit_cpp)]]
SEXP na_omit(SEXP x) {
switch(TYPEOF(x)) {
case INTSXP:
return na_omit_template<INTSXP, int>(x);
case REALSXP:
return na_omit_template<REALSXP, double>(x);
case LGLSXP:
return na_omit_template<LGLSXP, bool>(x);
case CPLXSXP:
return na_omit_template<CPLXSXP, Rcomplex>(x);
case RAWSXP:
return na_omit_template<RAWSXP, Rbyte>(x);
default:
stop("unsupported data type");
}
}
此函数删除 NA
values,这是我最初的目的。
不幸的是,目前它不适用于所有类型的向量,如下面的R
示例所示。
library(Rcpp)
sourceCpp('file.cpp')
na_omit_cpp(as.integer(c(1, NA, NA, 1, 2, NA))) # OK
# [1] 1 1 2
na_omit_cpp(as.numeric(c(1, NA, NA, 1, 2, NA)))
# [1] 1 1 2
na_omit_cpp(c(NA, 1L, NA, 3L, NA)) # OK
# [1] 1 3
na_omit_cpp(c(NA, 2L, 1, NA)) # OK
# [1] 2 1
na_omit_cpp(c(1.0, 1.1, 2.2, NA, 3, NA, 4)) # OK
# [1] 1.0 1.1 2.2 3.0 4.0
na_omit_cpp(c(1L, NaN, NaN, 0, NA)) # OK
# [1] 1 NaN NaN 0
na_omit_cpp(c(NA, NaN, 1.0, 0.0, 2.2, NA, 3.3, NA, 4.4)) # OK
# [1] NaN 1.0 0.0 2.2 3.3 4.4
na_omit_cpp(as.logical(c(1, 0, 1, NA))) # OK
# [1] TRUE FALSE TRUE
na_omit_cpp(as.logical(c(TRUE, FALSE, NA, TRUE, NA))) # OK
# [1] TRUE FALSE TRUE
# empty vectors ?
na_omit_cpp(c(NA)) # OK
# logical(0)
na_omit_cpp(numeric(0)) # OK
# numeric(0)
na_omit_cpp(logical(0)) # OK
# logical(0)
na_omit_cpp(raw(0)) # OK
# raw(0)
na_omit_cpp(as.raw(c(40,16,NA,0,2))) # NO! (R converts it to 00)
# [1] 28 10 00 00 02
# Warning message ...
na_omit_cpp(as.complex(c(-1, 2, 1, NA, 0, NA, -1))) # NO!
# [1] -1+0i 2+0i 1+0i NA 0+0i NA -1+0i
所以,这个函数几乎在所有情况下都有效,除了raw
向量和complex
向量。
当前未解决的问题是:
- 我不确定为什么会出现这个错误,我想找出原因。任何想法?
- 如@Sameer 所示,先前的模板化函数有一个奇怪的行为。
- 如何接受
character
向量?
我想清楚了 tocase STRSXP: return na_omit_template<STRSXP, ?>(x);
但是这个陈述不能代替std::string
, Rcpp:String
to ?
。