[Rcpp-devel] Returning a named (and classed?) list from an RcppExport SEXP function

Romain Francois romain at r-enthusiasts.com
Fri Mar 12 20:43:12 CET 2010


Hello Doug,

Le 12/03/10 17:14, Douglas Bates a écrit :
>
> I have looked at your (i.e. Dirk and Roman's) submitted Rjournal
> article on Rcpp and decided that I should take the plunge.
>
> To get my feet wet I am starting with a relatively simple example
> interfacing to (God help us) 1960's style Fortran written by Mike
> Powell and incorporated in the minqa package.
>
> The value to be returned is a named list of heterogeneous values.  I
> can see how to construct such a list in the classic Rcpp API using a
> RcppResultSet object but I don't know the best way to accomplish this
> in the more modern Rcpp namespace.

That is tricky. We have Pairlist has Dirk suggested, but as the name 
implies they manage LISTSXP objects and not VECSXP.

Rcpp::List (which manages VECSXP) has less convenient semantics (but 
this is on my todo list), you can do :

List x ;
x["foo"]  = 1 ;
x["bar"]  = "something" ;

which is kind of convenient, but that is not cheap as the VECSXP is 
reallocated each time.

Otherwise, it is possible to allocate it first and manage the names 
separately:

List x(2);
x[0] = 1 ;
x[1] = "something" ;
CharacterVector y(2) ;
y = "foo", "bar" ;
x.names() = y ;

but this is too verbose.

what we need is something like this:

List x(
   Named( "foo" ) = 1,
   Named( "bar" ) = "something" ) ;

> Can someone point me in the right
> direction?

We need to get better at documenting Rcpp, now that the code is getting 
stable. For now I think the best place to look for examples is the unit 
tests.

 > system.file( "unitTests", package = "Rcpp" )

They are vaguely organized in terms of classes.

> Also, is there a convenient idiom for attaching an S3
> class name to a list to be returned?

yes.

x.attr( "class" ) = "whatever" ;

> An unrelated question -- has anyone looked at accessing S4 classed
> objects in Rcpp?  I have had considerable experience with S4 classes
> and objects and could keep such a project in mind as I begin to
> explore Rcpp.

The slot method of the RObject class (which is the parent class of all 
our classes) allows read/write of slots.

x.slot( "foo" ) = 3 ;

this throws exception if x is not an S4 object or if its class does not 
have a "foo" attribute. this then uses the R function "slot<-" (there 
might be a better way with the R api, but I did not find it at the time)

> Yet another question, if i may.   Does coercion take place in
> constructing an object like
>
> Rcpp::NumericVector aa(a);
>
> where a is an SEXP, say an SEXP argument to a C++ function, where I
> accidentally passed an integer vector instead of a double vector?  If
> so, what happens if there is no coercion?  Are the contents of the
> SEXP copied to newly allocated storage or not?

There is coercion. for example a Rcpp::NumericVector is only allowed to 
store a REALSXP, if you give it a INTSXP, coercion happens.

There is no copy. The objects are essentially proxy objects to the SEXP 
they encapsulate. We have the clone template function to explicitely 
copy when this is needed, for example :

Rcpp::NumericVector aa(a) ;
Rcpp::NumericVector b = Rcpp::clone(aa) ;

> The reason that I ask is because there are some places in the lme4
> code where I want to make sure that I have a pointer to the contents
> of the original vector because I am want to change the contents
> without copying.

yes. we want that too. but this is somewhat orthogonal to the "copy on 
change" semantics of R ...


More information about the Rcpp-devel mailing list