Lahmanのデータベースを使って, 歴代の打者成績推移をrChartsで可視化します.
データは http://seanlahman.com/files/database/lahman-csv_2014-02-14.zip でダウンロードできます.
解凍したら, Batting.csvとMaster.csvを使います.
library(rCharts)
library(RPostgreSQL)
library(dplyr)
library(magrittr)
library(xtable)
# 各打者のシーズン記録のまとめデータ: Batting.csv
dat = fread("Batting.csv")
データの中身はこんな感じです.
head(dat) %>% xtable() %>% print(type="html")
| playerID | yearID | stint | teamID | lgID | G | G_batting | AB | R | H | X2B | X3B | HR | RBI | SB | CS | BB | SO | IBB | HBP | SH | SF | GIDP | G_old | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | aardsda01 | 2004 | 1 | SFN | NL | 11 | 11 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 11 |
| 2 | aardsda01 | 2006 | 1 | CHN | NL | 45 | 43 | 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 45 |
| 3 | aardsda01 | 2007 | 1 | CHA | AL | 25 | 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 |
| 4 | aardsda01 | 2008 | 1 | BOS | AL | 47 | 5 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 5 |
| 5 | aardsda01 | 2009 | 1 | SEA | AL | 73 | 3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | |
| 6 | aardsda01 | 2010 | 1 | SEA | AL | 53 | 4 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
# 選手をidで扱うのは淋しいので, フルネームを調べます
# フルネームはMaster.csvから作ります.
fullname_and_id =
fread("Master.csv") %>%
mutate(fullname = paste(nameFirst, nameLast, sep=" ")) %>%
dplyr::select(lahman40ID, fullname) %>%
setnames(c("playerID", "fullname"))
# 2012年までに3000本安打を超えている選手で遊びます
bat_over_3000 =
dat %>% group_by(playerID) %>%
dplyr::summarise(HIT = sum(H)) %>%
filter(HIT >= 3000) %>%
select(playerID)
# フルネームとIDを統合
batters = bat_over_3000 %>% inner_join(fullname_and_id, by="playerID")
# 3000本打った選手の成績まとめ
batters_data = batters %>% inner_join(dat, by = "playerID")
# シーズン中に移籍すると, データが別の行になります.
# 欲しいのは年度別の成績なので, 年度が同じなら成績はマージします
# 移籍はなかったことにします.
batters_data_hit =
batters_data %>%
dplyr::select(fullname, yearID, G, AB, H, HR, SO) %>%
group_by(fullname, yearID) %>%
dplyr::summarise(game = sum(G), atbat = sum(AB), hit = sum(H), homerun = sum(HR), so = sum(SO))
# デビューの年をチェックします
start = batters_data_hit %>%
group_by(fullname) %>%
dplyr::summarise(start = min(yearID))
# 最近の選手かどうか. 1975以降かどうかで場合分け
batters_data_hit =
batters_data_hit %>% inner_join(start, by="fullname") %>%
mutate(recent = ifelse(start > 1970, "recent", "old"))
# できたデータ
head(batters_data_hit) %>% xtable() %>% print(type="html")
| fullname | yearID | game | atbat | hit | homerun | so | start | recent | |
|---|---|---|---|---|---|---|---|---|---|
| 1 | Al Kaline | 1953 | 30 | 28 | 7 | 1 | 5 | 1953 | old |
| 2 | Al Kaline | 1954 | 138 | 504 | 139 | 4 | 45 | 1953 | old |
| 3 | Al Kaline | 1955 | 152 | 588 | 200 | 27 | 57 | 1953 | old |
| 4 | Al Kaline | 1956 | 153 | 617 | 194 | 27 | 55 | 1953 | old |
| 5 | Al Kaline | 1957 | 149 | 577 | 170 | 23 | 38 | 1953 | old |
| 6 | Al Kaline | 1958 | 146 | 543 | 170 | 16 | 47 | 1953 | old |
通算成績の積み上げの様子を見てみます.
# ひたすらcumsumします
career_data =
batters_data_hit %>% group_by(fullname) %>%
dplyr::summarise(yearID = yearID,
careerHIT= cumsum(hit),
careerHR = cumsum(homerun),
careerSO = cumsum(so),
careerGAME=cumsum(game),
recent = recent
)
# できたデータ
head(career_data) %>% xtable() %>% print(type="html")
| fullname | yearID | careerHIT | careerHR | careerSO | careerGAME | recent | |
|---|---|---|---|---|---|---|---|
| 1 | Al Kaline | 1953 | 7 | 1 | 5 | 30 | old |
| 2 | Al Kaline | 1954 | 146 | 5 | 50 | 168 | old |
| 3 | Al Kaline | 1955 | 346 | 32 | 107 | 320 | old |
| 4 | Al Kaline | 1956 | 540 | 59 | 162 | 473 | old |
| 5 | Al Kaline | 1957 | 710 | 82 | 200 | 622 | old |
| 6 | Al Kaline | 1958 | 880 | 98 | 247 | 768 | old |
# hPlotで可視化してみる
hp2 = hPlot(data = career_data, x="yearID", y="careerHIT", group = "fullname", type="line")
hp2$chart(forceY = "#![0]!#")
hp2$show("iframesrc", cdn = TRUE)
これは通算ヒット数の積み上げの様子です. 1970年代以降に, レジェンドプレーヤーが固まっているように見えますね.
割と最近の選手の成績だけ見てみると,
data_recent = career_data %>% filter(recent == "recent")
hp = hPlot(data = data_recent, x="yearID", y="careerHIT", group="fullname", type="line")
hp$show("iframesrc", cdn = TRUE)
こんな感じです.
ホームラン数も見たいです.
hp2 = hPlot(data = career_data, x="yearID", y="careerHR", group = "fullname", type="line")
hp2$chart(forceY = "#![0]!#")
hp2$show("iframesrc", cdn = TRUE)
1940年台に何かが起きていることが分かります. 優秀な打者が増えていますし, ホームランの数も劇的に増えています.
三振の数も見ます.
hp2 = hPlot(data = career_data, x="yearID", y="careerSO", group = "fullname", type="line")
hp2$chart(forceY = "#![0]!#")
hp2$show("iframesrc", cdn = TRUE)
古いデータには欠損があるみたいですね. 最近の選手だけ見ます
hp = hPlot(data = data_recent, x="yearID", y="careerSO", group="fullname", type="line")
hp$show("iframesrc", cdn = TRUE)
一人半端ない人がいますね…
“通算の打数/三振比率21.4という数字はバッティングスタイルを比較されるイチロー(約10)と比べても倍以上高い”
ひいい
以上です.