сделать масштабируемую функцию .combine - PullRequest
2 голосов
/ 27 сентября 2011

Я пытаюсь использовать foreach, и у меня возникают проблемы с масштабированием функции .combine. Например, вот простая функция объединения

MyComb <- function(part1,part2){
          xs <- c(part1$x,part2$x)
          ys <- c(part1$y,part2$y)
          return(list(xs,ys))
          }

Когда я использую эту функцию для объединения оператора foreach с итератором, отличным от 2, он возвращает его неправильно. Например это работает:

   x = foreach(i=1:2,.combine=MyComb) %dopar% list("x"=i*2,"y"=i*3)

Но не это:

 x = foreach(i=1:3,.combine=MyComb) %dopar% list("x"=i*2,"y"=i*3)

Есть ли способ обобщить функцию объединения, чтобы сделать ее масштабируемой до n итераций?

1 Ответ

3 голосов
/ 27 сентября 2011

Ваша .combine функция должна брать либо две части и возвращать что-то, что «похоже» на часть (может быть передано обратно как часть), либо принимать множество аргументов и объединять их все вместе (с одинаковыми ограничениями)).Таким образом, по крайней мере, ваш MyComb должен возвращать список с компонентами x и y (это то, что делает каждый кусок вашего %dopar%.

Несколько способов сделать это:

MyComb1 <- function(part1, part2) {
    list(x=c(part1$x, part2$x), y=c(part1$y, part2$y))
}

x = foreach(i=1:3,.combine=MyComb1) %dopar% list("x"=i*2,"y"=i*3)

Эта версия принимает только две части за раз.

MyComb2 <- function(...) {
    dots = list(...)
    ret <- lapply(names(dots[[1]]), function(e) {
        unlist(sapply(dots, '[[', e))
    })
    names(ret) <- names(dots[[1]])
    ret
}

s = foreach(i=1:3,.combine=MyComb2) %dopar% list("x"=i*2,"y"=i*3)
x = foreach(i=1:3,.combine=MyComb2, .multicombine=TRUE) %dopar% list("x"=i*2,"y"=i*3)

Эта версия может принимать несколько частей за раз и комбинировать их. Она более общая (но более сложная).

...