如何在不使用 for 循环的情况下使用参数组合测试函数
How to test a function with a combination of parameters without resorting to a for loop
在 R 中,是否可以在不使用 for 循环的情况下使用参数组合来测试函数?例如,我目前正在做类似的事情:
test_that("Function myfunction() works properly", {
a1 <- c(1, 2, 3, 10, 20, 100)
a2 <- c(-500, 0, 500)
a3 <- c("hello", "world")
for (a1i in a1) {
for (a2i in a2) {
for (a3i in a3) {
result <- myfunction(a1i, a2i, a3i)
expect_equal(result, something_expected)
expect_equal(dim(result), something_else)
# ...and other checks...
}
}
}
})
然而,这对于嵌套太多的 for 不切实际,并且还会引发 lintr 的圈复杂度错误。
在Python中我们可以用pytest轻松做到这一点(使用测试参数或文本夹具),这在Julia中也很容易实现。
我找到了patrick这个包,但是好像没有这样进行参数组合,只是定义了参数集。我想可以使用 for 循环为 patrick 创建这些参数集,但这似乎没有抓住要点。
如果你想完全避免 for
循环,那么你可以使用包 purrr
的映射函数来迭代数据帧,这是由 expand.grid
产生的:
a1 <- c(1, 2, 3, 10, 20, 100)
a2 <- c(-500, 0, 500)
a3 <- c("hello", "world")
df <- expand.grid(a1,a2,a3, stringsAsFactors = FALSE)
# purrr::pwalk(df, ~ cat(..1, ..2, ..3, "\n")) <-- avoiding for loop
for (i in 1:nrow(df))
cat(df[i,1], df[i, 2], df[i, 3], "\n")
#> 1 -500 hello
#> 2 -500 hello
#> 3 -500 hello
#> 10 -500 hello
#> 20 -500 hello
#> 100 -500 hello
#> 1 0 hello
#> 2 0 hello
#> 3 0 hello
#> 10 0 hello
#> 20 0 hello
#> 100 0 hello
#> 1 500 hello
#> 2 500 hello
#> 3 500 hello
#> 10 500 hello
#> 20 500 hello
#> 100 500 hello
#> 1 -500 world
#> 2 -500 world
#> 3 -500 world
#> 10 -500 world
#> 20 -500 world
#> 100 -500 world
#> 1 0 world
#> 2 0 world
#> 3 0 world
#> 10 0 world
#> 20 0 world
#> 100 0 world
#> 1 500 world
#> 2 500 world
#> 3 500 world
#> 10 500 world
#> 20 500 world
#> 100 500 world
这里有一个可能的选项,使用 base R(如果你想避免 for 循环),但在@Paulsmith 之后使用 expand.grid
。
invisible(apply(df, 1, function(x){
cat(paste0(paste(x[1],x[2],x[3],sep=' '),"\n"))
}))
输出
1 -500 hello
2 -500 hello
3 -500 hello
10 -500 hello
20 -500 hello
100 -500 hello
1 0 hello
2 0 hello
3 0 hello
10 0 hello
20 0 hello
100 0 hello
1 500 hello
2 500 hello
3 500 hello
10 500 hello
20 500 hello
100 500 hello
1 -500 world
2 -500 world
3 -500 world
10 -500 world
20 -500 world
100 -500 world
1 0 world
2 0 world
3 0 world
10 0 world
20 0 world
100 0 world
1 500 world
2 500 world
3 500 world
10 500 world
20 500 world
100 500 world
数据
a1 <- c(1, 2, 3, 10, 20, 100)
a2 <- c(-500, 0, 500)
a3 <- c("hello", "world")
df <- expand.grid(a1,a2,a3, stringsAsFactors = FALSE)
在 R 中,是否可以在不使用 for 循环的情况下使用参数组合来测试函数?例如,我目前正在做类似的事情:
test_that("Function myfunction() works properly", {
a1 <- c(1, 2, 3, 10, 20, 100)
a2 <- c(-500, 0, 500)
a3 <- c("hello", "world")
for (a1i in a1) {
for (a2i in a2) {
for (a3i in a3) {
result <- myfunction(a1i, a2i, a3i)
expect_equal(result, something_expected)
expect_equal(dim(result), something_else)
# ...and other checks...
}
}
}
})
然而,这对于嵌套太多的 for 不切实际,并且还会引发 lintr 的圈复杂度错误。
在Python中我们可以用pytest轻松做到这一点(使用测试参数或文本夹具),这在Julia中也很容易实现。
我找到了patrick这个包,但是好像没有这样进行参数组合,只是定义了参数集。我想可以使用 for 循环为 patrick 创建这些参数集,但这似乎没有抓住要点。
如果你想完全避免 for
循环,那么你可以使用包 purrr
的映射函数来迭代数据帧,这是由 expand.grid
产生的:
a1 <- c(1, 2, 3, 10, 20, 100)
a2 <- c(-500, 0, 500)
a3 <- c("hello", "world")
df <- expand.grid(a1,a2,a3, stringsAsFactors = FALSE)
# purrr::pwalk(df, ~ cat(..1, ..2, ..3, "\n")) <-- avoiding for loop
for (i in 1:nrow(df))
cat(df[i,1], df[i, 2], df[i, 3], "\n")
#> 1 -500 hello
#> 2 -500 hello
#> 3 -500 hello
#> 10 -500 hello
#> 20 -500 hello
#> 100 -500 hello
#> 1 0 hello
#> 2 0 hello
#> 3 0 hello
#> 10 0 hello
#> 20 0 hello
#> 100 0 hello
#> 1 500 hello
#> 2 500 hello
#> 3 500 hello
#> 10 500 hello
#> 20 500 hello
#> 100 500 hello
#> 1 -500 world
#> 2 -500 world
#> 3 -500 world
#> 10 -500 world
#> 20 -500 world
#> 100 -500 world
#> 1 0 world
#> 2 0 world
#> 3 0 world
#> 10 0 world
#> 20 0 world
#> 100 0 world
#> 1 500 world
#> 2 500 world
#> 3 500 world
#> 10 500 world
#> 20 500 world
#> 100 500 world
这里有一个可能的选项,使用 base R(如果你想避免 for 循环),但在@Paulsmith 之后使用 expand.grid
。
invisible(apply(df, 1, function(x){
cat(paste0(paste(x[1],x[2],x[3],sep=' '),"\n"))
}))
输出
1 -500 hello
2 -500 hello
3 -500 hello
10 -500 hello
20 -500 hello
100 -500 hello
1 0 hello
2 0 hello
3 0 hello
10 0 hello
20 0 hello
100 0 hello
1 500 hello
2 500 hello
3 500 hello
10 500 hello
20 500 hello
100 500 hello
1 -500 world
2 -500 world
3 -500 world
10 -500 world
20 -500 world
100 -500 world
1 0 world
2 0 world
3 0 world
10 0 world
20 0 world
100 0 world
1 500 world
2 500 world
3 500 world
10 500 world
20 500 world
100 500 world
数据
a1 <- c(1, 2, 3, 10, 20, 100)
a2 <- c(-500, 0, 500)
a3 <- c("hello", "world")
df <- expand.grid(a1,a2,a3, stringsAsFactors = FALSE)