Try the following:
#include <Rcpp.h> using namespace Rcpp; // [[Rcpp::export]] IntegerVector which4( NumericVector x) { int nx = x.size(); std::vector<int> y; y.reserve(nx); for(int i = 0; i < nx; i++) { if (R_IsNA(x[i])) y.push_back(i+1); } return wrap(y); }
which we can run, like this, in R:
> which4(t1) [1] 3 4 8
Performance
Note that we have changed the above solution to the backup space for the output vector. This replaces which3 , which:
// [[Rcpp::export]] IntegerVector which3( NumericVector x) { int nx = x.size(); IntegerVector y; for(int i = 0; i < nx; i++) { // if (internal::Rcpp_IsNA(x[i])) y.push_back(i+1); if (R_IsNA(x[i])) y.push_back(i+1); } return y; }
Then the performance on a vector of 9 elements is the following with which4 the fastest:
> library(rbenchmark) > benchmark(retIdxNA(t1), whichNA(t1), which2(t1), which3(t1), which4(t1), + replications = 10000, order = "relative")[1:4] test replications elapsed relative 5 which4(t1) 10000 0.14 1.000 4 which3(t1) 10000 0.16 1.143 1 retIdxNA(t1) 10000 0.17 1.214 2 whichNA(t1) 10000 0.17 1.214 3 which2(t1) 10000 0.25 1.786
Repeating this for a 9000-element vector, the Armadillo solution comes pretty quickly than the others. Here which3 (which coincides with which4 , except that it does not reserve space for the output vector) comes in the worst case, and which4 takes the second place.
> tt <- rep(t1, 1000) > benchmark(retIdxNA(tt), whichNA(tt), which2(tt), which3(tt), which4(tt), + replications = 1000, order = "relative")[1:4] test replications elapsed relative 2 whichNA(tt) 1000 0.09 1.000 5 which4(tt) 1000 0.79 8.778 3 which2(tt) 1000 1.03 11.444 1 retIdxNA(tt) 1000 1.19 13.222 4 which3(tt) 1000 23.58 262.000
G. grothendieck
source share