Reputation: 1729
I've built the following mwe that shows a series of nested functions, that are called inside a foreach statement, with MPI as a backend. All of this is packaged inside an R package. The problem is that when I load the package, and then call fun3, I can not get it to change the value of fun3on from TRUE to FALSE. Any suggestions? The complete code is at https://github.com/jamaas/toymod3.git.
Expect that calling
fun1(fun3on = FALSE)
to change the output values, but it does not?
#' Test function level 1
#' @param var11 first variable for function 1
#' @param var12 second variable for function 1
#' @param var13 third variable for function 1
#' @export fun1
fun1 <- function (var11=10, var12=8, var13=5,
var21=0.05, var22=9.876,
fun3on=TRUE, ...) {
results <- data.frame (foreach::`%dopar%`(
foreach::`%:%`(foreach::foreach(j = 1:var11,
.combine = cbind,
.packages="toymod2",
.export = "fun3on"),
foreach::foreach (i = 1:var12, .combine=rbind)),
out3 <- replicate(var13, do.call(fun2, list(var21, var22)))
)
)
## save outputs for subsequent analyses if required
saveRDS(results, file = paste("./outputs/", var13 ,"_", var12, "_", var11, "_",
format(Sys.time(), "%d_%m_%Y"), ".rds", sep=""))
return(results)
}
#' Test function level 2
#' @param var21 first variable for function 2
#' @param var22 second variable for function 2
#' @export fun2
fun2 <- function (var21=0.05, var22=9.876, ...) {
out2 <- `if` (rpois(1, var21) > 0,
var22 * fun3(...),
0)
}
#' Test function level 3
#' @param var31 first variable for function 3
#' @param var32 second variable for function 3
#' @param var33 third variable for function 3
#' @param fun3on turn the formula on or off
#' @export fun3
fun3 <- function (var31=1.396, var32=14.387,
var33=3.219, fun3on = TRUE, ...) {
out3 <- `if` (fun3on,
var31 * rnorm(1, mean=var32, sd= var33),
500)
}
Upvotes: 0
Views: 57
Reputation: 11738
The problem is that you are not passing fun3on
to fun2
so it won't be passed to fun3
.
In do.call(fun2, list(var21, var22))
, change it to be do.call(fun2, list(var21, var22, fun3on = fun3on, ...))
. Make sure to pass them as named arguments (I added the dots because you seem to have some in fun3
).
PS: don't name your returns unless you use evocative names.
Upvotes: 1
Reputation: 13591
Looks complicated. I'd post as a comment but since this potential answer is longer and represents an attempt at answering your question, here goes
My guess is your problem lies here
In fun1
you call fun2
fun2 <- function (var21=0.05, var22=9.876, ...) {
out2 <- `if` (rpois(1, var21) > 0,
var22 * fun3(...),
0)
}
fun2
calls fun3(...)
without passing arguments
fun3 <- function (var31=1.396, var32=14.387,
var33=3.219, fun3on = TRUE, ...) {
out3 <- `if` (fun3on,
var31 * rnorm(1, mean=var32, sd= var33),
500)
}
But fun3on
is default TRUE
in fun3
Maybe if you change (...)
to (fun3on=fun3on)
fun2 <- function (var21=0.05, var22=9.876, ...) {
out2 <- `if` (rpois(1, var21) > 0,
var22 * fun3(fun3on=fun3on),
0)
}
it might work???
Upvotes: 0