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

Christian Gunning xian at unm.edu
Fri Aug 31 05:52:46 CEST 2012


I'm trying to implement a class lets me access elements by name in the
actual C++ code.
I'm handing in a matrix from R, and using the colnames and rownames of
the matrix to generate a named list containing the relevant indices.
My main interest here is legible code -- I'm trying to set up
user-modifiable markov chain model specification functions in C++ that
are relatively idiot-proof and can be error-checked (so far the idiot
is just me). Initial tests indicate that the speed cost of list access
are very small compared to the actual model code.  I'm not sure if I'm
really abusing lists here, and any suggestions on other directions to
explore would be appreciated.

In any case, I finally got this working, but it's really ugly, and I
feel like there has to be an easier way to do this -- iterators?.
I looked at the doxygen docs for List instantiation and methods, and I
admit it's still Latin to me (which is a little better than Greek...)
This is built with a vanilla Rcpp.package.skeleton(modules=TRUE),
replacing the World class with the following:


using namespace Rcpp ;
class World {
    public:
        World(SEXP my_) : my(my_) {
            mynames = my.attr("dimnames");
            CharacterVector rownames = mynames[0];
            nrows = rownames.size();
            myrows = Rcpp::List(0);
            for (int i=0; i<nrows; i++) {
                Rcpp::CharacterVector tmpname(rownames[i]);
                std::string thisname = as<std::string>(tmpname);
                myrows[thisname] = i;
            }
        }
       Rcpp::List myrows;
       Rcpp::List getrows() {
           return myrows;
      }

    private:
        Rcpp::NumericMatrix my;
        Rcpp::List mynames;
        int  nrows;
};

RCPP_MODULE(yada){
    using namespace Rcpp ;
    class_<World>( "World" )
    // expose the default constructor
    .constructor<SEXP>()
    .method( "getrows", &World::getrows     , "test function, return
something" )
    ;
}

In R:
require(Rcpp)
Rcpp.package.skeleton('FillList', module=T)

In shell:
replace FillList/src/rcpp_module.cpp  contents from "class World" to
end with the above
R CMD INSTALL FillList

In R:
inmat = matrix(1:6, nrow=2);
colnames(inmat) = letters[1:ncol(inmat)];
rownames(inmat) = letters[1:nrow(inmat)];
require(FillList)
aa = new(World, inmat)
aa$getrows()

thanks,
Christian


More information about the Rcpp-devel mailing list