0

I am beginner in use of Rcpp and I want get faster selection of values of vectors after calculation of quantiles. In the example below, it runs well when lower and higher limits
calculated by qnorm function are manually entered (function val.sel.1). Yet, when these limits are coming from a prior calculation, no resulting vector is obtained (function val.sel.2). I am wondering what is wrong in the use I do of arguments. Thanks in advance for any help. Alain

R> src.1 <-'
NumericVector x = xx, p = prob;
int n = p.size() ;
int m = x.size() ;
NumericVector res(n), quant ;
for( int i=0; i<n; i++) res[i] = R::qnorm(p[i], Rcpp::mean(x), Rcpp::sd(x), 1, 0) ;
for( int i=0; i<m; i++) {
if (x[i] > 35.45295 && x[i] < 83.34705) quant.push_back(x[i]);  
}
return wrap(quant) ;
'
R> val.sel.1 <- cxxfunction(signature(xx="numeric", prob="numeric"), plugin='Rcpp',  body=src.1)

R> x <- c(77, 95, 16, 54, 63, 93, 44, 88, 25, 39)

R> val.sel.1(x, prob=c(0.2,0.8))        # [1] 77 54 63 44 39


R> src.2 <-'
NumericVector x = xx, p = prob;
int n = p.size() ;
int m = x.size() ;
NumericVector res(n), quant ;
for( int i=0; i<n; i++) res[i] = R::qnorm(p[i], Rcpp::mean(x), Rcpp::sd(x), 1, 0) ;
for( int i=0; i<m; i++) { 
if (x[i] > res[1] && x[i] <  res[2]) quant.push_back(x[i]); 
}
return wrap(quant) ;
'
R> val.sel.2 <- cxxfunction(signature(xx="numeric",prob="numeric"),plugin='Rcpp',     body=src.2)

R> val.sel.2(x, prob=c(0.2,0.8))            # numeric(0)

1 Answers1

3

Some comments:

1) Using push_back on Rcpp containers is generally considered 'bad practice' since it forces a copy of the vector with each push; it is better to initialize the vector with a given size, and fill them as needed, either with for loops, iterators, STL algorithms... See the Rcpp Gallery for a lot of good examples on how this is done.

2) If you really want to use push_back, consider using the STL containers, e.g. std::vector<double> or std::vector<int>, and Rcpp::wrap-ing the output when returning the result to R.

As for your actual problem, it's a simple mistake -- you're using R style array indexing rather than C++ style array indexing. Change

if (x[i] > res[1] && x[i] <  res[2]) quant.push_back(x[i]); 

to

if (x[i] > res[0] && x[i] <  res[1]) quant.push_back(x[i]); 

and you'll get the expected result.

Kevin Ushey
  • 20,530
  • 5
  • 56
  • 88