<div dir="ltr"><div><div><div>Hello Dirk,<br>Your modifications/corrections are VERY helpful, thank you! (also, thank you for the general kind words and ongoing support, they are much appreciated)<br><br></div><div>One more question/improvement - is it possible to have it return whatever value is inside the "label" attr?<br>

<br></div><div>For example, running the following would result in an error:<br></div></div><br>/*** R<br>x <- list(a = 1, b=2, 6)<br>attr(x[[2]], "leaf") = TRUE<br>attr(x[[2]], "label") = 2<br>extract_fun(x)<br>

</div><br>## output:<br><div>## <span class="">Error: expecting a string</span><span class="" style="border-collapse:separate;color:rgb(0,0,0);font-family:'Lucida Console';font-size:19px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:22px;text-indent:0px;text-transform:none;white-space:pre-wrap;word-spacing:0px;background-color:rgb(225,226,229)"></span><br>

/*<br><div><br><div>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)?<br></div><div>I thought that was what <br>        label = as<std::string>(x.attr( "label" )) ;<br>

</div><div>was doing - but apparently it does not coerce non-string into strings<br><br></div><div><br></div><div>Any suggestions?<br></div><div><br></div><div><br></div><div>Tal<br><br></div><div><br></div><div><br><br>
<br>
<br><br><div><br></div></div></div></div></div><div class="gmail_extra"><br clear="all"><div><div dir="ltr"><br>----------------Contact Details:-------------------------------------------------------<br>Contact me: <a href="mailto:Tal.Galili@gmail.com" target="_blank">Tal.Galili@gmail.com</a> |  <br>

Read me: <a href="http://www.talgalili.com" target="_blank">www.talgalili.com</a> (Hebrew) | <a href="http://www.biostatistics.co.il" target="_blank">www.biostatistics.co.il</a> (Hebrew) | <a href="http://www.r-statistics.com" target="_blank">www.r-statistics.com</a> (English)<br>

----------------------------------------------------------------------------------------------<br><br></div></div>
<br><br><div class="gmail_quote">On Fri, Aug 16, 2013 at 2:47 PM, Dirk Eddelbuettel <span dir="ltr"><<a href="mailto:edd@debian.org" target="_blank">edd@debian.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

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