[Rcpp-devel] type information about elements in Rcpp::List
Jiqiang Guo
guojq28 at gmail.com
Wed May 9 23:34:27 CEST 2012
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 <edd at debian.org> 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
> | 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
> _______________________________________________
> 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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20120509/82504302/attachment.html>
More information about the Rcpp-devel
mailing list