R: doSNOW/foreach создать список из списка

Привет, я хотел бы создать именованный список с помощью пакета doSNOW/foreach. Например, конечным продуктом будет объект списка. dfe, названный из вектора, скажем,

n=c("n1","n2","n3","n4","n5")

так что я могу получить доступ к списку объектов списка, таких как dfe[["n1"]]$a, где a является элементом в списке.

Вот пример того, о чем я говорю.

mainStart <- Sys.time()

n=c("n1","n2","n3","n4","n5")

cores=detectCores() 
cl <- parallel::makeCluster(cores[1]-1) #not to overload your computer
registerDoSNOW(cl)

## setup progress bar 
pb <- txtProgressBar(max = 5, style = 3)
progress <- function(n) setTxtProgressBar(pb, n)
opts <- list(progress = progress)


dfe <-  foreach(id.this = n, .combine = list, .options.snow = opts) %dopar% {
    list ( a=c(1,2,3), b = c(1,2,3))
}

endTime <- Sys.time()
endTime -mainStart 


close(pb)
stopCluster(cl)

Так что было бы здорово, если бы список, созданный в цикле foreach, мог иметь имя и доступ после цикла. Так что dfe[["n1"]]$a может дать мне вектор 1,2,3.


person Ahdee    schedule 25.07.2018    source источник
comment
Не комбинируйте и используйте setNames(dfe, n) впоследствии.   -  person F. Privé    schedule 25.07.2018
comment
@ F.Privé удивительно, что это работает, потому что я думал, что это выйдет из строя. Например, когда я это сделал, if ( id.this == "n2"){Sys.sleep(10)} заказ был сохранен, спасибо.   -  person Ahdee    schedule 25.07.2018


Ответы (1)


Как было предложено выше, проще просто установить имена ( dfe, n ), однако я не думал, что это сработает, поскольку некоторые процессы могут занимать больше времени, чем другие, но кажется, что порядок не меняется. Например, когда я устанавливаю

if ( id.this == "n2"){
        Sys.sleep(10)
    }

заказ все еще сохранялся. Итак, окончательный код будет примерно таким.

mainStart <- Sys.time()

n=c("n1","n2","n3","n4","n5")

cores=detectCores() 
cl <- parallel::makeCluster(cores[1]-1) #not to overload your computer
registerDoSNOW(cl)

## setup progress bar 
pb <- txtProgressBar(max = 4, style = 3)
progress <- function(n) setTxtProgressBar(pb, n)
opts <- list(progress = progress)


dfe <-  foreach(id.this = n, .options.snow = opts) %dopar% {
    #list(id.this = list(  a=c(1,2,3), b = c(1,2,3) ) )
    if ( id.this == "n2"){
        Sys.sleep(10)
    }
    list(  a=c(id.this,2,3), b = c(1,2,3) )
}

endTime <- Sys.time()
endTime -mainStart 


close(pb)
stopCluster(cl)

dfe=setNames(dfe, n)
person Ahdee    schedule 25.07.2018
comment
Да, функция foreach() учитывает порядок ввода/вашего итератора независимо от последовательной или параллельной обработки (и как, где и когда). Это возможно, потому что все элементы завершаются до возврата foreach(). - person HenrikB; 28.07.2018