2013-08-15 2 views
0

Я написал код для запуска нескольких циклических регрессий временного ряда для нескольких ценных бумаг. Поскольку количество ценных бумаг составляет более 10 000 и имеет более 200 окон для каждой безопасности, время выполнения для последовательной настройки (используя foreach% do%) составляет около 30 минут.Параллельные вычисления в R (Windows): изменение кода из foreach% do% to foreach% dopar%

Я хотел бы использовать foreach% dopar% для параллельных вычислений, используя бэкэнд doParrallel. Простое изменение% do% с% dopar% в коде не делает трюк. Я очень новичок в этом методе parrallel вычислений и надеюсь получить некоторую помощь.

Вот Еогеасп% делают% код:

sec = ncol(ret.zoo) 
num.factors = 2 
rows = nrow(ret.zoo) - 60 + 1 
beta.temp = matrix(nc = num.factors + 1, nr = sec*rows) 
gvkey.vec = matrix(nc = 1, nr = sec*rows) 

d = 1 
foreach(i=1:sec) %do% { 
     df = merge(ret.zoo[,i], data) 
     names(df) <- c("return", names(data)) 
     gvkey = substr(colnames(ret.zoo)[i],2,9) 

     reg = function(z) { 
      z.df = as.data.frame(z) 
      ret = z.df[,which(names(z.df) == "return")] 
      ret.no.na = ret[!is.na(ret)] 
      if(length(ret.no.na) >= 30) { 
      coef(lm(return ~ VAL + SIZE, data = as.data.frame(z), na.action = na.omit)) 
      } 
      else { 
      as.numeric(rep(NA,num.factors + 1)) ## the "+1" is for the intercept value 
      }  
    } 

    beta = rollapply(df, width = 60, FUN = reg, by.column = FALSE, align = "right") 
    beta.temp[d:(d+rows-1),] = beta 
    gvkey.vec[d:(d+rows-1),] = gvkey 
    d = d+rows 
} 
beta.df = data.frame(secId = gvkey.vec, date = rep(index(beta), sec), beta.temp) 
colnames(beta.df) <- c("gvkey", "date", "intercept", "VAL", "SIZE") 

Для того, чтобы дать возможность параллельных вычислений с использованием% dopar%, я назвал и зарегистрировал бэкенд «doParallel».

спасибо!

UPDATE

Вот моя первая попытка:

library(doParallel) ## parallel backend for the foreach function 
registerDoParallel() 

sec = ncol(ret.zoo) 
num.factors = 2 
rows = nrow(ret.zoo) - 60 + 1 

result <- foreach(i=1:sec) %dopar% { 
    library(zoo) 
    library(stats) 

    df = merge(ret.zoo[,i], data) 
    names(df) <- c("return", names(data)) 
    gvkey = substr(colnames(ret.zoo)[i],2,9) 

    reg = function(z) { 
     z.df = as.data.frame(z) 
     ret = z.df[,which(names(z.df) == "return")] 
     ret.no.na = ret[!is.na(ret)] 
     if(length(ret.no.na) >= 30) { 
      coef(lm(return ~ VAL + SIZE, data = as.data.frame(z), na.action = na.omit)) 
     } 
     else { 
      as.numeric(rep(NA,num.factors + 1)) ## the "+1" is for the intercept value 
     } 
    } 

    rollapply(df, width = 60, FUN = reg, by.column = FALSE, align = "right") 
} 
beta.df = do.call('combine', result) 

Это прекрасно работает до конца цикла. Однако, beta.df = do.call('combine', result) дает следующую ошибку: Error in do.call("combine", result) : could not find function "combine".

Как я могу объединить результат результата. Теперь это список, а не кадр данных.

Спасибо,

+0

Что ошибка? –

+0

На самом деле нет «явной» ошибки. Но матрица «beta.temp» имеет только значения NA, когда используется% dopar%. Когда вместо%% используется%, beta.temp имеет значения коэффициента регрессии, когда это необходимо, и значения NA, когда это необходимо. Я определенно делаю что-то неправильно, просто заменив% do% на% dopar% – Mayou

+0

Я считаю, что способ, которым я выделяю результаты beta.temp (путем увеличения d), неверен, когда используется% dopar%. Он отлично работает с% do%. Я просто не уверен, как сделать это по-другому в контексте параллельных вычислений. – Mayou

ответ

0

Вот способ объединения результатов из разных кластеров в dataframe (очень эффективный с точки зрения времени выполнения):

lstData <- Map(as.data.frame, result) 
dfData <- rbindlist(lstData) 
beta.df = as.data.frame(dfData) 
+0

Foreach имеет аргумент .combine ..check there –