How do I create a list of vectors in Rcpp?

18,943

Solution 1

[ 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

Solution 2

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
Share:
18,943
Jonathan Chang
Author by

Jonathan Chang

Stats wiz whizzing on stats.

Updated on June 02, 2022

Comments

  • Jonathan Chang
    Jonathan Chang about 2 years

    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?

  • Jonathan Chang
    Jonathan Chang about 14 years
    Cool, thanks! Everything works if you stick to the new Rcpp::... classes!
  • Dirk Eddelbuettel
    Dirk Eddelbuettel about 14 years
    Cool indeed. I still need to cook up new classes Rcpp::Date and Rcpp::Datetime --- but you can definitely live without the old RcppParams, RcppResultSet, RcppVector, ... etc. Feel free to contribute new unit tests or examples, or additions to the docs. See you on rcpp-devel then :)
  • Tae-Sung Shin
    Tae-Sung Shin over 11 years
    You makes my life easier. Although it's been a few days since I learned Rcpp but I can't imagine going back to combo of R & C.
  • Dirk Eddelbuettel
    Dirk Eddelbuettel over 11 years
    Glad to be of help. Hope to see you over on rcpp-devel if you have questions.
  • MichaelChirico
    MichaelChirico over 7 years
    Does your statement about preferring rcpp-devel still apply?
  • Dirk Eddelbuettel
    Dirk Eddelbuettel over 7 years
    Yes it does. Not all Rcpp committers watch questions here.