【问题标题】:Upcoming NAMESPACE, Depends, Imports changes for 2.14.0 (some definitions/use please)即将到来的 2.14.0 的 NAMESPACE、Depends、Imports 更改(请提供一些定义/使用)
【发布时间】:2011-10-24 18:50:26
【问题描述】:

如果您是包作者,那么当我们在大约一周后迁移到 2.14 时,希望您能充分了解包结构即将发生的变化。其中一项更改是所有软件包都需要一个 NAMESPACE,如果您不创建一个,将为您生成一个(R 相当于您在美国的 Miranda 权利)。所以作为一个好公民,我试图弄清楚这一点。这是来自 R-exts 的部分:

1.6.5 总结——转换现有包

总而言之,将现有包转换为使用命名空间 涉及几个简单的步骤:

识别公共定义并将它们放在导出指令中。 识别 S3 风格的方法定义并编写对应的 S3method 声明。识别依赖关系并替换任何 require 调用 导入指令(并在 Depends 和 导入说明文件的字段)。替换 .First.lib 函数 使用 .onLoad 函数或 useDynLib 指令。

为了确保我在这里做正确的事,有人可以给出一个简短的明确定义/答案(我是否通过将几个小但相关的问题放在一起而违反了规则?)。所有答案都应考虑到 2.14,请:

  1. R 使用的 NAMESPACE 的定义
  2. 有没有办法在构建和检查之前生成一个 NAMESPACE,还是我们先 b/c 一次然后编辑自动创建的 NAMESPACE?
  3. DESCRIPTION 文件中“Depends:”和“Imports:”之间的区别。特别是,我为什么要将包放在“Depends:”而不是“Imports:”中,反之亦然?
  4. 听起来“require”不再被使用,尽管它没有这么说。这是正确的解释吗?

谢谢!

