为我的 Rcpp 包添加依赖项

Add dependencies for my Rcpp package

Rcpp初学者的问题:

我想提高我在R中的执行效率。所以我在cpp中写了一些代码并使用Rcpp来帮助我编译它们。

问题是我在我的 .cpp 文件中使用了一些其他 R 包,我希望在用户安装我的包时自动安装和导入这些包。

例如如果我在我的文件中使用 R 包 'gtools',我不想出现错误:

* installing to library 'C:/Program Files/R/R-3.4.1/library'
* installing *source* package 'pkgname' ...
make: Nothing to be done for `all`.
** libs
installing to C:/Program Files/R/R-3.4.1/library/pkgname/libs/i386
** R
** preparing package for lazy loading
Error in library(gtools) : there is no package called 'gtools'
Error : unable to load R code in package 'pkgname'
ERROR: lazy loading failed for package 'pkgname'
* removing 'C:/Program Files/R/R-3.4.1/library/pkgname'

Exited with status 1.

我试图将依赖包名称添加到 DESCRIPTION 文件中。即

Imports: Rcpp (>= 0.12.12),gtools
LinkingTo: Rcpp, gtools

但它给了我以下错误:

ERROR: dependency 'gtools' is not available for package 'pkgname'

我没有找到任何类似的问题,如果有请告诉我。

首先,您可能应该确保 gtools 安装 在您的系统上。我这样说是因为以下错误:

Error in library(gtools) : there is no package called 'gtools'

话虽如此,您 运行 遇到的主要问题是 DESCRIPTION 文件中 LinkingTo:Imports: 字段之间的不确定性。 Section 1.1.3: Package Dependencies of Writing R Extensions.

中对此进行了介绍

具体来说,我们有:

The ‘Imports’ field lists packages whose namespaces are imported from (as specified in the NAMESPACE file) but which do not need to be attached. Namespaces accessed by the ‘::’ and ‘:::’ operators must be listed here, or in ‘Suggests’ or ‘Enhances’ (see below). Ideally this field will include all the standard packages that are used, and it is important to include S4-using packages (as their class definitions can change and the DESCRIPTION file is used to decide which packages to re-install when this happens). Packages declared in the ‘Depends’ field should not also be in the ‘Imports’ field. Version requirements can be specified and are checked when the namespace is loaded (since R >= 3.0.0).

LinkingTo 字段:

A package that wishes to make use of header files in other packages needs to declare them as a comma-separated list in the field ‘LinkingTo’ in the DESCRIPTION file. For example

LinkingTo: link1, link2

The ‘LinkingTo’ field can have a version requirement which is checked at installation.

Specifying a package in ‘LinkingTo’ suffices if these are C++ headers containing source code or static linking is done at installation: the packages do not need to be (and usually should not be) listed in the ‘Depends’ or ‘Imports’ fields. This includes CRAN package BH and almost all users of RcppArmadillo and RcppEigen.

For another use of ‘LinkingTo’ see Linking to native routines in other packages.

因此,Imports: 用于指定包含您希望导入的 R 函数的包。特别是,来自给定包或整个包本身的函数必须在 NAMESPACE 文件中指定。对于使用 Rcpp 的包,如果作者已从 C++ 导出例程,您通常可以期望 R 函数可用。

现在,关于 LinkingTo:,这更具体一些。如果作者希望通过 header 文件提供 C++ API,他们必须明确声明 [=43= 中给出的语句].通常,以这种方式进行的包是 "header-only"。这些软件包将 header 定义放在 inst/include 下,例如

|- pkgname
   |- inst/
      |- include/
         |- pkgname.h
   |- R/
   |- man/
   |- DESCRIPTION
   |- NAMESPACE

然而,另一个趋势是允许 "non-header" 包。这导致主题有点复杂,因为您必须了解共享 objects 和动态库。 CRAN 概述了 如何 "Link" 在 Section 5.8: Linking to other packages of Writing R Extensions

中打包

如果作者没有提供C++API,那么有四个选项:

  1. 作者 支持调用 C++ API 或提交允许访问 C++API.
  2. Call an R function from C++。 (尽管如此,这抵消了在 C++ 中编写代码所带来的任何性能提升。)
  3. 从作者的包中复制实现,同时尊重他们的知识属性。
  4. 从头开始实现所需的功能以避免许可问题。

不幸的是,gtools 就是这种情况。作为作者 do not provide a means to "link" to the C++ version of package's code.