32

我正在使用 devtools、testthat 和 roxygen2 开发 R 包。我在数据文件夹中有几个数据集(foo.txt 和 bar.csv)。

我的文件结构如下所示:

/ mypackage
    / data
        * foo.txt, bar.csv
    / inst
        / tests
            * run-all.R, test_1.R
    / man
    / R

我很确定 'foo' 和 'bar' 记录正确:

    #' Foo data
    #'
    #' Sample foo data
    #'
    #' @name foo
    #' @docType data
    NULL
    #' Bar data
    #'
    #' Sample bar data
    #'
    #' @name bar
    #' @docType data
    NULL

我想在我的文档示例和单元测试中使用“foo”和“bar”中的数据。

例如,我想在我的 testthat 测试中使用这些数据集,方法是调用:

    data(foo)
    data(bar)
    expect_that(foo$col[1], equals(bar$col[1]))

而且,我希望文档中的示例如下所示:

    #' @examples
    #' data(foo)
    #' functionThatUsesFoo(foo)

如果我在开发包时尝试调用 data(foo),则会收到错误“未找到数据集 'foo'”。但是,如果我构建包、安装它并加载它——那么我可以使测试和示例工作。

我目前的解决方法是不运行该示例:

    #' @examples
    #' \dontrun{data(foo)}
    #' \dontrun{functionThatUsesFoo(foo)}

在测试中,使用特定于我的本地计算机的路径预加载数据:

    foo <- read.delim(pathToFoo, sep="\t", fill = TRUE, comment.char="#")
    bar <- read.delim(pathToBar, sep=";", fill = TRUE, comment.char="#"
    expect_that(foo$col[1], equals(bar$col[1]))

这似乎并不理想 - 特别是因为我正在与其他人合作 - 要求所有合作者都有相同的完整路径到 'foo' 和 'bar'。另外,文档中的示例看起来无法运行,即使安装了软件包,它们也可以。

有什么建议么?非常感谢。

4

2 回答 2

21

在示例/测试中导入非 RData 文件

我通过查看JSONIO 包找到了解决此问题的方法,显然需要提供一些读取文件的示例,而不是 .RData 种类的文件。

我让它在函数级示例中工作,并同时R CMD check mypackage满足testthat::test_package().

(1) 重新组织你的包结构,使示例数据目录在inst. 在某些时候R CMD check mypackage告诉我将非 RData 数据文件移动到inst/extdata,所以在这个新结构中,它也被重命名。

/ mypackage
    / inst
        / tests
            * run-all.R, test_1.R
        / extdata
            * foo.txt, bar.csv
    / man
    / R
    / tests
        * run-testthat-mypackage.R

(2) (可选)添加一个顶级tests目录,以便您的新测试现在也可以在R CMD check mypackage.

run-testthat-mypackage.R脚本至少应包含以下两行:

library("testthat")
test_package("mypackage")

请注意,这是允许在 期间调用 testthat 的部分,R CMD check mypackage否则没有必要。您还应该testthat在您的说明文件中添加“建议:”依赖项。

(3) 最后,指定包内路径的秘诀:

barfile <- system.file("extdata", "bar.csv", package="mypackage")
bar <- read.csv(barfile)
# remainder of example/test code here...

如果您查看system.file()命令的输出,它将返回 R 框架内包的完整系统路径。在 Mac OS X 上,这看起来像:

"/Library/Frameworks/R.framework/Versions/2.15/Resources/library/mypackage/extdata/bar.csv"

这对我来说似乎没问题的原因是,除了包中的路径特性之外,您不会对任何路径特性进行硬编码,因此这种方法相对于其他系统上的其他 R 安装应该是健壮的。

data()方法

至于data()语义,据我所知,这是.RData顶级data目录中的 R 二进制 ( ) 文件所特有的。因此,您可以通过预先导入数据文件并使用save()命令将它们保存到您的数据目录中来绕过我上面的示例。但是,这假设您只需要展示一个数据已经加载到 R 中的示例,而不是重复地展示导入文件的上游过程。

于 2012-06-21T22:29:38.727 回答
2

根据@hadley 的评论,.RData转换效果很好。

至于跨团队成员与不同环境的团队协作这一更广泛的问题,一个常见的模式是就单个环境变量达成一致,例如,FOO_PROJECT_ROOT团队中的每个人都将在他们的环境中适当地设置。从那时起,您可以使用相对路径,包括跨项目。

一种特定于 R 的方法是就每个团队成员将在其.Rprofile文件中设置的一些数据/功能达成一致。例如,如何devtools在非标准位置查找包。

最后但并非最不重要的一点是,尽管它不是最优的,但您实际上可以将开发人员特定的代码放入您的存储库中。如果@hadley 做到了,那并不是一件坏事。例如,看看他如何在自己的环境中激活某些行为。testthat

于 2012-06-20T03:25:22.793 回答