メジャーリーグのデータ解析をしたい (K/BBの計算したら上原が凄い)
序論
Rを使ってメジャーリーグのデータ処理をします.
今回は前処理に役立つplyrパッケージを使いながら,
レッドソックスの上原浩治選手の成績を確認します.
今回使うのは, plyrパッケージです.
データのまとめにはとても便利です.
ddplyの使い方がわかると思います.
データの取得と指標の確認
データはlahmanのdatabaseを使います.
せっかくだから最新のバージョンを使います.
http://www.seanlahman.com/baseball-archive/statistics/
K/BBについて.
今年はレッドソックスのリリーバー上原浩治選手が大活躍でした.
最初は中継ぎ投手でしたが, 後半からは安定した守護神として勝利に貢献していました.
安定したピッチングをする投手を評価する指標として, K/BBというものがあります.
Kは奪三振(Knock out), BBは四球(Base on Balls)です.
奪三振数 / 四球数 で計算されます.
Wikipediaより... K/BBの説明
奪三振と与四球は守備や球場の影響を受けないため、K/BBはシーズン毎のバラつきが小幅で、投手の制球力を示す。 また、好投手ならば一般的にK/BBが2.00を下回る事が少なく[1]、優秀な投手は3.50を超える事が多い。
フォアボールが少なく, 三振が多く取れるピッチングをするとK/BBは高くなります.
しっかりコントロールしながら三振が取れる選手が評価できます.
コントロールを重視すると球威が落ちて三振が取れません.
三振を重視すると, 球威のためにコントロールが落ちて四球が増えます.
K/BBはなかなか奥深い指標です.
通算K/BBの計算
今回はPitching.csvを使います.
Pitchingデータの内容を確認します.
> Pitching <- read.csv("Pitching.csv") > head(Pitching) playerID yearID stint teamID lgID W L G GS CG SHO SV IPouts H ER HR BB SO BAOpp ERA IBB WP HBP BK BFP GF R SH SF GIDP 1 bechtge01 1871 1 PH1 <NA> 1 2 3 3 2 0 0 78 43 23 0 11 1 NA 7.96 NA NA NA 0 NA NA 42 NA NA NA 2 brainas01 1871 1 WS3 <NA> 12 15 30 30 30 0 0 792 361 132 4 37 13 NA 4.50 NA NA NA 0 NA NA 292 NA NA NA 3 fergubo01 1871 1 NY2 <NA> 0 0 1 0 0 0 0 3 8 3 0 0 0 NA 27.00 NA NA NA 0 NA NA 9 NA NA NA 4 fishech01 1871 1 RC1 <NA> 4 16 24 24 22 1 0 639 295 103 3 31 15 NA 4.35 NA NA NA 0 NA NA 257 NA NA NA 5 fleetfr01 1871 1 NY2 <NA> 0 1 1 1 1 0 0 27 20 10 0 3 0 NA 10.00 NA NA NA 0 NA NA 21 NA NA NA 6 flowedi01 1871 1 TRO <NA> 0 0 1 0 0 0 0 3 1 0 0 0 0 NA 0.00 NA NA NA 0 NA NA 0 NA NA NA >
なるほど.
SOが奪三振, BBが四球ですね.
では, 通算SOと通算BB を計算して, 通算K/BBを調べてみます.
# データ読み込み Pitching <- read.csv("Pitching.csv") # 重いので2000年以降に限る Pitching <- subset(Pitching, yearID> 2000) # plyrを使ってデータを要約 Pitching.KBB <- ddply(Pitching, .(playerID), summarize, Career.SO = sum(SO, na.rm = TRUE), Career.BB = sum(BB, na.rm=TRUE), Career.IPouts = sum(IPouts, na.rm = TRUE), Career.KBB = sum(SO, na.rm=TRUE)/ sum(BB, na.rm = TRUE))
内容を確認します.
> head(Pitching.KBB) playerID Career.SO Career.BB Career.IPouts Career.KBB 1 aardsda01 305 169 919 1.804734 2 abadfe01 97 43 367 2.255814 3 abbotpa01 218 191 999 1.141361 4 abreuju01 12 3 20 4.000000 5 abreuwi01 38 19 133 2.000000 6 accarje01 205 111 854 1.846847
投球回が少ないために四球0で引退した残念な選手もいますので,
100イニング以上投げた投手に限定して, 通算K/BBのランキングを見ます
# 四球1以上でアウトを300個以上とった選手 Pitching.KBB <- subset(Pitching.KBB, Career.BB > 0 & Career.IPouts >= 300) # K/BBで並べ替え Pitching.KBB <- Pitching.KBB[order(Pitching.KBB$Career.KBB, decreasing = TRUE), ]
確認します.
> head(Pitching.KBB) playerID Career.SO Career.BB Career.IPouts Career.KBB 1947 ueharko01 332 38 858 8.736842 1723 schilcu01 1377 212 4077 6.495283 1644 romose01 335 60 881 5.583333 1601 riverma01 778 142 2494 5.478873 1296 mujiced01 350 68 1318 5.147059 497 doolise01 120 24 349 5.000000
ueharako01 ... 一体何者なんだ...
せっかくだから可視化します. 上位10人だけ考えます.
ただのplotではなくてggplot2します.
library(ggplot2) Pitching.KBB.top10 <- head(Pitching.KBB, 10) ggplot(Pitching.KBB.top10, aes(x = playerID, y = Career.KBB)) + geom_bar(stat="identity")
こんな感じです.
上原すごいですね.
以上です.
plyrパッケージについて
これを読みます.
「plyrパッケージで君も前処理スタ☆」改め「plyrパッケージ徹底入門」
http://www.slideshare.net/teramonagi/tokyo-r30-20130420
よくわかりました.
plyrは, 分割して, 処理して, まとめます,
コードを見返してみると,
Pitching.KBB <- ddply(Pitching, .(playerID), summarize, Career.SO = sum(SO, na.rm = TRUE), Career.BB = sum(BB, na.rm=TRUE), Career.IPouts = sum(IPouts, na.rm = TRUE), Career.KBB = sum(SO, na.rm=TRUE)/ sum(BB, na.rm = TRUE))
となっています.
playerIDで分割して, 選手ごとの成績データフレームが得られます.
選手の成績でsumを取れば, 通算成績になります.
plyrの練習...年度別チーム防御率の算出
もう少し遊んでみます.
年度別チーム防御率ランキングを作ります.
手順としては,
1. plyrで, チームと年度で分割して, 各選手のデータで和を取る.
2. 合計自責点と合計投球回から防御率を計算.
3. 防御率で並べ替え
ですが, コードはこんな感じになります.
# データ読み込み Pitching <- read.csv("Pitching.csv") # 2000年以降 Pitching <- subset(Pitching, yearID > 2000) # チーム防御率を計算 # teamIDとyearIDで分割して成績を統合すればいい # 1アウトあたり失点 × 27 で防御率になる Pitching.teamERA <- ddply(Pitching, .(teamID, yearID), summarize, teamIPouts = sum(IPouts, na.rm=TRUE), teamER = sum(ER, na.rm=TRUE), teamERA = teamER / teamIPouts * 27) head(Pitching.teamERA) # 並べ替え Pitching.teamERA.ordered <- Pitching.teamERA[order(Pitching.teamERA$teamERA), ]
結果を見ます.
> head(Pitching.teamERA.ordered) teamID yearID teamIPouts teamER teamERA 275 PHI 2011 4431 496 3.022343 19 ATL 2002 4402 511 3.134257 183 LAN 2003 4373 511 3.155042 30 ATL 2013 4351 512 3.177201 354 TBA 2012 4379 518 3.193880 327 SFN 2011 4404 523 3.206403
簡単に出来ました. 年度とチームで分割してまとめただけです.
plyrを上手に使うと楽しいです.
... 2011年のフィリーズはチーム防御率3.02...???
"野球の記録で話したい"
3本柱は太かった フィラデルフィア・フィリーズ2011年投手|2011年MLBレビュー
http://baseballstats2011.jp/archives/889585.html
すごいわ.
追記
データの数値による並べ替えはarrange関数でいいですね.
わざわざorderでゴニョゴニョやるのは面倒です.
Pitching.teamERA.ordered <- arrange(Pitching.teamERA, teamERA)
の方が簡単です.