2010-06-21 5 views
26

J'écris un module CRPP un voudrais revenir comme un élément de la liste RcppResultSet une liste dont les éléments sont des vecteurs. Par exemple, .Call("myfunc")$foo devrait être quelque chose comme:Comment créer une liste de vecteurs dans Rcpp?

[[1]] 
[1] 1 

[[2]] 
[1] 1 1 

[[3]] 
[1] 1 1 1 

(les chiffres exacts ne sont pas importants ici). Le problème est que je ne connais pas la bonne façon Rcpp de le faire. J'ai essayé de passer un vector<vector<int> > mais ceci construit une matrice en prenant silencieusement la longueur du premier vecteur comme largeur (même si la matrice est en lambeaux!). Je l'ai essayé la construction d'un RcppList mais ont du mal à jeter divers objets (comme RcppVector) en toute sécurité dans SEXP s.

Quelqu'un a des conseils sur les meilleures pratiques pour faire face à des structures complexes telles que les listes de vecteurs dans CRPP?

Répondre

37

[agréable de voir ça ici, mais Romain et je le recommande généralement la liste rccp-devel pour la question. S'il vous plaît poster là aller de l'avant que le projet n'est pas encore si grand que cela justifie d'avoir des questions dispersées sur tout le web. ]

RcppResultSet fait partie de l'ancienne classique API alors beaucoup de travail est entré dans ce que nous appelons la nouvelle API (en commençant par 0,7. * Versions). Jetez un oeil à l'actuel Rcpp page on CRAN et la liste des vignettes - six et en comptant.

Avec la nouvelle API vous reviendriez quelque chose comme

return Rcpp::List::create(Rcpp::Named("vec") = someVector, 
          Rcpp::Named("lst") = someList, 
          Rcpp::Named("vec2") = someOtherVector); 

en une seule déclaration (et peut-être en utilisant Rcpp::wrap() explicites appels), ce qui crée ce qui en R serait

list(vec=someVector, lst=someList, vec2=someOtherVector) 

Et Rcpp::List devrait aussi être capable de faire des listes de listes de listes ... bien que je ne sois pas sûr que nous ayons des tests unitaires pour cela --- mais il y a de nombreux exemples dans les 500 tests unitaires.

Comme il arrive, j'ai passé les derniers jours la conversion d'un grand nombre de RQuantLib code de l'API classique à la nouvelle API. Cela sera probablement publié une fois que nous aurons la version 0.8.3 de Rcpp (espérons que dans quelques jours). En attendant, vous pouvez consulter le RQuantLib SVN archive

+0

Cool, merci! Tout fonctionne si vous vous en tenez aux nouvelles classes 'Rcpp :: ...'! –

+0

Cool en effet. Je dois encore concocter de nouvelles classes 'CRPP :: Date' et' CRPP :: DateTime' --- mais vous pouvez certainement vivre sans le vieux 'RcppParams',' RcppResultSet', 'RcppVector', etc ... Sentez-vous libre de contribuer de nouveaux tests unitaires ou des exemples, ou des ajouts aux docs. Rendez-vous sur 'rcpp-devel' alors :) –

+0

Vous me simplifie la vie. Bien que cela fait quelques jours que j'ai appris Rcpp mais je ne peux pas m'imaginer retourner à la combo de R & C. –

21

je aurais tendance à utiliser une variante compressée de la solution de Dirk:

using namespace Rcpp ; 
return List::create( 
    _["vec"] = someVector, 
    _["lst"] = someList, 
    _["vec2"] = someOtherVector 
) ; 

Aussi, pour revenir à la question initiale, vector< vector<int> > devrait se conclure à une liste de vecteurs entiers, pas une matrice. Voir:

require(Rcpp) 
require(inline) 
require(RUnit) 

fx <- cxxfunction(, ' 

    std::vector< std::vector<int> > v ; 

    std::vector<int> x1(1) ; v.push_back(x1); 
    std::vector<int> x2(2) ; v.push_back(x2); 
    std::vector<int> x3(3) ; v.push_back(x3); 

    return wrap(v) ; 

', plugin = "Rcpp") 

Je reçois:

> fx() 

[[1]] 
[1] 0 

[[2]] 
[1] 0 0 

[[3]] 
[1] 0 0 0 
Questions connexes