[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