2015-04-23 2 views
0

У меня есть кадр данных, как это:Параллельная обработка в R для кадра данных

     Open High Low Close Volume 
1998-09-08 10:32:00 106.44 106.44 106.44 106.44  1 
1998-09-08 10:33:00 106.42 106.42 106.35 106.35 628225 
1998-09-08 10:34:00 106.31 106.38 106.31 106.38 135840 
1998-09-08 10:35:00 106.35 106.35 106.32 106.34 170010 
1998-09-08 10:36:00 106.35 106.36 106.35 106.36 309560 
1998-09-08 10:37:00 106.44 106.50 106.44 106.50 115540 
1998-09-08 10:38:00 106.49 106.53 106.49 106.52 427620 
1998-09-08 10:39:00 106.53 106.54 106.52 106.53 321350 
1998-09-08 10:40:00 106.55 106.60 106.54 106.54 317647 
1998-09-08 10:41:00 106.56 106.63 106.56 106.63 233901 

мне нужно изменить Open в параллельной обработки. Я написал функцию, как это:

parTest <- function(x){ 

      foreach(i = 1:nrow(x)) %dopar% {     
         x[i,1] <- i 
       } 
return(x)   
} 

, но когда я называю это изменение функции ничего и вернуться без изменений кадра данных.

zz <- parTest (x) 
zz 

Когда я использую простой for loop он работает, но foreach не работают!

Я также использовал соответствующий пакет и сердечники настройки, а также:

library(foreach) 
library(doParallel) 
cl <- makeCluster(4) 
registerDoParallel(cl) 

Спасибо за вашу помощь.

ответ

5

foreach возьмет возвращаемое значение из кодового блока и как-то объединит его. В вашем случае, поскольку вы не указываете аргумент .combine, он возвращает каждый экземпляр внутри списка. (Первый абзац help(foreach) говорит об этом.)

Хорошо, так что происходит с каждым экземпляром вашего кода? Он принимает вид data.frame с момента запуска вызова (это означает, что строка 2 не видит измененный data.frame из строки 1 и т. Д.), Обновляя этот data.frame, а затем возвращая «что-то».

Это «нечто» не так, как вы думаете. Чтобы увидеть это, попробуйте вручную обновить data.frame с чем-то вроде (x[1,1] <- 1); это показывает, что возвращаемое значение из присваивания - это значение «1», а не содержание x. Другими словами, возвращаемое значение из присваивания - это назначенное значение, а не вся переменная, которой она была назначена.

Таким образом, в вашем случае, x[i,1] <- i тихо вернуться i, поэтому возвращаемое значение из дочерних процессов foreach (которые вы не захватывая) список 1:nrow(x), бесполезным для вас. Если вы назначили результат от foreach и явно вернули его из блока кода , вы увидите это.

Что я думаю вы хотите - это для кода, чтобы вернуть определенную строку, которая была скорректирована, а затем объединить их в data.frame в конце. Обратите внимание: если вы вернете весь файл data.frame, то возврат с foreach будет списком data.frames, а не (я думаю), что вы хотите.

Есть много способов сделать это, я покажу три. Этот первый будет работать очень хорошо, и это немного более буквально в том, как вы управляете data.frame.

parTest <- function(x) { 
    ret <- foreach(i = 1:nrow(x)) %dopar% { 
     x[i,1] <- i 
     x[i,,drop=FALSE] 
    } 
    do.call('rbind', ret) 
} 

Если ваш data.frame довольно большой, поймите, что вы делаете много копий этого data.frame. Если вам нужна только одна строка (я предполагаю, что ваш пример надуман как простой MWE), тогда это не нужно.Вы можете упростить это немного с:

parTest <- function(x) { 
    foreach(i = 1:nrow(x), .combine=rbind) %dopar% { 
     x[i,1] <- i 
     x[i,,drop=FALSE] 
    } 
} 

Другой метод, с помощью iterators пакета:

library(iterators) 
parTest <- function(x) { 
    foreach(df = iter(x, by='row'), .combine=rbind) %dopar% { 
     df[i,1] <- i 
     df[i,,drop=FALSE] 
    } 
} 

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

BTW: Я предполагаю, что вы действительно ищете результирующий data.frame, а не только для побочного эффекта изменения данных в кадре. При работе с параллельными файлами с использованием %dopar% убедитесь, что дочерние процессы не видят или работают с вызывающей средой действительной.

+0

Ваш последний пример следует изменить, чтобы использовать 'df'. Он не должен использовать либо 'x', либо' i'. –

+0

Стив, спасибо большое. Но я понял новую проблему. мой фрейм данных - объект зоопарка с индексом POSIXct. Мне нужно изменить индекс объекта зоопарка в foreach, но эта матрица возврата функции. Мне нужно ввести зоопарк и вернуть зоопарк. –

+0

@Steve, что случилось, когда вы принуждали 'as.zoo'? – r2evans

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