当调用datadist() + options()设置rms时,Testthat失败

6

我想使用testthat包进行单元测试,但是似乎无法与rms包正常配合。以下是示例:

library(rms)
set.seed(10)
ds <- data.frame(
  ftime = rexp(200),
  fstatus = sample(0:1,200,replace=TRUE),
  x1 = runif(200),
  x2 = runif(200),
  x3 = factor(sample(LETTERS[1:3], size=200, replace=TRUE)))


ddist <- datadist(ds)
options(datadist="ddist")

s <- Surv(ds$ftime, ds$fstatus == 1)
fit <- cph(s ~ x1 + x2 + x3, data=ds)

返回以下错误:

在Design(eval.parent(m))中出现错误:选项(datadist=)未找到数据集ddist

即使print(ddist)能正常工作并且options("datadist")返回正确的变量,仍然会出现这种情况。 那么,testthat 是否有引起错误的不同变量范围?

更新

我通过在我的软件包目录(Eclipse StatET)中启动R控制台来运行testthat:

library(testthat)
test_dir("inst/tests")
q()

同样的错误也会在R CMD check --as-cran命令中出现。

@agstudy:添加了我如何运行testthat的方式。 - Max Gordon
“耸肩” 两位教授Harrell和Wickham已经或曾经采用编程技术,这些技术可能与R Core的技术相似或不相似。因此,可能会发生持续四个小时以上的副作用。我想你可能刚好遇到了其中之一。如果您想保留rms,还有其他两个单元测试包可供尝试。 - Dirk Eddelbuettel
目前无法复现。R 2.15.2,MacOS 10.6.8,R.app GUI 1.53(6335),testthat版本为0.7,evaluate版本为0.4.2(并重新测试了evaluate 0.4.3)。也许这是由于常规路径被StatET劫持的问题?我不知道你所说的“使用相同的错误”是什么意思:R CMD check --as-cran?那是完整的命令行输入吗(当我输入它时出现了错误,但与rms无关)? - IRTFM
@DWin: 我使用的是Windows 7操作系统,R 2.15.2 64位版本,并安装了testthat v0.7、evaluate 0.4.3以及最新的rms包3.6-2。R CMD只是对我的软件包进行CRAN检查的命令。 - Max Gordon
@DirkEddelbuettel:我非常喜欢Hmisc/rms软件包中的工具,而我的软件包旨在补充其中一些工具,比如提供一个替代latex()的markdown选项。我设置单元测试的原因是为了通过重组Predict()、predictrms()、contrast()和summary.rms()这些函数的代码来理解它们。它们都有自己计算置信区间的方法,这对我来说似乎不是一个好主意,特别是因为看起来只有Predict()函数能正确处理基于自助法的估计(使用coef.reps=TRUE)。 - Max Gordon
2个回答

5

虽然@agstudy的建议是正确的,但我已经找到了一个简单的解决方法,通过使用<<-运算符将变量分配给全局环境,这是一个有效的测试文件:

set.seed(10)
n <- 11
ds <- data.frame(
  y = rnorm(n),
  x1 = factor(sample(c("a", "aa", "aaa"), size = n, replace = TRUE)))

suppressMessages(library(rms))
dd <<- datadist(ds)
options(datadist = "dd")

context("rms")
test_that("test", {
  fit <- ols(y ~ x1, data=ds)
  s <- summary(fit)
  expect_true(inherits(s, "summary.rms"))
})

如果你恰好在test_that中进行赋值操作,这也可以正常运作:

context("rms")
test_that("test", {
  set.seed(10)
  n <- 11
  ds <- data.frame(
    y = rnorm(n),
    x1 = factor(sample(c("a", "aa", "aaa"), size = n, replace = TRUE)))

  suppressMessages(library(rms))
  dd <<- datadist(ds)
  options(datadist = "dd")

  fit <- ols(y ~ x1, data=ds)
  s <- summary(fit)
  expect_true(inherits(s, "summary.rms"))
})

这也等同于下面的代码(可能更易理解):
env <- globalenv() # Grab the global environment
env$dd <- datadist(ds) # Assign the datadist to it

如果您想了解环境是如何工作的,我可以推荐Hadley在Advanced R中对此主题的优秀覆盖。我发现这解释了我遇到的许多问题。请参考链接

2

正如错误提示所建议的那样,这是一个范围问题。

一个可能的解决方法是在调用 test_dir 时定义你的 ds

例如,你可以像这样创建文件 runtest.R

library(rms)
set.seed(10)
ds <- data.frame(
  ftime = rexp(200),
  fstatus = sample(0:1,200,replace=TRUE),
  x1 = runif(200),
  x2 = runif(200),
  x3 = factor(sample(LETTERS[1:3], size=200, replace=TRUE)))
ddist <- datadist(ds)
options(datadist="ddist")
library(testthat)
test_dir("inst/tests")

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接