Невозможно изменить значение логической переменной внутри функции foreach с помощью doMPI

Я построил следующий mwe, который показывает ряд вложенных функций, которые вызываются внутри оператора foreach, с MPI в качестве серверной части. Все это упаковано в пакет R. Проблема в том, что когда я загружаю пакет, а затем вызываю fun3, я не могу заставить его изменить значение fun3on с TRUE на FALSE. Какие-либо предложения? Полный код находится по адресу https://github.com/jamaas/toymod3.git.

Ожидайте, что вызов

fun1(fun3on = ЛОЖЬ)

изменить выходные значения, но это не так?

#' 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)
}

person Jim Maas    schedule 10.09.2017    source источник


Ответы (2)


Проблема в том, что вы не передаете fun3on в fun2, поэтому оно не будет передано в fun3.

В do.call(fun2, list(var21, var22)) измените его на do.call(fun2, list(var21, var22, fun3on = fun3on, ...)). Убедитесь, что они переданы как именованные аргументы (я добавил точки, потому что у вас они есть в fun3).

PS: не называйте свои возвращения, если вы не используете вызывающие воспоминания имена.

person F. Privé    schedule 10.09.2017

Выглядит сложно. Я бы опубликовал комментарий, но, поскольку этот потенциальный ответ длиннее и представляет собой попытку ответить на ваш вопрос, вот

Я предполагаю, что ваша проблема кроется здесь

В fun1 вы звоните fun2

fun2 <- function (var21=0.05, var22=9.876, ...) {
    out2 <- `if` (rpois(1, var21) > 0,
                    var22 * fun3(...),
                  0)
}

fun2 вызывает 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)
}

Но fun3on по умолчанию TRUE в fun3

Может быть, если вы измените (...) на (fun3on=fun3on)

fun2 <- function (var21=0.05, var22=9.876, ...) {
    out2 <- `if` (rpois(1, var21) > 0,
                    var22 * fun3(fun3on=fun3on),
                  0)
}

может получится???

person CPak    schedule 10.09.2017