Reputation: 6852
In R, is it possible to test a function with a combination of parameters without resorting to a for loop? For example, I'm currently doing something similar to this:
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...
}
}
}
})
However, this is not practical with too many nested fors, and also raises cyclomatic complexity errors with lintr.
In Python we can easily do this with pytest (using test parameters or text fixtures), and this is also easy to achieve in Julia.
I found the patrick package, but it doesn't seem to do parameter combination in this way, only to define parameter sets. I guess one could create these parameter sets for patrick using for loops, but that seems to be missing the point.
Upvotes: 1
Views: 412
Reputation: 16856
Here is a possible option using base R (also if you want to avoid the for loop), but following at @Paulsmith with expand.grid
.
invisible(apply(df, 1, function(x){
cat(paste0(paste(x[1],x[2],x[3],sep=' '),"\n"))
}))
Output
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
Data
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)
Upvotes: 0
Reputation: 25333
If you want to avoid the for
loop at all, then you can use the map functions of package purrr
to iterate over the dataframe, which resulted from 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
Upvotes: 3