[Rcpp-devel] Help with accessing and manipulating List objects

Tal Galili tal.galili at gmail.com
Fri Aug 16 14:48:02 CEST 2013


Hello Dirk,
Your modifications/corrections are VERY helpful, thank you! (also, thank
you for the general kind words and ongoing support, they are much
appreciated)

One more question/improvement - is it possible to have it return whatever
value is inside the "label" attr?

For example, running the following would result in an error:

/*** R
x <- list(a = 1, b=2, 6)
attr(x[[2]], "leaf") = TRUE
attr(x[[2]], "label") = 2
extract_fun(x)

## output:
## Error: expecting a string
/*

Is there a way to either coerce/force "2" to become a string / or to return
it as what it is? (a numeric/double value)?
I thought that was what
        label = as<std::string>(x.attr( "label" )) ;
was doing - but apparently it does not coerce non-string into strings


Any suggestions?


Tal










----------------Contact
Details:-------------------------------------------------------
Contact me: Tal.Galili at gmail.com |
Read me: www.talgalili.com (Hebrew) | www.biostatistics.co.il (Hebrew) |
www.r-statistics.com (English)
----------------------------------------------------------------------------------------------



On Fri, Aug 16, 2013 at 2:47 PM, Dirk Eddelbuettel <edd at debian.org> wrote:

>
> Tal,
>
> You were close.  The error you got indicated that some of (our) wrapping
> around (our) class String was missing somehow.  String is pretty new;
> Romain
> just added it a few month ago under funding by Hadley -- and I am still
> pretty unfamiliar with it.
>
> Which is why I always go back to std::string. So I converted your code
> back,
> which then built find but ran into one run-time error: you didn't test for
> the attribute before extracting it.  That is corrected too.  So your
> list-walker is below, with some extra verbose stdout prints.
>
> Hope this helps, it is a nice example and always was a very good question.
>
> Dirk
>
>
> // Code first
>
>
> #include <Rcpp.h>
> using namespace Rcpp;
>
>
> bool is_list(RObject x){
>     return TYPEOF(x) == VECSXP ;
> }
>
> bool is_string(RObject x){
>     return TYPEOF(x) == STRSXP && Rf_length(x) == 1 ;
> }
>
> bool is_logical(RObject x){
>     return TYPEOF(x) == LGLSXP && Rf_length(x) == 1 ;
> }
>
>
> bool is_leaf(RObject x){
>     if( TYPEOF(x) != REALSXP ) return false ;
>     if( !is_logical( x.attr("leaf") ) ) return false ;
>     bool leaf = x.attr( "leaf" ) ;
>     return leaf; // either TRUE or FALSE. But often, if it exists - it is
> TRUE.
> }
>
> std::string get_label(RObject x){
>     std::string label = "<empty>";
>     if (x.hasAttribute("label")) {
>         label = as<std::string>(x.attr( "label" )) ;
>     }
>     return label; // either TRUE or FALSE. But often, if it exists - it is
> TRUE.
> }
>
>
> void process( List data, std::vector<std::string>& results){
>     Rcout << "List with " << data.size() << " elements\n";
>     for( int i=0; i<data.size(); i++){
>         if( is_list( data[i] ) ){
>             // recurse
>             Rcout << "Recursing into list\n";
>             process( data[i], results ) ;
>         } else if( is_leaf( data[i] ) ){
>             Rcout << "Looking at leaf\n";
>             // we want to collect them. we can use the NumericVector class
>             // wince we know this is a numeric vector.
>             std::string x_label = get_label(data[i]);
>             results.push_back(x_label);
>         } // else do nothing
>     }
> }
>
> // [[Rcpp::export]]
> std::vector<std::string> extract_fun(List x){
>     std::vector<std::string> results ;
>     process(x, results) ;
>     return(results) ;
> }
>
> /*** R
>
> x <- list(a = 1, b = 2, c = list(ca = 3, cb = 4, 5), 6)
> attr(x[[1]], "leaf") = TRUE
> attr(x[[1]], "label") = "leaf 1"
> attr(x[[3]][[1]], "leaf") = TRUE
>
> attr(x[[2]], "leaf") = TRUE
> attr(x[[2]], "label") = "leaf 2"
>
> str(x)
>
> extract_fun(x)
>
> */
>
>
> // Output below:
>
> > extract_fun(x)
> List with 4 elements
> Looking at leaf
> Looking at leaf
> Recursing into list
> List with 3 elements
> Looking at leaf
> [1] "leaf 1"  "leaf 2"  "<empty>"
>
>
>
> --
> Dirk Eddelbuettel | edd at debian.org | http://dirk.eddelbuettel.com
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20130816/74dacbb8/attachment.html>


More information about the Rcpp-devel mailing list