2012-11-11 12 views
6

Ich habe gerade angefangen, R zu lernen, also mit trivial aussehenden Problemen festgefahren. Ich versuche herauszufinden, wie Werte in R ausgegeben werden. In C++ verwenden wir einfach die Rückgabevariable, aber das scheint bei R nicht der Fall zu sein. Angenommen, ich habe eine Funktion, die 4 Eingabeargumente benötigt, übergibt diese Argumente an a C++ - Funktion, die die erforderlichen Berechnungen durchführt, was muss ich jetzt tun, wenn ich dieses myfun in R laden und die Ausgabe von der C++ - Funktion erhalten möchte? Das folgende ist die Vorlage, die ich versuche zu verwenden.C++ - und R-Schnittstelle, Ausgabe

extern "C" { 
    SEXP myfun(SEXP S, SEXP A, SEXP B, SEXP C) { //will call this function from R. 
    SEXP rate, dir, list, list_names; //declare variables 

    PROTECT(rate = allocMatrix(REALSXP, 10, 2)); //allocate 10x2 matrix of double type? 
    PROTECT(dir = allocVector(INTSXP, 10)); //allocated vector(10) of int type? 

    double* p_rate = REAL(rate); //why do I need pointers? 
    int* p_dir = INTEGER(dir); 

// hier nenne ich eine C++ Funktion, die vector<vector<double> > someVal und vector<int> someVal2 berechnet.

Jetzt möchte ich diese Werte an die Rate und dir übergeben.

for(int i =0; i < 10; i++){ 
     rate[i][0] = someVal1[i][0]; 
     rate[i][1] = someVal1[i][1]; 
     dir[i] = someVal2[i]; 
    } 

aber der Compiler mag es nicht. Ich bin mir nicht sicher, wie man in diesem Fall die Zeiger p_rate und p_dir benutzt.

Auch ich bin nicht ganz zu verstehen, warum der folgende Code ist so wie es ist. Es scheint die strings, rate und dir an die list_names und values ​​an rate und dir weiterzuleiten. Warum können wir nicht einfach die gewünschten Werte drucken und drucken?

char *tag[2] = {"rate","dir"}; 
    PROTECT(list_names = allocVector(STRSXP ,2)); 
    SET_STRING_ELT(list_names, 0, mkChar(tag[0])); 
    SET_STRING_ELT(list_names, 1, mkChar(tag[1])); 
    PROTECT(list = allocVector(VECSXP ,2)); 
    SET_VECTOR_ELT(list, 0, rate); 
    SET_VECTOR_ELT(list, 1, dir); 
    setAttrib(list, R_NamesSymbol , list_names); 

    UNPROTECT(8); 
    return (list); 
} 

Ich bekomme nicht die Grundidee hinter der Rückgabe der Variablen in R, es scheint sehr verwirrend. Ich würde es sehr schätzen, wenn mich jemand auf die entsprechenden Ressourcen aufmerksam machen könnte, die diese Dinge erklären.

Vielen Dank für Ihre Hilfe im Voraus!

Antwort

9

Wenn Sie bereits mit C++ vertraut sind, können Sie unser Rcpp-Projekt für nahtlose R- und C++ - Integrationen nützlich finden. Es enthält viel Dokumentation und Beispiele, plus CRAN hat jetzt über 80 Pakete, die es verwenden, die ein weiteres großes Korpus von Beispielen bietet.

Sie könnten mit "Einführung" Vignette beginnen, die unserem JSS paper entspricht, und auch den [rcpp] Tag hier lesen.

Ansonsten sind Sie wieder bei der R-API, die blanker ist und nur auf C basiert.

5

Wie wir bei der Beantwortung Ihrer previous question gesagt haben, geben Sie Rcpp eine Chance, und nehmen Sie alle Kludis in Ihrem Code.

#include <Rcpp.h> 
using namespace Rcpp ; 

void yourCode(std::vector< std::vector<double> >& someVal, 
       std::vector<double>& someVal2){ ... } 

extern "C" SEXP myfun() { 
    NumericMatrix rate(10, 2); 
    NumericVector dir(10) ; 

    std::vector< std::vector<double> > someVal ; 
    std::vector<double> someVal2 ; 

    // call whatever function that fills someVal and someVal2 
    yourCode(someVal, someVal2) ; 

    // fills rate and dir 
    for(int i =0; i < 10; i++){ 
     rate(i, 0) = someVal1[i][0]; 
     rate(i, 1) = someVal1[i][1]; 
     dir[i] = someVal2[i]; 
    } 

    // structure the output 
    List result = List::create( 
     _["rate"] = rate, 
     _["dir"] = dir 
    ) ; 

    return result ; 

}