是否可以在testthat测试或run_examples()中使用R包数据?

时间:2012-01-17 16:49:54

标签: r devtools roxygen roxygen2

我正在使用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'中的数据。

例如,我想通过调用:

在我的测试中使用这些数据集
    data(foo)
    data(bar)
    expect_that(foo$col[1], equals(bar$col[1]))

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

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

如果我在开发包时尝试调用data(foo),则会收到错误“data set'foo'not found”。但是,如果我构建软件包,安装它并加载它 - 那么我可以使测试和示例工作。

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

    #' @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'相同的完整路径。此外,文档中的示例看起来无法运行,即使安装了软件包,也可以。

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

2 个答案:

答案 0 :(得分:19)

在examples / tests

中导入非RData文件

我通过查看the JSONIO package找到了解决这个问题的方法,这显然需要提供一些除.RData变体之外的文件读取示例。

我让它在函数级示例中工作,并且同时满足R CMD check mypackagetestthat::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")

请注意,这是允许在R CMD check mypackage期间调用testt的部分,否则不是必需的。您还应在描述文件中添加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目录中的R二进制(data)文件。因此,您可以通过预先导入数据文件并使用save()命令将它们保存到数据目录中来绕过上面的示例。但是,这假设您只需要显示已将数据加载到R中的示例,而不是可重复地演示导入文件的上游过程。

答案 1 :(得分:2)

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

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

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

最后但并非最不重要的是,虽然它不是最佳的,但您实际上可以将特定于开发人员的代码放入您的存储库中。如果@hadley这样做,那不是一件坏事。例如,请参阅testthat在他自己的环境中activates certain behaviors的方式。