Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test Rcpp::CharacterVector elements for equality?

Tags:

r

rcpp

I am trying to write some simple Rcpp code examples. This is remarkably easy with the Rcpp and inline packages.

But I am stumped on how to test whether two character elements for equality. The following example compares the first elements of two character vectors. But I can't get it to compile.

What is the trick?

library(Rcpp)
library(inline)

cCode <- '
    Rcpp::CharacterVector cx(x);
    Rcpp::CharacterVector cy(y);
    Rcpp::LogicalVector r(1);
    r[0] = (cx[0] == cy[0]);
    return(r);
    '

cCharCompare <- cxxfunction(signature(x="character", y="character"), 
                            plugin="Rcpp", body=cCode)
cCharCompare("a", "b")

--

The comparison using == works perfectly fine if one of the two elements is a constant. The following code compiles and gives expected results:

cCode <- '
    Rcpp::CharacterVector cx(x);
    Rcpp::LogicalVector r(1);
    r[0] = (cx[0] == "a");
    return(r);
    '

cCharCompareA <- cxxfunction(signature(x="character"), plugin="Rcpp", body=cCode)

cCharCompareA("a")
[1] TRUE

cCharCompareA("b")
[1] FALSE
like image 445
Andrie Avatar asked Oct 24 '11 11:10

Andrie


1 Answers

The equality operator has been introduced in Rcpp 0.10.4. The implementation looks like this in the string_proxy class:

bool operator==( const string_proxy& other){
    return strcmp( begin(), other.begin() ) == 0 ;
}

So now we can write:

#include <Rcpp.h>
using namespace Rcpp ;

// [[Rcpp::export]]
LogicalVector test( CharacterVector x, CharacterVector y){
    Rcpp::LogicalVector r(x.size());
    for( int i=0; i<x.size(); i++){
        r[i] = (x[i] == y[i]);
    }
    return(r);
}

And something similar is used on our unit tests:

> test(letters, letters)
 [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[16] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
like image 104
Romain Francois Avatar answered Oct 22 '22 09:10

Romain Francois