Dirk, Thanks. As Dirk previously points out, every element of Rcpp::List is of type SEXP. So I looked at some R's doc, we should be able to get information (attributes in R's term: int or real, names, dims) from the SEXP at least using R's C functions such as examples at http://cran.r-project.org/doc/manuals/R-exts.html#Attributes and the functions used in Dirk's example.
Jiqiang On Wed, May 9, 2012 at 4:55 PM, Dirk Eddelbuettel <[email protected]> wrote: > > On 9 May 2012 at 16:38, Bob Carpenter wrote: > | Thanks again, Dirk, for being so responsive to > | our newbie queries. There's some more inline below. > | > | On 5/8/12 11:34 PM, Dirk Eddelbuettel wrote: > | > > | > On 8 May 2012 at 23:17, Jiqiang Guo wrote: > | > | Suppose I have a function in CPP as > | > | > | > | void cppfun(Rcpp::List lst) { > | > | ...... > | > | } > | > | > | > | Then I would like to call this cppfun in R code as say > | > | cppfun(list(a=a, b=b, c=c, ...)), in which > | > > | > (Well you need a SEXP somefun(SEXP ...) interface from R) > | > | We (I'm working with Jiqiang) were hoping to > | let Rcpp do the heavy wrapping here following > | the std::vector example in the Rcpp modules doc (last > | full example). > | > | > | a, b, c could be of different types and their type might be > | different as this > | > | function gets called another time. So I would like to know the > | type of a, b, > | > | c in the CPP code. Could someone help me out or point to me some > other > | > | approaches? Thanks. > | > > | > It's a good question. I have at time thought about that a little, but > | have no > | > immediate solution for you. > | > > | > One could possible use something C++-ish via traits. > | > | We are using traits/policies all over our own code, > | but this isn't a compile-time type/behavioral config issue. The > | types someone passes us in a call that takes a list > | could be anything, and we need to check they're compatible > | with what we're expecting and handle the error if they're > | not. > | > | > One could also use C level macros from the R API which simply test > | for types > | > as after all each element of a List must be a SEXP, so we use the > | SEXP-style > | > macros. > | > | This could work. We just don't know what's in an > | SEXP or how to get the SEXP from the Rcpp::List entries. > > See below for a stylized (working) example. > > | What we (I'm working with Jiqiang) need is to be able to > | > | 1. access the value of an Rcpp list entry by name. > > Name or position work, yes. > > But if you know the name, don't you know the type too? > > | 2. recover the basic type, integer or floating point > > Integer always casts up to float so you get just use NumericVector if ... > > | 3. recover the dimensions > > ... all you want is the length. > > | 4. recover the values as a vector > > My stylized example does that, allbeit for matrices. > > | Presumably that's available somewhere in the Rcpp::List > | if you can use it to communicate back and forth > | losslessly with R. > > Sort of. Rcpp::List allows for mixed types, just as in R. In C/C++, these > are > SEXP. And SEXP can be converted via Rcpp::as<> or implicitly because that > is > what Rcpp does anyway. > > | > In the end I always went with more explicit code design: only use a > | List for > | > transfer to / from R, and otherwise use explicit C++ types. > | > | I completely agree with Dirk's last point -- we only > | want to use Rcpp as transport to/from R. > | > | Is there a place to find the API doc somewhere, > | like what methods are available on an Rcpp::List? > > There are our writeups, ie the vignettes. > > But there is so much code that it is hard to document all. There is the > doxygen generated documentation too. > > > | Otherwise, I can just look at the code. I'm about to > | try to look through the source now, so maybe I'll be > | able to answer our own question. > | > | - Bob > > Here is a simple example: > > > R> > R> suppressMessages(library(inline)) > R> > R> src <- ' > + Rcpp::List lst(lstSexp); > + > + int n = lst.length(); > + Rcpp::IntegerMatrix dims(n, 2); > + > + for (int i=0; i<n; i++) { > + SEXP s = lst[i]; // could also go by name > + if (Rf_isInteger(s)) { // isInteger() from R API > + Rcpp::IntegerMatrix m(s); > + dims(i,0) = m.nrow(); > + dims(i,1) = m.ncol(); > + } else if (Rf_isNumeric(s)) { // idem > + Rcpp::NumericMatrix m(s); > + dims(i,0) = m.nrow(); > + dims(i,1) = m.ncol(); > + } else if (Rf_isString(s)) { // idem > + Rcpp::CharacterMatrix m(s); > + dims(i,0) = m.nrow(); > + dims(i,1) = m.ncol(); > + } else { > + dims(i,0) = R_NaInt; > + dims(i,1) = R_NaInt; > + } > + } > + return dims; > + ' > R> > R> fun <- cxxfunction(signature(lstSexp="list"), # types are checked, > 'list' just for info > + body=src, > + plugin="Rcpp") > R> > R> fun(list(a=matrix(1:9,3,3), b=matrix(1L:4L,2,2), c=NULL, d=new.env(), > e=rnorm)) > [,1] [,2] > [1,] 3 3 > [2,] 2 2 > [3,] NA NA > [4,] NA NA > [5,] NA NA > R> > > > Notice how we pass two different matrices, a NULL, an environment and a > function just for kicks. > > Hope this helps, Dirk > > | > | > | > | _______________________________________________ > | Rcpp-devel mailing list > | [email protected] > | https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel > > -- > R/Finance 2012 Conference on May 11 and 12, 2012 at UIC in Chicago, IL > See agenda, registration details and more at http://www.RinFinance.com > _______________________________________________ > Rcpp-devel mailing list > [email protected] > https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel >
_______________________________________________ Rcpp-devel mailing list [email protected] https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
