Search code examples
rrcpp

How to check if a name exists in Rcpp List object?


Is it possible to check if a name exists in a List object that's passed to a function in Rcpp?

In base R this can be checked in the following manner:

"a" %in% names(foo)

albeit, noting the difficulties in such an approach (here). Is there an equivalent approach for an Rcpp function? Thanks.


Solution

  • Here is a very simple first pass. You can use STL members of vectors of string for the matches too and more.

    Code

    #include <Rcpp.h>                                                                                                                                             
                                                                                                                                                                  
    // [[Rcpp::export]]                                                                                                                                           
    bool contains(std::string s, Rcpp::List L) {                                                                                                                  
        Rcpp::CharacterVector nv = L.names();                                                                                                                     
        for (int i=0; i<nv.size(); i++) {                                                                                                                         
            if (std::string(nv[i]) == s) {                                                                                                                        
                return true;                                                                                                                                      
            }                                                                                                                                                     
        }                                                                                                                                                         
        return false;                                                                                                                                             
    }                                                                                                                                                             
                                                                                                                                                                  
    /*** R                                                                                                                                                        
    l <- list(aa="a", bb=1.23, cc=LETTERS[1:4])                                                                                                                   
    contains("aaa", l) # false                                                                                                                                    
    contains("bb", l)  # true                                                                                                                                     
    */
    

    Output

     > Rcpp::sourceCpp("~/git/stackoverflow/68397853/answer.cpp")                                                                                                 
                                                                                                                                                                  
     > l <- list(aa="a", bb=1.23, cc=LETTERS[1:4])                                                                                                                
                                                                                                                                                                  
     > contains("aaa", l) # false                                                                                                                                 
     [1] FALSE                                                                                                                                                    
                                                                                                                                                                  
     > contains("bb", l)  # true                                                                                                                                  
     [1] TRUE                                                                                                                                                     
     >    
    

    I have a vague feeling I may have answered a similar question before, and/or written similar helper functions. Anyway, takes about a minute to do a simple one so if in doubt just do it.