15

I currently have a .cpp file that I can compile using sourceCpp(). As expected the corresponding R function is created and the code works as expected.

Here it is:

#include <Rcpp.h> 
using namespace Rcpp;

// [[Rcpp::export]]
NumericVector exampleOne(NumericVector vectorOne, NumericVector vectorTwo){

    NumericVector outputVector = vectorOne + vectorTwo; 

    return outputVector;
}

I am now converting my project over to a package using Rcpp. So I created the skeleton with rStudio and started looking at how to convert things over.

In Hadley's excellent primer on Cpp, he says in section "Using Rcpp in a Package":

If your packages uses the Rcpp::export attribute then one additional step in the package build process is requried. The compileAttributes function scans the source files within a package for Rcpp::export attributes and generates the code required to export the functions to R.

You should re-run compileAttributes whenever functions are added, removed, or have their signatures changed. Note that if you build your package using RStudio or devtools then this step occurs automatically.

So it looks like the code that compiled with sourceCpp() should work pretty much as is in a package.

I created the corresponding R file.

exampleOne <- function(vectorOne, vectorTwo){
    outToR <- .Call("exampleOne", vectorOne, vectorTwo, PACKAGE ="testPackage")
    outToR
}

Then I (re)built the package and I get this error:

Error in .Call("exampleOne", vectorOne, vectorTwo, PACKAGE = "voteR") : C symbol name "exampleOne" not in DLL for package "testPackage"

Does anyone have an idea as to what else I need to do when taking code that compiles with sourceCpp() and then using it in a package?

I should note that I have read: "Writing a package that uses Rcpp" http://cran.rstudio.com/web/packages/Rcpp/vignettes/Rcpp-package.pdf and understand the basic structure presented there. However, after looking at the RcppExamples source code, it appears that the structure in the vignettes is not exactly the same as that used in the example package. For example there are no .h files used. Also neither the vignette nor the source code use the [[Rcpp::export]] attribute. This all makes it difficult to track down exactly where my error is.

Romain Francois
  • 17,432
  • 3
  • 51
  • 77
politicalEconomist
  • 1,041
  • 1
  • 14
  • 19
  • If you're using `compileAttributes` correctly, you don't need to create the R functions yourself. But a lot depends on how you're creating the package - the package development tools in RStudio and in (the development version of) devtools will take care of most of the details for you. – hadley Jan 12 '13 at 17:10
  • My vote is still for doing it by hand and understanding what happens---just start with `rcpp.package.skeleton()` which *does* have an option for use with Attributes. – Dirk Eddelbuettel Jan 12 '13 at 17:56
  • Thanks to both of you. I dumped "my" version of the R file after realizing, just as Hadley said, that the RcppExports.R file contained all of the corresponding R functions (thanks to the ["Attributes" Vignette](http://dirk.eddelbuettel.com/code/rcpp/Rcpp-attributes.pdf.)) The error is gone now. By trying to create my own version of the R file it was somehow screwing things up (the shared library maybe?). – politicalEconomist Jan 12 '13 at 19:53
  • I think for my purposes the RStudio path is best for now. Building from scratch invites too many places for me to make a mistake when applying the general information in "Writing a package that uses Rcpp" to my code. All of the code there uses the "pre-attribute" way of doing things. Also all the stuff about .h files is a mystery to me at my current level of understanding of C++. Thanks again for the amazing resources you guys are providing. – politicalEconomist Jan 12 '13 at 19:54

3 Answers3

11

Here is my "walk through" of how to go from using sourceCpp() to a package that uses Rcpp. If there is an error please feel free to edit this or let me know and I will edit it.

[NOTE: I HIGHLY recommend using RStudio for this process.]

So you have the sourceCpp() thing down pat and now you need to build a package. This is not hard, but can be a bit tricky, because the information out there about building packages with Rcpp ranges from the exhaustive thorough documentation you want with any R package (but that is above your head as a newbie), and the newbie sensitive introductions (that may leave out a detail you happen to need).

Here I use oneCpp.cpp and twoCpp.cpp as the names of two .cpp files you will use in your package.

Here is what I suggest:

A. First I assume you have a version of theCppFile.cpp that compiles with sourceCpp() and works as you expect it to. This is not a must, but if you are new to Rcpp OR packages, it is nice to make sure your code works in this simple situation before you move to the more complicated case below.

B. Now build your package using Rcpp.package.skeleton() or use the Project>Create Project>Package w/Rcpp wizard in RStudio (HIGHLY recommended). You can find details about using Rcpp.package.skeleton() in hadley/devtools or Rcpp Attributes Vignette. The full documentation for writing packages with Rcpp is in Writing a package that uses Rcpp, however this one assumes you know your way around C++ fairly well, and does not use the new "Attributes" way of doing Rcpp. It will be invaluable though if you move toward making more complex packages.

You should now have a directory structure for your package that looks something like this:

yourPackageName
- DESCRIPTION
- NAMESPACE
- \R\
    - RcppExports.R 
- Read-and-delete-me
- \man\
    - yourPackageName-package.Rd
- \src\
    - Makevars
    - Makevars.win
    - oneCpp.cpp 
    - twoCpp.cpp
    - RcppExports.cpp

Once everything is set up, do a "Build & Reload" if using RStudio, or compileAttributes() if you are not in RStudio.

C. You should now see in your \R directory a file called RcppExports.R. Open it and check it out. In RcppExports.R you should see the R wrapper functions for all the .cpp files you have in your \src directory. Pretty sweet, eh?.

D) Try out the R function that corresponds to the function you wrote in theCppFile.cpp. Does it work? If so move on.

E) You can now just add new .cpp files like otherCpp.cpp to the \src directory as you create them. Then you just have to rebuild the package, and the R wrappers will be generated and added to RcppExports.R for you. In RStudio this is just "Build & Reload" in the Build menu. If you are not using RStudio you should run compileAttributes()

B.Gao
  • 146
  • 1
  • 8
politicalEconomist
  • 1,041
  • 1
  • 14
  • 19
4

In short, the trick is to call compileAttributes() from within the root of the package. So for instance for package foo

$ cd /path/to/foo
$ ls
DESCRIPTION  man  NAMESPACE  R  src
$ R
R> compileAttributes()

This command will generate the RcppExports.cpp and RcppExports.R that were missing.

Calimo
  • 7,510
  • 4
  • 39
  • 61
3

You are missing the forest for the trees.

sourceCpp() is a recent function; it is part of what we call "Rcpp attributes" which has its own vignette (with the same title, in the package, on my website, and on CRAN) which you may want to read. It among other things details how to turn something you compiled and run using sourceCpp() into a package. Which is what you want.

Randomly jumping between documentation won't help you, and at the end of the genuine source documentation by package authors may be preferable. Or to put a different spin on it: you are using a new feature but old documentation that doesn't reflect it. Try to write a basic package with Rcpp, ie come to it from the other end as well.

Lastly, there is a mailing list...

Dirk Eddelbuettel
  • 360,940
  • 56
  • 644
  • 725