Renaming and Hiding an Exported Rcpp function in an R Package
Asked Answered
P

2

8

Writing an R package, I have a R function that calls a specific Rcpp function. The Rcpp function just serves as a helper function and I do not want to creat a .Rd file for it. My solution so far is to export both functions in the Namespace file which causes the warning to create an .Rd file for the Rcpp function as soon as I run the check command. If I remove the helper function in the Namespace file, I get rid of this warning causing now the problem that the R function is not able to find it anymore.

Is there a way to solve this problem. That means to make the Rcpp function still visible for the R function and at the same time to get rid of the warning that there exists no .Rd file for the Rcpp function?

Thanks a lot :-)

Perot answered 4/9, 2017 at 14:24 Comment(1)
Perhaps you could not export it and call it explicitly via :::?Mackenie
F
11

Origin of the Registration Issue: the NAMESPACE file

I'm assuming that in your NAMESPACE file you have:

exportPattern("^[[:alpha:]]+") 

This basically "automatically" exports any function that begins with alphabet letter. Thus, your exported Rcpp function via // [[Rcpp::exports]] is being picked up.

To solve this, there are two solutions. The first is more of a "hack" and the second involves properly using export() in the NAMESPACE file.

Custom Naming the Rcpp Function

For the first solution, you can change how you export the Rcpp function explicitly stating how the function should appear in R. The important aspect of this name change, due to the configuration of the NAMESPACE registering all functions that start with an alphabetic letter, is to prefix to the function name a period (.), e.g.:

// [[Rcpp::export(".function_name")]]

As a real life example, take the function C++ function some_function():

// [[Rcpp::export]]
void some_function(int value)

The use of the Rcpp attributes here will export into R the function name some_function()

Now, to explicitly name the function something different for R would be:

// [[Rcpp::export(.some_function)]]
void some_function(int value)

which will be exported into R as .some_function(). Probably more illustrative is we could change it to be a completely different name, e.g.

// [[Rcpp::export(toad)]]
void some_function(int value)

This would mean the exported R function that calls the C++ function is toad().

Specify exports

The other approach that you may wish to take is to explicitly declare which function should be exported and which function should not be exported. To do this, the NAMESPACE file must be rid of the exportPattern("^[[:alpha:]]+") entry and each function that should be available must be specified as export(function). For example, the cIRT package's NAMESPACE has each function that should be "public" exported.

With this being said, a majority of users generate documentation with roxygen2. Under this documentation generator, you can specify in the roxygen2 tags, e.g. #' @tag or //' @tag, that the function should be exported into the NAMESPACE with:

# R code
#' @export

or

// C++ code
//' @export

Within the function documentation for C++ this would look like:

//' Title
//'
//' Description
//' 
//' @export

If you do not want a function exported, then all you have to do is not document it with //' @export.

Faithless answered 4/9, 2017 at 15:16 Comment(1)
My very personal and possibly unpopular opinion is to never allow tools like roxygen2 to mess with my NAMESPACE and DESCRIPTION files. Convenience is good, but control maybe be preferable.Rousing
R
7

There are two aspects here:

  1. Have the C++ function callable from R. You need the // [[Rcpp::export]] tag for that, and it will create an R interface.

  2. Have that R/C++ interface function 'visible' to clients of the package. That is different and controlled by NAMESPACE. Just do not list it there, only list your other function. You can still call it from the outside by using the colons: yourpackage:::yourCppFunction().

That way your C++ code is callable (per 1.) and does not need an Rd file (per 2. as it is not exported.) Only your visible R wrapper needs an man page entry.

For one worked example see this C++ file in the anytime package which is not in the NAMESPACE file, hence has no help page, yet is still callable to test code.

Rousing answered 4/9, 2017 at 14:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.