2011-09-26 2 views
2

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

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

Когда я использую эту функцию, чтобы объединить Еогеасп заявление с итератора, кроме 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) 

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

ответ

3

Функция .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) 

Это один может занять несколько штук за один раз, и объединить их. Это более общий (но более сложный).

+0

Спасибо! Таким образом, в моем реальном приложении каждый бит, поставленный в MyComb, представляет собой список с кучей элементов, каждый из которых является матрицей. Я хочу, чтобы (..., вдоль = 3) каждая матрица с тем же именем из исходного списка и, наконец, возвращала большой список с этими массивами. У меня возникли проблемы с тем, как это сделать с вашим решением MyComb2. Есть идеи? – scottyaz

+0

@scottyaz Возможно, просто замените 'unlist (...)' на 'abind (..., вдоль = 3)', но без создания рабочего примера я не уверен. Результат 'sapply (dots, '[[', e)' - это список компонентов с именем «e» из каждой части. 'abind' может принимать список как свой аргумент, поэтому он должен работать с тем, что возвращается из' sapply'. –

+0

sapply (точки, '[[', e, simplify = F) делает трюк! – scottyaz

 Смежные вопросы

  • Нет связанных вопросов^_^