Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I create a list of vectors in Rcpp?

Tags:

r

rcpp

I'm writing an Rcpp module an would like to return as one element of the RcppResultSet list a list whose elements are vectors. E.g., .Call("myfunc")$foo should be something like:

[[1]] [1] 1  [[2]] [1] 1 1  [[3]] [1] 1 1 1 

(the exact numbers are not important here). The issue is that I don't know the right Rcpp way of doing this. I tried passing a vector<vector<int> > but this constructs a matrix by silently taking the length of the first vector as the width (even if the matrix is ragged!). I've tried constructing an RcppList but have a hard time casting various objects (like RcppVector) safely into SEXPs.

Anyone have tips on best practices for dealing with complicated structures such as lists of vectors in Rcpp?

like image 956
Jonathan Chang Avatar asked Jun 21 '10 21:06

Jonathan Chang


People also ask

Is it possible to create a vector list?

You can stick a vector (a restricted structure where all components have to be of the same type) into a list (unrestricted). But you cannot do the reverse. Use lists of lists of lists ... and then use lapply et al to extract.

How do I add a list to a vector?

Adding elements to a list. Additional vectors can be added by specifying the position in the list where we wish to append the new vector. The new elements are concatenated at the end of the list. Multiple elements can also be added to a list with the use of a 'for' or a 'while' loop.


2 Answers

[ Nice to see this here but Romain and I generally recommend the rccp-devel list for question. Please post there going forward as the project is not yet that large it warrants to have questions scattered all over the web. ]

RcppResultSet is part of the older classic API whereas a lot of work has gone into what we call the new API (starting with the 0.7.* releases). Have a look at the current Rcpp page on CRAN and the list of vignettes -- six and counting.

With new API you would return something like

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

all in one statement (and possibly using explicit Rcpp::wrap() calls), creating what in R would be

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

And Rcpp::List should also be able to do lists of lists of lists... though I am not sure we have unit tests for this --- but there are numerous examples in the 500+ unit tests.

As it happens, I spent the last few days converting a lot of RQuantLib code from the classic API to the new API. This will probably get released once we get version 0.8.3 of Rcpp out (hopefully in a few days). In the meantime, you can look at the RQuantLib SVN archive

like image 184
Dirk Eddelbuettel Avatar answered Sep 22 '22 05:09

Dirk Eddelbuettel


I would tend to use a compressed variation of Dirk's solution:

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

Also, to come back to the original question, vector< vector<int> > should wrap itself to a list of integer vectors, not a matrix. See:

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

I get :

> fx()   [[1]] [1] 0  [[2]] [1] 0 0  [[3]] [1] 0 0 0 
like image 37
Romain Francois Avatar answered Sep 23 '22 05:09

Romain Francois