从sourceCpp迁移到包含Rcpp的包

pol*_*ist 13 c++ r rcpp

我目前有一个.cpp可以使用的文件sourceCpp().正如所料,创建了相应的R函数,代码按预期工作.

这里是:

#include <Rcpp.h> 
using namespace Rcpp;

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

    NumericVector outputVector = vectorOne + vectorTwo; 

    return outputVector;
}
Run Code Online (Sandbox Code Playgroud)

我现在将我的项目转换为使用的包Rcpp.所以我用rStudio创建了骨架,并开始研究如何将事物转换过来.

在Hadley 关于Cpp优秀入门书中,他在"在一个包中使用Rcpp"一节中说:

如果您的包使用Rcpp :: export属性,则需要在包构建过程中执行一个额外步骤.compileAttributes函数扫描包中的源文件以获取Rcpp :: export属性,并生成将函数导出到R所需的代码.

每当添加,删除函数或更改其签名时,都应重新运行compileAttributes.请注意,如果使用RStudio或devtools构建程序包,则会自动执行此步骤.

所以看起来编译的代码sourceCpp()应该像包中一样工作.

我创建了相应的R文件.

exampleOne <- function(vectorOne, vectorTwo){
    outToR <- .Call("exampleOne", vectorOne, vectorTwo, PACKAGE ="testPackage")
    outToR
}
Run Code Online (Sandbox Code Playgroud)

然后我(重新)构建了包,我得到了这个错误:

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

有没有人知道在使用sourceCpp()编译然后在包中使用它的代码时我还需要做什么?

我应该注意到我已经读过:"编写一个使用Rcpp的软件包" http://cran.rstudio.com/web/packages/Rcpp/vignettes/Rcpp-package.pdf,并了解其中的基本结构.但是,在查看RcppExamples源代码之后,看起来晕影中的结构与示例包中使用的结构不完全相同.例如,没有使用.h文件.插图和源代码也不使用[[Rcpp :: export]]属性.这一切都很难准确追踪我的错误.

pol*_*ist 9

这是我如何从使用sourceCpp()到使用Rcpp的包的"演练".如果有错误,请随时编辑或让我知道,我将编辑它.

[注意:我强烈建议在此过程中使用RStudio.]

因此,您可以轻松获取sourceCpp(),现在需要构建一个包.这并不难,但可能有点棘手,因为有关使用Rcpp构建软件包的信息范围从您想要的任何R软件包的详尽彻底的文档(但是作为新手高于你的头脑),以及新手敏感介绍(可能会遗漏您碰巧需要的细节).

在这里,我使用oneCpp.cpptwoCpp.cpp作为您将在包中使用的两个.cpp文件的名称.

这是我的建议:

A.首先,我假设您有一个theCppFile.cpp使用sourceCpp()编译的版本,并按预期工作.这不是必须的,但是如果您是Rcpp OR软件包的新手,那么在转移到下面更复杂的情况之前,确保您的代码在这种简单的情况下工作是很好的.

B.现在使用Rcpp.package.skeleton()或使用RStudio中的项目>创建项目>包w/Rcpp向导构建您的包(强烈推荐).您可以在[hadley/devtools] [1]或[Rcpp Attributes Vignette] [2]中找到有关使用Rcpp.package.skeleton()的详细信息.使用Rcpp编写软件包的完整文档在[编写一个使用Rcpp的软件包] [3],但是这个假设您已经很好地了解了C++,并且不使用新的"属性"方式来执行Rcpp.如果你转向制作更复杂的包,那将是非常宝贵的.

您现在应该有一个包的目录结构,如下所示:

yourPackageName
- DESCRIPTION
- NAMESPACE
- \R\
    - RcppExports.R 
- Read-and-delete-me
- \man\
    - yourPackageName-package.Rd
- \src\
    - Makevars
    - Makevars.win
    - oneCpp.cpp 
    - twoCpp.cpp
    - RcppExports.cpp
Run Code Online (Sandbox Code Playgroud)

设置好所有内容后,如果使用RStudio,或者compileAttributes()如果您不在RStudio中,请执行"构建和重新加载" .

C.您现在应该在\ R目录中看到一个名为的文件RcppExports.R.打开它并检查出来.在RcppExports.R您应该看到目录中所有.cpp文件的R包装函数\src.很甜蜜,嗯?

D)尝试与您编写的函数对应的R函数theCppFile.cpp.它有用吗?如果是这样的话.

E)现在你只需添加新的.cpp文件,如otherCpp.cpp\src你创建它们的目录.然后你只需重建包,就会生成并添加R包装器RcppExports.R.在RStudio中,这只是Build菜单中的"Build&Reload".如果你不使用RStudio,你应该运行compileAttributes()


Dir*_*tel 3

你只见树木,不见森林。

sourceCpp()是最近的函数;它是我们所谓的“Rcpp 属性”的一部分,它有自己的小插图(在包中、我的网站上和 CRAN 上具有相同的标题),您可能想阅读。其中详细介绍了如何将您编译和运行的内容转换sourceCpp()为包。这就是你想要的。

在文档之间随机跳转不会对您有帮助,并且在包作者提供的真正源文档的末尾可能会更好。或者换个说法:您正在使用一项新功能,但旧文档并未反映它。尝试用 Rcpp 编写一个基本包,即从另一端也可以访问它。

最后,还有一个邮件列表...