#はじめに
データ分析でRを使っていると、データ前処理・加工やループ計算で時間がかかったりすることもしばしばです。Rは計算処理が遅いといわれますが、単純な足し算などはベクトルを使って処理させれば計算時間を改善することもできますし、オリジナルな関数を使って計算を早くしたいという場合には、複数のCPUを使った「並列計算」によって計算時間を大幅に減らすことができます!
#準備
- R 2.14.0以上
- 必要なライブラリー parallel(と、ここでは祝日データが必要なため、Nippon)
#目的(やりたいこと)
日付のリストを受け取って、もし平日ならそのまま、休日や祝日だと後の直近営業日のリストを返す処理を作成します。
#コード
# libraries
library(Nippon)
library(parallel)
# input data
date.List <- seq(as.Date("2016/1/1",format="%Y/%m/%d"),as.Date("2016/12/31",format="%Y/%m/%d"),by=1)
# function
calcNormalDate <- function(date_)
{
calc.Date <- as.Date(date_)
n <- length(date_)
for (i in 1:n){
while(is.jholiday(calc.Date[i]) || weekdays(calc.Date[i]) %in% c("土曜日","日曜日"))
{
calc.Date[i] <- calc.Date[i] + 1
}
}
return(calc.Date)
}
# normal calc
system.time(new.date.List <- calcNormalDate(date.List))
# parrallel calc
cl <- makeCluster(4)
clusterCall(cl,Sys.getpid)
clusterExport(cl,"is.jholiday")
system.time(new.date.List <- parLapply(cl,date.List,calcNormalDate))
stopCluster(cl)
#結果
- ノーマル処理 経過時間: 2.16
- 並列処理 経過時間: 0.88
#解説
- インプットデータとして、2016/1/1から2016/12/31まで日付リストを作成します。
- calcNormalDate で目的の関数を作成します。
- cl <- makeCluster(4)で、ワーカープロセス数を指定して、クラスター生成します。ここでは4つです。
- clusterExport(cl,"is.jholiday")を入れとかないと、is.jholidayがないとエラーがでます。
- parLapply(cl,date.List,calcNormalDate)の2番目の引数にデータを入れて、3番目の引数にオリジナル関数を入れます。
- 祝日はNIPPONライブラリーを使っています。
#終わりに
他の言語(C++やJAVAなど)が使えるのであれば、それらで処理をさせたほうがいいと思いますが、そういったことができない場合にこの並列計算は役に立ちます。
#参考資料
『Rによるハイパフォーマンスコンピューティング』(著:福島真太郎、出版:ソシム株式会社)がおすすめです。