I have 2 files, Rfile.R and Cppfile.cpp.
Contents in Cppfile.cpp:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
int CPPF(int k){return ++k;}
Contents in Rfile.R:
RF<-function(k){return(CPPF(k))}
I want to build an R package based on the 2 files. I use the lastest versions of Rstudio and Roxygen2.
I tried 3 ways to build the package with or without Roxygen2, and had different results:
New Project->New Directory->R package->Type:Package w/Rcpp, add both Rfile.R and Cppfile.cpp as source files. Build & reload, everything works out fine. The functions work as they do.
New Project->New Directory->R package->Type:Package w/Rcpp, add both Rfile.R and Cppfile.cpp as source files. Select "Generate documentations with Roxygen", check all its options. Build & Reload, the functions don't work. Inputting "RF" gives the contents of RF, inputting "CPPF" pops "Object not found".
New Project->New Directory->R package->Type:Package w/Rcpp, add only Cppfile.cpp as source files. Select "Generate documentations with Roxygen", check all its options. Build & Reload, the function works.
Then copy Rfile.R directly into the project folder->R folder. Build & Reload, everything fine, functions work well.
Am I using the Roxygen wrong or Roxygen has bugs? I need it to document. I can stick to the 3rd way which cost me much energy to find, but wired.
Thanks!
One Way To Solve The Issue:
When selecting "Generate documentations with Roxygen", Don't check "NAMESPACE file" option.
You're mixing up two things (which are easy to mix up, unfortunately):
First, the // [[Rcpp::export]] attribute is used for auto-generating wrapper functions in two files, RcppExports.cpp and RcppExports.R. A wrapper R function, CPPF, will be auto-generated by Rcpp::compileAttributes() here, and placed into R/RcppExports.R.
Second, roxygen comments can be used to manage the NAMESPACE, e.g. with the #export tag. Note that this is different from // [[Rcpp::export]]!
The auto-generated function is not automatically exported. The Rcpp.package.skeleton() will generate a NAMESPACE file that automatically exports all functions of a given name; ie, the exportPattern("^[[:alpha:]]+") entry. This is good enough for small packages; but as your package gets more complicated you will want more fine-grained control over your namespace. Or you can just adopt a convention where all internal, non-exported functions begin with a .. Either way, this mechanism is what allows the auto-generated function to be exported to your package namespace.
If you want to use roxygen to manage the NAMESPACE, you need to add roxygen comments to your C++ functions if you want them to be exported in the namespace. So you could modify your function as the following:
#include <Rcpp.h>
using namespace Rcpp;
//' #export
// [[Rcpp::export]]
int CPPF(int k){return ++k;}
Note that you might have to run roxygen2::upgradeRoxygen() to ensure that roxygen2 takes over the NAMESPACE, for new versions of roxygen2.
So if 2. does not work, file it as a (reproducible) bug report with the roxygen2 team.
I see no Rcpp issue; it is possible that something went wrong with the Imports: / NAMESPACE declaration. I see no Rcpp issue here (as 1. works fine).
FWIW I also use roxygen2 on some packages, and I too build them from time to time in RStudio.
Related
When I do a package including some C code or using Rcpp, I type the roxygen code:
#' #useDynLib TheDLL, .registration=true
I did a package in which I included some DLLs created with Haskell, that I put in the inst/libs folder. I didn't type .registration=true in the roxygen code and the package works fine. Should I type it nevertheless? If so, what is the role of .registration=true?
I think you almost certainly shouldn't use it in a general-purpose DLL, but if the DLL was written specifically for R, maybe you should. It indicates that the dll calls R_registerRoutines from its R_init_DLLNAME function, so entry points can be saved into variables. For example, you might have a function named "foo". You can call it using
.Call("foo", ...)
without registering it, and R will need to search symbol tables for it at run time. Or you can register it and call it as
.Call(foo, ...)
and the search is unnecessary. This is discussed mainly in section 5.4.2 of "Writing R Extensions". I believe that if you specify .registration=true then R will use the registration information to find entry points, otherwise it needs to search through all the exports of the DLL, which is probably slower.
I am looking for a fast R solution to read a package NAMESPACE file. The solution should contain already preprocessed (and aggregated) records and separated imports and exports.
Unfortunately I can’t use getNamespaceExports("dplyr")/getNamespaceImports("dplyr") as they need the package to be loaded to the R session, which is too slow.
I need a solution which simply process a text from the NAMESPACE file. Any solutions using external packages as well as partial solutions would still be welcome.
The raw data we could grabbed with a call like readLines("https://raw.githubusercontent.com/cran/dplyr/master/NAMESPACE"). roxygen2 generated files are formatted properly, but this will be not true for all manually generated files.
EDIT:
Thanks to Konrad R. answer I could develop such functionality in my new CRAN package - pacs. I recommended to check pacs::pac_namespace function. There is even one function which goes one step further, comparing NAMESPACE files between different package versions pacs::pac_comapre_namespace.
The function is included in R as base::parseNamespaceFile. Unfortunately the function does not directly take a path as an argument. Instead it constructs the path from a package name and the library location. However, armed with this knowledge you should be able to call it; e.g.:
parseNamespaceFile('dplyr', .libPaths()[1L])
EDIT
Somebody has to remember that the whole packages imports (like import(rlang)) have to be still invoked with the same function and the exports for them extracted. Two core elements are using parse on NAMESPACE code and then using the recursive extract function parseDirective.
I have an Rcpp module in my package which, as well as exposing the class, exposes a number of methods. Is it possible to document the methods (on the C++ side) using roxygen2? My module looks like this:
RCPP_MODULE(BayesFst) {
using namespace Rcpp;
class_<BayesFst>( "BayesFst")
.default_constructor("Standard constructor")
.method("printData", &BayesFst::printData)
.method("printCounts", &BayesFst::printCounts)
.method("printInitialPvals", &BayesFst::printInitialPvals)
.method("printFstSummary", &BayesFst::printFstSummary)
.method("run", &BayesFst::run)
.method("setData", &BayesFst::setData)
.method("setPriorParameters", &BayesFst::setPriorParameters)
.method("setRunParameters", &BayesFst::setRunParameters)
.method("ldiriTest", &BayesFst::ldiriTest)
.property("interaction", &BayesFst::getInteraction, &BayesFst::setInteraction)
;
}
I would like to document all of these methods ideally. A simple idea is to hide the class behind wrapper functions and then call the methods from within R wrapper functions, but this feels kind of inelegant to me.
I have tried adding the roxygen comment lines to the functions, but because they don't get exported in the same way the documentation doesn't seem to get picked up.
You will not be able to rely on Rcpp to carry the roxygen documentation over the way compileAttributes() would ... as you are not invoking compileAttributes().
Feel free to construct (and test and then contribute :) a new helper function; otherwise I would just use roxygen in an R file and proceed from there.
Edit: I also filed an issue so that we don't forget about it.
I am receiving an error [could not find function "str_trim"] when I run check() on an R package I am developing. I have since added two things:
1) In DESCRIPTION
Imports: stringr
2) In NAMESPACE
importFrom(stringr,str_trim)
However, when I then run install() and document(), then the line in NAMESPACE is removed. Then, when I again run check(), I receive the original error.
Why is this line being removed? Should I try a different approach, and if so, what kind of approach? Thank you!
It seems you are doing package development "the Hadley way".
Hadley wants you to use roxygen (i.e. the roxygen2 package but that should be automatic if you use his 'devtools').
Then, the roxygen "magic" is used to auto-write your NAMESPACE file... and so also destroys things you've put there.
You must add #importFrom .... statements to your R/*.R files if you want to use roxygen.
I agree with many things Hadley advocates; the wholesale use of 'roxygen' is not among them however.
I want good, carefully maintained help files with \link{}s, \eqn{}, etc etc
-> I edit my man/*.Rd files and I manually build NAMESPACE (so it ends up looking well organized, I can also add comments there, and I can even use
if(getRVersion() >= "3.2.0") { ...... } in the NAMESPACE file, something that's not easily possible with roxygen.
I would like to write a C++ function with Rcpp that uses a C function found in the package hypred, which is on CRAN here.
I read using C function from other package in Rcpp, but don't understand if this applies for me and if it would apply, what to do.
The desired function is in the the source file /src/hypredRoutines.c and is called meiosisFUNAllChr.
What I so far did based on this SO question here is:
I separated the function meiosisFUNAllChr from the rest of the code and placed it in a new file called meiosisFUNAllChr.c.
I created a header file called meiosisFUNAllChr.h containing:
#ifndef MEIOSISFUNALLCHR_H
#define MEIOSISFUNALLCHR_H
void meiosisFUNallChr (...);
#endif
Compiled it with
gcc -c -o meiosisFUNAllChr.o meiosisFUNAllChr.c
Created a dummy c++ function
#include <Rcpp.h>
using namespace Rcpp;
extern "C" {
#include "meiosisFUNallChr.h"
}
// [[Rcpp::export]]
int timesTwo(int x) {
return x * 2;
}
At this point, compiling with sourceCpp does not work. Can you show me how to get it working?
Many Thanks!
EDIT
Compiling with sourceCpp gives me:
meiosisFUNallChr.h: file or directory not found
hypred registers its two functions, at the R level you can get hold of the one you want like this:
xp <- getDLLRegisteredRoutines( getLoadedDLLs()[["hypred"]] )[[".C"]][["meiosisFUNallChr"]]$address
I believe you can then access the function pointer in C++ like this:
DL_FUNC meiosisFUNallChr = reinterpret_cast<DL_FUNC>( R_ExternalPtrAddr(xp) ) ;
But you'd be better off negotiating with the package authors that they implement this scheme if you can make a case that you really need to be calling the C function directly.
Briefly:
You want to use another source file (presumably available under a suitable license).
You want to call it from a new file of yours.
So you already have two files.
By now the alarm bells should go off that you really, really, want to create a package.
Which the Rcpp documentation details in many places. And there are 340+ packages on CRAN using Rcpp, many doing this very issue of calling a C file too. Pick one or two, study their structure; also pick one or two created by the fully documented Rcpp tools such as Rcpp.package.skeleton() and things should become a lot clearer.
Edit: Obviously, this approach only needs to be taken if the other package does not export its function. If you can get its author to export, use that as mention in Romain's answer. Pairs of packages that export/use are zoo/xts, xts/RcppXts, expm/RcppKalman (not on CRAN), RApiSerialize/RcppRedis, ...