#r #rcpp
#r #rcpp
Вопрос:
Я пытаюсь передать аргументы в функции rcpp, используя … но это не работает. Как это сделать правильно?
NumericVector function(SEXP xR, ...){
NumericVector x(xR);
int lenx = x.size();
NumericVector ret(lenx);
for(int i=0; i < lenx; i ){
if(x[i]<0){
ret[i] = 0;
}else if(x[i]>1){
ret[i] = 1;
}else{
ret[i] = anotherfunction(x[i], ...);
}
}
return ret;
}
В текущей версии я получаю эту ошибку:
expected primary-expression before '...' token
Ответ №1:
Rcpp11
имеет концепцию переменного числа аргументов с классом Dots
и NamedDots
. Вы бы сделали что-то вроде этого:
#include <Rcpp11>
List force_dots( const Dotsamp; dots ){
List out(n) ;
for( int i=0; i<n; i ){
out[i] = Rcpp_eval( dots.promise(i), dots.environment(i)) ;
}
return out ;
}
// [[export]]
List dots_example(NumericVector x, Dots dots){
int n = dots.size() ;
List args = force_dots(dots) ;
return args ;
}
/*** R
dots_example(1:10, "e" )
# [[1]]
# [1] "e"
*/
При использовании attributes::sourceCpp
этого файла вы получаете функцию R с многоточием:
> dots_example
function(x, ...){
res <- .Call( "sourceCpp_dots_example" , x, environment())
res
}
Это лишь частично отвечает на вопрос, т. Е. как передать C переменное количество аргументов из R.
Вам также понадобится что-то похожее на R do.call
для вызова another_function
функции. Пока вам вроде как придется делать это вручную, пока мы не найдем способ реализовать полезный do_call
Ответ №2:
Возможно, вы путаете конструкцию на языке R ...
с чем-то, что, как вы предполагаете, также существует в C . И хотя C имеет varargs
, это не поддерживается Rcpp из-за интерфейса от R. Все, что у нас есть, — это .Call()
интерфейс
SEXP somefunction(SEXP a, SEXP b, SEXP c, ...)
и здесь ...
используется в буквальном смысле только для изложения: у вас может быть 0, 1, 2, 3, … SEXP
аргументов. Но те, которые вы используете, должны быть полностью квалифицированы. Короче говоря, использование ...
приводит к синтаксической ошибке, которую вы видите. Подробности см. в разделе 5.9 «Написание расширений R».
И в качестве дополнительного примечания, именно поэтому у нас есть макросгенерированный код в Rcpp. Теперь, с C 11, вы также можете использовать переменные шаблоны в коде C (которые Rcpp11 с большим эффектом использует в своем внутреннем коде), но это, конечно, не изменяет интерфейс на R, который остается тем же .Call()
интерфейсом и, следовательно, тем же ограничением. Вариационные шаблоны очень хороши и открыты для использования в вашем коде C либо с Rcpp, либо с Rcpp11, но они не меняют интерфейс на R. Вам нужен фиксированный набор аргументов, и вы не можете полагаться на переменное число.
Тем не менее, если вы просто передаете List
объект в качестве одного из своих аргументов, то вы можете по желанию просмотреть его по позиции или имени и проверить содержимое. Это наиболее близко по духу к вашему вопросу.