Rcpp: удобное использование компараторов

Я новичок в использовании Rcpp и хочу ускорить выбор значений векторов после вычисления квантилей. В приведенном ниже примере он работает хорошо, когда нижние и верхние пределы
рассчитанные функцией qnorm вводятся вручную (функция val.sel.1). Тем не менее, когда эти пределы исходят из предварительного расчета, результирующий вектор не получается (функция val.sel.2). Мне интересно, что не так в использовании я аргументов. Заранее благодарю за любую помощь. 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 ответ

Некоторые комментарии:

1) Использование push_back на Rcpp контейнеры, как правило, считаются "плохой практикой", так как они заставляют копировать вектор при каждом нажатии; Лучше инициализировать вектор с заданным размером и заполнять их по мере необходимости, либо циклами for, итераторами, алгоритмами STL... Смотрите в галерее Rcpp множество хороших примеров того, как это делается.

2) Если вы действительно хотите использовать push_backрассмотрите возможность использования контейнеров STL, например std::vector<double> или же std::vector<int>, а также Rcpp::wrap-направление вывода при возврате результата в R.

Что касается вашей реальной проблемы, это простая ошибка - вы используете индексацию массива в стиле R, а не индексацию в стиле C++. + Изменить

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

в

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

и вы получите ожидаемый результат.

Другие вопросы по тегам