2012-09-29 31 views
0

我试图将下面的代码转换为并行使用foreach%dopar%foreach抛出%dopar%错误,但成功执行%do%

library(doSNOW) 
library(foreach) 
cl<- makeCluster(4, type = "SOCK") 
registerDoSNOW(cl) 

min_subid <- c() 
max_subid <- c() 
p_typ <- c() 
p_nm <- c() 
st_tm<-c() 
end_tm <- c() 
supp <- c() 
chart_type <- c() 

foreach(j =1:noOfPhases) %dopar% 
{ 
    start_time <-phases[j, colnames(phases)=="StartTime"] 
    end_time  <-phases[j, colnames(phases)=="StopTime"] 
    phase_type <-phases[j, colnames(phases)=="Phase_Type_Id"] 
    phase_name <-phases[j, colnames(phases)=="Phase_Name"] 
    suppress  <-phases[j, colnames(phases)=="Suppression_Time"] 
    chart_typ  <-phases[j, colnames(phases)=="chartType"] 

    conft<-(masterData$Time.Subgroup>=start_time & masterData$Time.Subgroup<=end_time) 

    masterData[which(conft), colnames(masterData)=="Phase_Type"]<-phase_type 
    masterData[which(conft), colnames(masterData)=="Phase_Name"]<-phase_name 

    min_subid <- rbind(min_subid, min(which(conft))) 
    max_subid <- rbind(max_subid, max(which(conft))) 
    p_typ  <- rbind(p_typ, masterData$Phase_Type[min(which(conft))]) 
    p_nm  <- rbind(p_nm, masterData$Phase_Name[min(which(conft))]) 
    st_tm  <- rbind(st_tm, as.character(start_time)) 
    end_tm <- rbind(end_tm, as.character(end_time)) 
    supp  <- rbind(supp,as.character(suppress)) 
    chart_type <- rbind(chart_type,as.character(chart_typ)) 

    phase_info <- data.frame(Subgrp_No_Start=min_subid, Subgrp_No_End=max_subid, Phase_Type=p_typ, 
          Phase_Name=p_nm, Start_Time=st_tm, Stop_Time=end_tm, 
              Suppression_Time=supp,ChartType=chart_type) 
} 

phase_output<-merge(phase_info, phases, by.x=c("Start_Time", 
    "Stop_Time","ChartType"), by.y=c("StartTime", "StopTime","chartType")) 

上述代码当包括代替%dopar%%do%成功执行。谁能帮助我了解为什么我收到以下错误,当它运行并行(%dopar%),并成功地在连续(%do%

Error in merge(phase_info, phases, by.x = c("Start_Time", "Stop_Time", : 
    object 'phase_info' not found 
+0

告诉我们,你得到'%dopar%'错误。我猜目前的错误只是告诉我们你的foreach没有产生正确的结果(或者根本没有)。 –

回答

5
运行

的解决方案是非常简单的,但是我开始用的是什么的解释当您执行代码来解释错误时发生。

在您的foreach块中会发生什么情况是为每个值j创建一个数据帧(phase_info),并将它们一起返回到列表中。但是,由于您的分配phase_info <- data.frame(...)位于foreach而非外部,因此该列表不会存储在任何地方并被丢弃。引起混淆的原因是,在使用%do%时,将在主节点上顺序创建所有数据帧,并在使用%dopar%时在工作节点上并行创建帧。由于phase_info在其工作空间中不存在,因此如果使用%dopar%,则会在主节点上执行以下merge命令,从而导致错误。还请注意,如果使用与上面类似的%do%,则每次迭代foreach都会覆盖先前结果(,即您只能得到最后一次迭代的结果)。

这轻微的变化修复它:

phase_info <- foreach(...) %dopar% { 
    ... 

    data.frame(Subgrp_No_Start=min_subid, Subgrp_No_End=max_subid, Phase_Type=p_typ, 
          Phase_Name=p_nm, Start_Time=st_tm, Stop_Time=end_tm, 
              Suppression_Time=supp,ChartType=chart_type) 
    # No need to give it a name as it will be returned and the name forgotten 
} 
phase_output <- merge(phase_info, ...) 

正如我上面提到,phase_info现在将是一个列表,其中每个元素是一个数据帧。我刚才猜测,但你可能要执行的merge的elementwise那么,像这样:

phase_output <- lapply(phase_info, merge, phases, by.x=c("Start_Time", 
    "Stop_Time","ChartType"), by.y=c("StartTime", "StopTime","chartType")) 
+0

这个改变很有效。非常感谢。这是一个明确的解释。 – Amar