【问题讨论】:

    标签: r package packages


    【解决方案1】:

    我在https://github.com/hadley/devtools/wiki/Namespaces 写了一些关于这个主题的文章。

    回答您的问题:

    1. 见 Dirk 的回答。
    2. 使用 roxygen2
    3. 现在每个包都有一个命名空间,几乎没有理由使用 Depends。
    4. require 只能用于加载建议的包

    【讨论】:

    • 谢谢,维基很有帮助。
    【解决方案2】:

    CRAN 包从几乎不朽的时间开始就有了 NAMESPACE。只需选择一些您最喜欢的 CRAN 包并查看它们的 NAMESPACE 文件。

    它可以像从snow 中提取的单行(加评论)一样简单:

    # Export all names unless they start with a dot
    exportPattern("^[^.]")
    

    像往常一样运行R CMD check,在大多数情况下应该没问题。

    【讨论】:

    • 跟进 Dirk,关于 NAMESPACE 的作用:应该导出什么?我的猜测是大多数功能,但我找不到任何清楚说明这一点的地方。在下雪的例子中,他们选择隐藏 .functions 但所有其他的都是“用户可见的”? .functions 实际上也是用户可见的,对吧,如果您知道如何搜索?
    • 这是您作为维护者的设计决定。通常,您编写的所有内容都是为用户准备的,这就是通配符有很大帮助的原因。它获取所有以字母开头的内容,但仍允许您隐藏以点开头的标识符。
    • 请注意,我在这个主题上已经被激怒了(tolstoy.newcastle.edu.au/R/e13/devel/11/03/0651.html):“在生产代码中不使用 exportPattern()(至少,不适用于广泛定义的模式)被认为是一种好的做法:请参阅当前的“编写 R 扩展”。否则事情可能会发生变化(nlme 出口最近发生了变化,因此 import(nlme) 带来了什么)。“
    • 太有趣了,因为我引用了雪包 a) 就是这样做的,b) 有 R 核心成员作为主要作者:-)
    【解决方案3】:

    我将用我在将几个包切换到 R 2.14 后学到的一些细节来回答我自己的问题。

    上述手册中的描述给人的印象是,您在 Depends: for R 2.13 中的任何内容都应该移至 Imports: in R 2.14。您应该这样做,但它们在功能上并不是一对一的,我希望从下面的注释中可以清楚地看到。

    我们开始吧:

    取决于:可能仅用于限制版本,例如 'R >= 2.10' 或 'MASS > 0.1',在 R 2.14 下没有其他内容。

    拥有命名空间在一定程度上是一种通知用户可能存在名称冲突和“替换”的机制——换句话说,就是覆盖正在使用的名称。 NAMESPACE 文件必须在项目中匹配,并且为了描述中的 Imports: 字段。导入的函数名称等将列在 sessionInfo() 中的“通过命名空间加载(且未附加)”下。这些包已安装但未加载(即没有库(某些导入的包))。

    命名空间的另一个作用是让你的包“内部”可以使用函数。我的意思是,如果你的包使用了导入包中的函数,就会被找到。

    但是,当您在检查期间运行 .Rd 文件中的示例时,您曾经在 R 2.13 中的 Depends: 下但现在在 Imports: 在 R 2.14 下的包不可用。这是因为检查环境非常类似于在干净的环境中获取脚本(假设您使用的是 R --vanilla 所以 .Rprofiles 等尚未运行)。除非您在示例中添加 library(needed package) 语句,否则即使在 R 2.13 下它也不会在 R 2.14 下工作。因此,即使您的包 Imports: 所需的包,旧示例也不一定会运行,因为 Imports: 与 Depends: 不太一样(严格来说,它们是附加的但未加载)。

    如果有任何错误,请纠正我。非常感谢 Hadley Wickham 和其他帮助我的人!

    【讨论】:

      【解决方案4】:

      我最近为我的一个包做了这个。这是我的新 Depends、Imports 和 Suggests 行

      Depends: R (>= 2.15.0)
      Imports: nlme, mvtnorm, KFAS (>= 0.9.11), stats, utils, graphics
      Suggests: Hmisc, maps, xtable, stringr
      

      stats、utils 和 graphics 是 base R 的一部分,但用户可以分离它们,然后我的包将无法工作。如果您从命令行使用 R,您可能会想“为什么有人要分离它们?”。但是,如果用户正在使用 RStudio,比如说,我可以看到他们正在浏览并“取消点击”所有包。奇怪的事情,尽管如此,如果他们这样做,我不希望我的包裹停止工作。或者他们可能会重新定义,比如说,绘图函数(或其他一些函数),然后我的包就会失败。

      我的 NAMESPACE 然后有以下几行

      import(KFAS)
      import(stats)
      import(utils)
      import(graphics)
      

      我不想查看并跟踪我使用了哪些统计信息、实用程序和图形函数,因此我导入了它们的整个命名空间。对于 KFAS,我只需要 2 个函数,但是导出的函数名称在版本之间发生了变化,所以我导入了整个命名空间,然后在我的代码中测试用户拥有哪个版本。

      对于 mvtnorm 和 nlme,我只使用一个函数,所以我只导入那些函数。我可以导入整个命名空间,但尽量只导入我真正使用的东西。

      importFrom(mvtnorm, rmvnorm)
      importFrom(nlme, fdHess)
      

      出现 Suggests 包的小插曲有

      require(package)
      

      其中的行。

      对于我的 NAMESPACE 中的导出函数,我有点伤心。 CRAN 已变得严格,不允许在您的包代码中使用 :::。这意味着,如果我不导出函数,我将限制创意重用。另一方面,我理解只需要导出您打算使用稳定的 arg 列表维护的函数并输出,否则我们会通过更改函数接口来破坏彼此的包。

      【讨论】:

        猜你喜欢
        • 2012-01-28
        • 2018-12-28
        • 2014-12-13
        • 2014-04-18
        • 1970-01-01
        • 2013-04-21
        • 1970-01-01
        • 2016-12-08
        相关资源
        最近更新 更多