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 | Rcpp-devel@lists.r-forge.r-project.org | 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 Rcpp-devel@lists.r-forge.r-project.org https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel