[Rcpp-devel] A clean way to handle character/strings between R and Rcpp

Iñaki Ucar iucar at fedoraproject.org
Sat Apr 3 16:55:25 CEST 2021


On Sat, 3 Apr 2021 at 16:28, prezzemolo <prezzemolo at ctemplar.com> wrote:
>
> Hey.
>
> I am wondering if there's some general guidance on what the 'right' options are to cleanly handle character arguments passed from R to Rcpp.
>
> It is all rather simple: let's say I have a human-readable argument vector c("tree", "herb", "shrub") [It could also be a factor in R], which I can send to an Rcpp function along with other arguments for evaluation.
> What would be the cleanest way to define those arguments (plant types) in R to then have as little trouble sending them over to Rcpp for use in cases like if() statements?

You can use the == operator with standard strings:

Rcpp::cppFunction('
void test(std::string x) {
  if (x == "flower")
    Rcout << "flower" << std::endl;
  else if (x == "tree")
    Rcout << "tree" << std::endl;
  else
    Rcout << "string " << x << " not found" << std::endl;
}
')

test("flower")
#> flower
test("tree")
#> tree
test("other")
#> string other not found


Iñaki


>
>
> The use of enums comes to mind:
>
> // beginningoffile
> enum class var_type { flower, tree };
>
> RCPP_EXPOSED_ENUM_NODECL(var_type)
>
> // [[Rcpp::export]]
> int charHandle1(var_type text_arg = var_type::flower) {
>  if(text_arg == var_type::flower) {
>   Rcout << static_cast<int>(text_arg) << " says '0 (flower)'.\n";
>  } else if(text_arg == var_type::tree) {
>   Rcout << static_cast<int>(text_arg) << " says '1 (tree)'.\n";
>  }
>  return 0;
> }
> // endoffile
>
> This however, doesn't seem to work. I understand R would have to know the var_type for it to work.
> Then I can do it simply by comparing the const char * argument. This will work, but the strcmp() comparison isn't very straightforward for someone who doesn't know C++ (and perhaps for some other reasons).
>
> // [[Rcpp::export]]
> int charHandle2(const char* text_arg = "flower") {
>  if(strcmp(text_arg, "flower") == 0) {
>   Rcout << text_arg << " says 'flower'.\n";
>  } else if(strcmp(text_arg, "tree") == 0) {
>   Rcout << text_arg << " says 'tree'.\n";
>  }
>  return 0;
> }
>
> I am looking for some good practice guidance on how to handle this safely and legibly to avoid sending people to function definitions. An argument could be made, for instance, that a list of plant type used as function arguments could be stored as factor in R and then sent and used in some way in Rcpp. What other options are there? To my best knowledge, support for enums is limited - I glanced over the vignettes and couldn't find any significant mention of enums (or factors, really), so I guess some other way of handling such cases should be taken. Has anyone dealt with such cases and has recommendations?
>
> Regards,
> Angelo (Greetings from Genoa)
> _______________________________________________
> Rcpp-devel mailing list
> Rcpp-devel at lists.r-forge.r-project.org
> https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel



-- 
Iñaki Úcar


More information about the Rcpp-devel mailing list