野球データをnysolで前処理 + 計算時間の比較

概要

Rで大きなデータを扱うのは大変なので, 高速CSV処理コマンド群nysolを使います.

2013年の全試合の打席結果データを集計してみます. GitHub

処理時間の比較も行いたいです.

先行研究

処理時間比較のスライドがあります.

nysolがめっちゃ速いみたいですが, どうでしょうか.

利用するデータ

打者idと打数フラグ, ヒットフラグの項目を使います.

options(rpubs.upload.method = "internal")
library(data.table)
library(dplyr)
system.time(
dat <- fread("../all2013.csv")
)
## 
Read 99.5% of 190907 rows
Read 190907 rows and 97 (of 97) columns from 0.076 GB file in 00:00:03
##    user  system elapsed 
##   1.998   0.062   2.060
## データサイズ
dat %>% dim
## [1] 190907     97
## 内容
dat %>% select(GAME_ID,BAT_ID,AB_FL,H_FL) %>% head
##         GAME_ID   BAT_ID AB_FL H_FL
## 1: ANA201304090 crisc001     T    0
## 2: ANA201304090 younc004     T    0
## 3: ANA201304090 lowrj001     F    0
## 4: ANA201304090 cespy001     F    0
## 5: ANA201304090 norrd001     T    1
## 6: ANA201304090 donaj001     T    1

打席ごとにデータレコードがあります. 打数ならAB_FL:Tです.

H_FL=2なら2塁打です.

ヒット数ランキングを作る: dplyr

通算ヒット数ランキングを作ってみます.

BAT_IDでグループ化して和を取れば, 2013年の成績になります.

system.time(
dat %>% 
  select(BAT_ID, H_FL, AB_FL) %>% 
  mutate(AB_FL = ifelse(AB_FL=="T", 1,0)) %>% 
  mutate(HIT_FL = ifelse(H_FL>0, 1,0)) %>% 
  group_by(BAT_ID) %>% 
  summarise(PLATE=n(),
            ATBAT=sum(AB_FL),
            BASE=sum(H_FL),
            HIT = sum(HIT_FL)) %>% 
  arrange(desc(HIT)) %>% 
  mutate(AVERAGE = HIT / ATBAT) %>% 
  head(10)
)
##    user  system elapsed 
##   0.307   0.013   0.321

できました.

ヒット数ランキングを作る: nysol

同じことをnysolでやります. 参考

## nysolでやる
time sh cat ../all2013.csv | 
  mcut f=BAT_ID,H_FL,AB_FL | 
  mcal c='1' a=PLATE | 
  msed f=AB_FL c=T v=1 | 
  msed f=AB_FL c=F v=0 | 
  mcal c='if(${H_FL}>0 , 1, 0)' a=HIT_FL | 
  mstats k=BAT_ID f=PLATE:PLATE,AB_FL:ATBAT,H_FL:BASE,HIT_FL:HIT c=sum | 
  mcal c='round( ${HIT}/${ATBAT}, 0.001)' a='AVERAGE' | 
  mcut f=BAT_ID,PLATE,ATBAT,HIT,AVERAGE | 
  msortf f=HIT%nr | 
  head -n 10 "

できました.

mcal, mstatsの使い方を頑張って覚えれば, すぐに移行出来る気がします.

雑感

Rはデータ読み込みが遅いです. nysolはその点でとても速い気がします.

実験: 計算時間の比較 (19万行)

実行時間を測りました.

使用したデータは2013年メジャーリーグ全試合データ(77MB)でした.

Rだと, freadに2.0秒, 処理に0.3秒.

nysolだと, 全部で1.0秒.

集計処理自体はdplyrが早くて, 問題は読み込み時間.

追加実験: 計算時間の比較(1000万行)

使うデータを大きくして実行時間を測りました.

使用したデータは, 1920年からのメジャーリーグ全試合データ(4.3GB)です.

Rだと, freadに48秒, dplyrの処理に3秒.

nysolだと, 全部で16秒.

先程と同様, nysolが速いですが, 読み込めさえすればRは強そうです.

結論

Rで遅いのは読み込みのようです. dplyrは速いです.

ちなみに, pipeRを外しても実行時間はあまり変わりませんでした. pipeRよく分かんねえ.