Предаване на много аргументи () чрез многоточие в 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


person bartektartanus    schedule 05.07.2014    source източник


Отговори (2)


Rcpp11 има концепцията за променлив брой аргументи с класа Dots и NamedDots. Бихте направили нещо подобно:

#include <Rcpp11>

List force_dots( const Dots& 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.

Ще ви трябва и нещо подобно на do.call на R, когато извиквате функцията another_function. Засега някак трябва да го правите ръчно, докато намерим начин да внедрим полезно do_call

person Romain Francois    schedule 06.07.2014

Може да бъркате 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 обект като един от вашите аргументи, тогава можете да го обходите по позиция или име по желание и да проверите съдържанието. Това е най-близкото по дух на вашия въпрос.

person Dirk Eddelbuettel    schedule 05.07.2014