[Rcpp-devel] Filling a list with iterator, or setting names from CharacterVector/SEXP?

Dirk Eddelbuettel edd at debian.org
Fri Sep 7 13:43:53 CEST 2012


On 7 September 2012 at 01:32, Christian Gunning wrote:
| > | Can I use as<std::string>() and then iterate over the CharacterVector?
| >
| > Sure, works via   Rcpp::as< std::vector< std::string> >(foo)
| 
| Perfect, thanks.  Revised example included below for reference.
| 
| > I am not sure what it is that you want but if you look e.g. at RcppExamples
| > and its examples related to parameter passage in and out, you see that we can
| > pick _arbitrary_ objects in and out of Rcpp::Lists by name.   Does that help?
| 
| It looks like I just answered my own question -- I'd like to get the
| actual *names* of the list on the C++ side:
| Rcpp::List listnames = mylist.attr("names");
| Is the .attr mechanism general to any named attribute that belongs to an SEXP?
| 
| The ultimate goal is C++ error-checking of list-access names -- if the
| named element is not present in the list, print the offending name and
| throw an exception.  Is there an easier way to do this than checking
| the supplied name (as std::string) against the vector of list names?

I think the STL has algorithms for it, ie something like the R code 

    "foo" %in% vec

then works via a single call with one 'token' and a vector. The function may
be called find() -- I can't quite recall but I think I used this before.

Dirk

| I admit this looks convoluted, but it's a minimal example...
| 
| using namespace Rcpp ;
| class World {
|     public:
|         World(SEXP mymat_) : mymat(mymat_), myrows(0), mycols(0) {
|             Rcpp::List mynames = mymat.attr("dimnames");
|             CharacterVector rownames_ = mynames[0];
|             rownames = Rcpp::as< std::vector< std::string>
| >(rownames_);
|             nrows = rownames.size();
|             for (int i=0; i<nrows; i++) {
|                        myrows[rownames[i]] = i;
|             }
|             rownames_list = myrows.attr("names");
|         }
|         SEXP get(std::string varname) {
|             if (debug) {
|                 // check that varname is in rownames_list
|             }
|             return myrows[varname];
|        }
|        void put(std::string varname, int val){
|             if (debug) {
|                 // check that varname is in rownames_list
|             }
|             myrows[varname] = val;
|         };
|     public:
|         Rcpp::List myrows, mycols;
|     private:
|         std::vector<std::string> rownames;
|         Rcpp::List rownames_list ;
|         Rcpp::NumericMatrix mymat;
|         Rcpp::List mynames;
|         int  nrows, ncols;
|         bool debug;
| };
| 
| RCPP_MODULE(yada){
|     using namespace Rcpp ;
|     class_<World>( "World" )
|     .constructor<SEXP>()
|     .method( "get", &World::get     , "get a list element" )
|     .method( "put", &World::put     , "put a list element" )
|     ;
| }
| 
| 
| ## in R
| mytest <- function(nr=2, nc=3) {
|   inmat = matrix(1:(nr*nc), nrow=nr);
|   colnames(inmat) = letters[1:nc];
|   rownames(inmat) = letters[1:nr];
|   aa <- new(World, inmat)
|   ret1 <- aa$get("a")
|   aa$put("a", 17L)
|   ret2 <- aa$get("a")
|   list(ret1, ret2)
| }
| 
| 
| -- 
| A man, a plan, a cat, a ham, a yak, a yam, a hat, a canal – Panama!

-- 
Dirk Eddelbuettel | edd at debian.org | http://dirk.eddelbuettel.com  


More information about the Rcpp-devel mailing list