0

foreachandを使用して、次のコードを並列に変換しようとしています%dopar%

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"))

上記のコードは%do%、 の代わりに が含まれている場合に正常に実行され%dopar%ます。並列 ( ) で実行し、順次 ( )%dopar%で正常に実行すると、次のエラーが発生する理由を理解するのに誰か助けてもらえますか?%do%

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

1 に答える 1

5

解決策は本当に簡単ですが、エラーを説明するためにコードを実行したときに何が起こっているのかを説明することから始めます。

foreachブロックで発生するのは、のphase_info値ごとに1つのデータフレーム()が作成されj、それらがリストにまとめて返されることです。ただし、割り当ては外部ではなくphase_info <- data.frame(...)内部にあるため、リストはどこにも保存されず、破棄されます。foreach混乱の原因は、使用する場合はマスターノード%do%すべてのデータフレームを順番に作成し、使用する場合はワーカーノードで並列に作成されることです。次のコマンドはマスターノードで実行され、ワー​​クスペースに存在しないために使用した場合はエラーが発生します。また、上記のように使用する場合、の各反復は%dopar%merge%dopar%phase_info%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

phase_output <- lapply(phase_info, merge, phases, by.x=c("Start_Time",
     "Stop_Time","ChartType"), by.y=c("StartTime", "StopTime","chartType"))
于 2012-09-29T07:50:08.133 に答える