本文介绍了开发一套依赖 R 包的最佳实践的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开始研究一系列 R 包,所有这些包都共享大量的公共代码,这些代码都存放在自己的包中,我们称之为 myPackageUtilities.所以我有几个包

I am starting to work on a family of R packages, all of which share substantial common code which is housed in its own package, lets call it myPackageUtilities. So I have several packages

myPackage1myPackage2 等...

所有这些包都依赖于 myPackageUtilities 中的每个方法.有关真实示例,请参阅 statnet on CRAN.这个想法是未来的开发人员可能会创建 myPackageN,而不必重新编写/复制所有支持代码,这个未来的开发人员可以简单地使用 mypackageUtilities 来获取开始了.

All of these packages depend on every method in myPackageUtilities. For a real-world example, please see statnet on CRAN. The idea is that a future developer might create myPackageN, and instead of having to re-write/duplicate all of the supporting code, this future developer can simply use mypackageUtilities to get started.

有并发症:

1) 部分 mypackageUtilities 中的代码供最终用户使用,其余的则用于内部开发目的.最终用户代码需要使用 roxygen2 正确记录.此代码包括 S3 类和泛型,以及用户的各种帮助函数.

1) Some of the code in mypackageUtilities is intended for end-users, and the rest is for internal development purposes. The end-user code needs to be properly documented using roxygen2. This code includes both S3 classes and generics, as well as various helper functions for the user.

2) 依赖包(myPackage1myPackage2 等)可能会扩展在 myPackageUtilities 中定义的 S3 泛型.

2) The dependent packages (myPackage1, myPackage2, etc.) will likely extend S3 generics defined in myPackageUtilities.

我的问题是:组装所有这些的最佳方式是什么?这里有两个自然的(但非详尽的)选项:

My question is: What is the best way to assemble all of this? Here are two natural (but non-exhuastive) options:

  1. Imports下包含mypackageUtilities:对所有依赖包,强制用户单独加载mypackageUtilities
  2. 在 Depends: 下包含 mypackageUtilities 用于所有依赖包,并且对从 mypackageUtilities 导出的内容非常有选择性,以免造成搜索路径混乱.所有内部(非导出)代码都必须通过 myPackage1 中的 ::: 等访问.
  1. Include mypackageUtilities under Imports: for all the dependent packages, and force users to separately load mypackageUtilities,
  2. Include mypackageUtilities under Depends: for all the dependent packages, and be very selective about what is exported from mypackageUtilities so as to avoid cluttering the search path. All of the internal (non-exported) code will have to accessed via ::: in myPackage1, etc.

我最初问了一个类似的问题在这里,但很快发现情况很快变得复杂.例如:

I originally asked a similar question over here, but quickly discovered the situation gets complicated quickly. For example:

  • 如果我们使用 Imports: 而不是 Depends:,那么 mypackageUtilities 中定义的任何泛型都不会被 myPackage1 等找到.
    • 这使得使用 mypackageUtilities 提供的通用模板变得困难/不可能,并且几乎违背了整个设置的目的.
    • If we use Imports: instead of Depends:, then any generics defined in mypackageUtilities aren't found by myPackage1, etc.
      • This makes using the generic templates provided by mypackageUtilities difficult/impossible, and almost defeats the purpose of this entire set-up.

      也许我深深误解了命名空间的工作原理,在这种情况下,这将是消除我的误解的好地方!

      Perhaps I am deeply misunderstanding how namespaces work, in which case this would be a great place to clear up my misunderstanding!

      推荐答案

      欢迎来到兔子洞.

      您可能会惊喜地发现您可以将 myPackageUtilities 中的函数导入到 myPackage1 中,然后从 myPackage1 中导出来制作可从全球环境中访问.

      You may be pleasantly surprised to learn that you can import a function from myPackageUtilities into myPackage1 and then export it from myPackage1 to make it accessible from the global environment.

      所以,当您说 myPackageUtilities 中有一个函数应该由最终用户在 myPackage1 加载时访问时,这就是我将包含在我的myPackage1

      So, when you say that you have a function in myPackageUtilities that should be accessible by the end user when myPackage1 is loaded, this is what I would include in my documentation for fn_name in myPackage1

      #' @importFrom myPackageUtilities fn_name
      #' @export fn_name
      

      (参见 https://github.com/hadley/dplyr/blob/master/R/utils.r 例如)

      这仍然留下了如何链接到原始文档的问题.恐怕我对此没有一个好的答案.我目前的做法是,基本上,从原始源复制参数文档,然后在我的 @details 部分写入 请参阅文档 code{link[myPackageUtilities]{fn_name}}

      That still leaves the question of how to link to the original documentation. And I'm afraid I don't have a good answer for that. My current practice is to, essentially, copy the parameters documentation from the original source and then in my @details section write please see the documentation for code{link[myPackageUtilities]{fn_name}}

      最后,我仍然认为您最好的选择是从 myPackageUtilities 导出所有将在 myPackageUtilities 之外使用的内容,并在每个您希望 myPackageUtilities 中的函数可从全局环境访问的包.

      In the end, I still think your best bet is to export everything from myPackageUtilities that will ever get used outside of myPackageUtilities and do a combination import-export in each package where you want a function from myPackageUtilities to be accessible from the global environment.

      这篇关于开发一套依赖 R 包的最佳实践的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-29 06:03