[Rcpp-devel] type information about elements in Rcpp::List
Dirk Eddelbuettel
edd at debian.org
Wed May 9 22:55:42 CEST 2012
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 at 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
More information about the Rcpp-devel
mailing list