[Rcpp-devel] Testing for existence of named components
Ulrich Bodenhofer
bodenhofer at bioinf.jku.at
Wed Mar 28 15:17:38 CEST 2012
Thanks for your swift reply, Dirk! Wow, to be frank, that is not what I
was expecting. In the meantime, I read Section 5.9.6 of "Writing R
extensions" and I was stunned to see a solution there that is similar to
the one you propose. I do not know R internals very well, but I cannot
believe that accesses by names are implemented by tediously searching
through all names sequentially. There must be some hash table behind,
right? Otherwise, list accesses would be terribly slow. If all my
assumptions are right, I wonder why the R API does not make this
mechanism available.
May I add one more question: where can I find the definition of the List
class and the implementation of its methods in the Rcpp package source
code? I was looking for this, but got lost. Are you using the method
described in Section 5.9.6 of "Writing R extensions" (which I doubt) or
something else. I would actually be quite curious to learn more about
how lists are implemented in Rcpp.
Thanks and best regards,
Ulrich
If so, I wonder why this mechanism has not been
On 03/28/2012 02:56 PM, Dirk Eddelbuettel wrote:
> On 28 March 2012 at 13:56, Ulrich Bodenhofer wrote:
> | My question is the following: is there any way of checking in whether a
> | component of an Rcpp list (or vector) with a given name exists in this list. If
> | I simply try accessing a non-existing component, I get an "index out of bounds"
> | error. Trying to catch a possible exception did not work either. I also browsed
> | the Rcpp package source code, but unfortunately I got lost. Sorry if this has
> | been addressed on this list before. At least I googled in many different ways,
> | but could not find anything. Any ideas? Any help is gratefully appreciated!
>
> Good question, and I have the suspicion that we answered that years ago on
> the list before.
>
> Here is a super-pedestrian version. It takes a list, extracts its names() --
> and should probably test whether names is empty ? -- and then compares these
> against a vector of tokens, returning a bool for each token:
>
> R>
> R> suppressMessages(library(inline))
> R>
> R> f<- cxxfunction(signature(ls="list", ts="character"), plugin="Rcpp", body='
> + Rcpp::List lst(ls);
> + Rcpp::CharacterVector nam = lst.names();
> + std::vector<std::string> nm = Rcpp::as< std::vector< std::string> >(nam);
> + int m = nam.size();
> +
> + Rcpp::CharacterVector tok(ts);
> + std::vector<std::string> tk = Rcpp::as< std::vector< std::string> >(tok);
> + int n = tok.size();
> +
> + Rcpp::LogicalVector log(n);
> +
> + for (int i=0; i<n; i++) { // look at all tokens
> + log[i] = false; // assume false, but compare to all names
> + for (int j=0; j<m; j++) {
> + log[i] = (tk[i] == nm[j]); // and note equality if we find it
> + }
> + }
> + return log;
> + ')
> R> ll<- list(aa=1,b="b") ## list with names 'aa' and 'b'
> R> f(ll, c("aa", "b", "c")) ## does it contain 'a' or 'b' or 'c' ?
> [1] FALSE TRUE FALSE
> R> f(ll, "c") ## works with scalars too
> [1] FALSE
> R>
>
> I am sure there is a much cleverer solution one could write...
>
> Dirk
>
More information about the Rcpp-devel
mailing list