2012-11-11 4 views
6

Ho appena iniziato a imparare R, rimanendo bloccato con problemi di aspetto banale. Sto cercando di capire come vengono emessi i valori in R. In C++ usiamo semplicemente la variabile return, ma non sembra essere il caso di R. Dico che ho una funzione che accetta 4 argomenti di input, passa quegli argomenti ad un funzione C++ che esegue i calcoli richiesti, ora se voglio caricare questo myfun in R e ottenere l'output dal funciton C++, cosa devo fare? Di seguito è riportato il modello che sto cercando di utilizzare.Interfaccia C++ e R, uscita

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); 

// qui Mi chiamare una funzione C++ che calcola vector<vector<double> > someVal e vector<int> someVal2.

Ora voglio passare quei valori alla velocità e dir.

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

ma il compilatore non piace. Non sono sicuro di come usare i puntatori p_rate e p_dir in questo caso.

Inoltre, non capisco perché il codice seguente sia così com'è. Sembra che stia passando le stringhe, rate e dir a list_names e valori alla velocità e dir. Perché non possiamo semplicemente eseguire il cout e stampare i valori desiderati?

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); 
} 

Non ricevo l'idea di base dietro il ritorno delle variabili in R, sembra molto confuso. Sarei davvero grato se qualcuno potesse indicarmi le risorse appropriate che spiegano queste cose.

Grazie per il vostro aiuto in anticipo!

risposta

9

Se si ha già familiarità con C++, è possibile trovare utile il nostro progetto Rcpp per integrarion R e C++ senza interruzioni. Contiene molto di documentazione ed esempi, oltre a CRAN sono ora disponibili più di 80 pacchetti che forniscono un altro grande corpus di esempi.

Si potrebbe iniziare con la vignetta "Introduzione" che corrisponde al nostro JSS paper, e anche sfogliare il tag [rcpp] qui.

In caso contrario, si torna all'API R che è più semplice e basato solo su C.

5

Come abbiamo detto rispondendo allo previous question, dare un colpo a Rcpp e portare via tutto il kludge nel codice.

#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 ; 

}