如何从使用内联的C++过渡到制作自己的R包?

Nat*_*nos 9 r inline package rcpp

这里有两件事:(1)我正在学习如何使用Rcpp和朋友来更快地制作我的R代码;(2)我之前从未构建过R包.

我已经使用了inlinedown.很棒的套餐.爱它.但是,我似乎无法使用inlinewith 开发的任何代码package.skeleton来制作R包.

这是一个最小的例子:

第1步:制作R脚本

#############################
# File : build-R-pacakge.R  #
#############################
require(inline)
require(Rcpp)
require(RcppArmadillo)

# Define a simple cxxfunction
plus.two.cpp.src <- '
    arma::mat U = Rcpp::as<arma::mat>(UmatrixR);
    return(Rcpp::wrap(U+2));
'
plus.two.cpp <- cxxfunction(
             signature(UmatrixR="numeric"),
             body=plus.two.cpp.src,
             plugin="RcppArmadillo")

# Define the analogous R function
plus.two.r <- function( x ) {
  return( x + 2 )
}
Run Code Online (Sandbox Code Playgroud)

第2步:将其构建为R包

在新的R会话运行中:

source('build-R-package.R')
RcppArmadillo.package.skeleton(name='inlineExample',
                 list=c('plus.two.cpp', 'plus.two.r'),
                 code_files='build-R-package.R')
Run Code Online (Sandbox Code Playgroud)

然后删除man/*.Rd文件,因为R没有放入"正常工作"的默认值.

$ rm inlineExample/man/*.Rd
Run Code Online (Sandbox Code Playgroud)

并运行:

$ R CMD build inlineExample/
<< snip >> 
$ R CMD check inlineExample_1.0.tar.gz 
<< snip >>
$ R CMD INSTALL inlineExample_1.0.tar.gz 
<< snip >>
Run Code Online (Sandbox Code Playgroud)

哪一切都成功完成,除了一些抱怨缺少文档.

第3步:尝试一下

然后在新的R会话中尝试:

> require(inlineExample)
Loading required package: inlineExample
Loading required package: Rcpp
Loading required package: RcppArmadillo
Loading required package: inline
>
> plus.two.cpp( matrix(1:12, ncol=3))
Error in .Primitive(".Call")(<pointer: (nil)>, UmatrixR) : 
  NULL value passed as symbol address
>
> plus.two.cpp
An object of class "CFunc"
function (UmatrixR) 
.Primitive(".Call")(<pointer: (nil)>, UmatrixR)
<environment: 0x2f28370>
Slot "code":
[1] "\n// includes from the plugin\n#include <RcppArmadillo.h>\n#include <Rcpp.h>\n\n\n#ifndef BEGIN_RCPP\n#define BEGIN_RCPP\n#endif\n\n#ifndef END_RCPP\n#define END_RCPP\n#endif\n\nusing namespace Rcpp;\n\n\n// user includes\n\n\n// declarations\nextern \"C\" {\nSEXP file2f8c4cc10657( SEXP UmatrixR) ;\n}\n\n// definition\n\nSEXP file2f8c4cc10657( SEXP UmatrixR ){\nBEGIN_RCPP\n\n  arma::mat U = Rcpp::as<arma::mat>(UmatrixR);\n  return(Rcpp::wrap(U+2));\n\nEND_RCPP\n}\n\n\n"
Run Code Online (Sandbox Code Playgroud)

它失败.对于我未经训练的眼睛,似乎:

  1. inline编译的代码永远不会被*.package.skeleton复制到目录框架的"右"部分,以便以后通过R构建过程进行编译,并且
  2. 失败的是'code_files'参数不会导致R在加载包时使用那些*.R文件.

进一步考虑这一点,似乎(2)会是一个非常糟糕的主意,因为它会强制用户在每次加载包时编译代码.这将排除所有只需要二进制包的用户,而且只是非常低效.

并且(1)在技术上似乎是可能的,但正如在Rcpp邮件列表中讨论的那样,不值得实现一组自动魔术转换器功能.

那么,问题是:

有人可以直接了解正确的方法来获取提供的示例代码并将其转换为R包吗?

对于理解现有文档,我有一点太新的意义.FWIW,我相信它对未来的人们会有所帮助!

Ari*_*man 10

第1步:编写一个没有Rcpp的虚拟包,只是为了了解工作原理.

第2步:阅读Dirk 关于如何制作使用Rcpp的包的说明.

从我所读到的内容inline看来,使包装中的Rcpp变得更加容易.

  • +1 - 我们应该将内联视为包装构建的另一种选择(在"让我得到一些先交互作用的东西"的意义上),而不是迈向它的第一步.因此,一旦您的代码准备就绪,请考虑打包.并且在不使用内联创建的内容限制自己的情况下进行全新思考. (4认同)