【问题标题】:How do I transition from using C++ with inline to making my own R package?如何从使用内联 C++ 过渡到制作自己的 R 包?
【发布时间】:2014-07-30 00:56:34
【问题描述】:

这里发生了两件事:(1)我只是在学习如何使用 Rcpp 和朋友们来使我的 R 代码更快,(2)我以前从未构建过 R 包。

我已经使用inline down。很棒的包裹。爱它。但是,我似乎无法使用使用inlinepackage.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 )
}

第 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')

然后删除 man/*.Rd 文件,因为 R 没有设置“正常工作”的默认值。

$ rm inlineExample/man/*.Rd

然后运行:

$ R CMD build inlineExample/
<< snip >> 
$ R CMD check inlineExample_1.0.tar.gz 
<< snip >>
$ R CMD INSTALL inlineExample_1.0.tar.gz 
<< snip >>

除了一些抱怨缺少文档外,所有这些都成功完成。

第 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"

失败了。在我未经训练的眼睛看来:

  1. inline 编译的代码从未被 *.package.skeleton 复制到目录骨架的“右侧”部分,以供 R 构建过程稍后编译,并且
  2. 'code_files' 参数未能导致 R 在加载包时获取这些 *.R 文件。

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

并且(1)在技术上似乎是可行的,但作为discussed on the Rcpp mailing list,实现一组自动魔术转换器功能是不值得的。

那么问题来了:

有人可以介绍一下获取提供的示例代码并将其转换为 R 包的正确方法吗?

对我来说,理解现有文档有点新鲜。 FWIW,我相信这对未来的人们会有帮助!

【问题讨论】:

    标签: r package inline rcpp


    【解决方案1】:

    第 1 步:编写一个不带 Rcpp 的虚拟包,发送至 get a feel for how things work

    第 2 步:阅读 Dirk 的 explanation of how to make a package that uses Rcpp

    从我读到的inline 看来,包中的 Rcpp 变得更难而不是更容易。

    【讨论】:

    • +1 -- 我们应该将内联视为包构建的替代(在“让我首先以交互方式工作”的意义上),而不是第一步朝着它。因此,一旦您的代码准备就绪,请考虑打包。并以全新的方式思考,不要被您使用内联创建的内容所束缚。
    • 很公平。我会一次做一个,并听取德克关于重新思考的建议。谢谢你让我直截了当。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-21
    • 1970-01-01
    • 1970-01-01
    • 2011-07-03
    • 2019-03-08
    • 2015-05-29
    • 1970-01-01
    相关资源
    最近更新 更多