2016-10-23 3 views
1

Предположим, что я хочу применять параллельно myfunction для каждой строки myDataFrame. Предположим, что otherDataFrame является фреймворком данных с двумя столбцами: COLUNM1_odf и COLUMN2_odf по некоторым причинам используется в myfunction. Так что я хотел бы написать код, используя parApply так:R, dplyr и snow: как распараллелить функции, которые используют dplyr

clus <- makeCluster(4) 
clusterExport(clus, list("myfunction","%>%")) 

myfunction <- function(fst, snd) { 
#otherFunction and aGlobalDataFrame are defined in the global env 
otherFunction(aGlobalDataFrame) 

# some code to create otherDataFrame **INTERNALLY** to this function 
otherDataFrame %>% filter(COLUMN1_odf==fst & COLUMN2_odf==snd) 
return(otherDataFrame) 
} 
do.call(bind_rows,parApply(clus,myDataFrame,1,function(r) { myfunction(r[1],r[2]) } 

Проблема здесь состоит в том, что R не признает COLUMN1_odf и COLUMN2_odf даже если я вставляю их в clusterExport. Как я могу решить эту проблему? Есть ли способ «экспортировать» весь объект, который нужен snow, чтобы не перечислять каждый из них?

EDIT 1: Я добавил комментарий (в коде выше), чтобы указать, что otherDataFrame создается interally для myfunction.

EDIT 2: Я добавил некоторые псевдо-код, чтобы обобщать myfunction: теперь он использует глобальную dataframe (aGlobalDataFrame и другую функцию otherFunction)

+1

Аргументы вашей 'myFunction' должны держать все объекты. Попробуйте 'myFunction <- function (otherDataFrame, fst, snd) {...'. –

+0

в действительности otherDataFrame - это объект, созданный в моей функции, поэтому я не могу перейти к нему. – enneppi

+0

Вместо использования 'parApply' вы можете использовать' parLapply'. 'do.call (bind_rows, parLapply (clus, 1: nrow (myDataFrame), function (i, r) {myfunction (r [i, 1], r [i, 2])}'. (У меня нет протестировал это. Может все еще понадобиться какое-то вождение) – Benjamin

ответ

1

Совершено несколько экспериментов, поэтому я решил мою проблему (с предложением Вениамина и учитывая «изменить», что я добавил к вопросу) с:

clus <- makeCluster(4) 
clusterEvalQ(clus, {library(dplyr); library(magrittr)}) 
clusterExport(clus, "myfunction", "otherfunction", aGlobalDataFrame) 

myfunction <- function(fst, snd) { 
#otherFunction and aGlobalDataFrame are defined in the global env 
otherFunction(aGlobalDataFrame) 

# some code to create otherDataFrame **INTERNALLY** to this function 
otherDataFrame %>% dplyr::filter(COLUMN1_odf==fst & COLUMN2_odf==snd) 
return(otherDataFrame) 
} 

do.call(bind_rows, parApply(clus, myDataFrame, 1, 
     {function(r) { myfunction(r[1], r[2]) }) 

Таким образом, я зарегистрирован aGlobalDataFrame, myfunction и otherfunction, короче все функции и данные, используемые функцией, используемой для распараллеливания работы (myfunction сам)

0

Теперь, когда я не смотрел на это на моем телефоне , Я вижу пару вопросов.

Во-первых, вы фактически не создаете otherDataFrame в своей функции. Вы пытаетесь подключить существующий otherDataFrame к filter, а еслине существует в среде, функция завершится с ошибкой.

Во-вторых, если вы уже не загрузили пакет dplyr в свои кластерные среды, вы вызовете неправильную функцию filter.

И наконец, когда вы звоните parApply, вы не указали нигде, что должно быть fst и snd. Дайте следующую попытку:

clus <- makeCluster(4) 
clusterEvalQ(clus, {library(dplyr); library(magrittr)}) 
clusterExport(clus, "myfunction") 

myfunction <- function(otherDataFrame, fst, snd) { 
dplyr::filter(otherDataFrame, COLUMN1_odf==fst & COLUMN2_odf==snd) 
} 
do.call(bind_rows,parApply(clus,myDataFrame,1,function(r, fst, snd) { myfunction(r[fst],r[snd]), "[fst]", "[snd]") } 
+0

Я попробую это как можно скорее ...даже несмотря на то, что otherDataFrame создается внутри функции (прочитайте мое последнее редактирование), ваше предложение - хороший способ следить за – enneppi

+0

, возможно, это своего рода опечатка .... {myfunction (r [fst], r [snd]), "[ fst] "," [snd] ")}? – enneppi

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