Statcastデータから見るコースに逆らわない打撃の有効性
内角の球は引っ張り、外角の球は流し打ち、といったコースに逆らわない打撃は有効だと言われる。実際にそのような傾向はあるのだろうか。探っていきたいと思う。
検証
2015-2020のMLBを対象にBaseball Savantから入手したStatcastのデータを使い検証する。投球コースは14㎝ずつ内角ボール、内角、真ん中、外角、外角ボールと5分割した。(投球の高さは考慮しない)
打球は3方向、引っ張り(Pull)、センター方向(Cent)、流し打ち(Opp)に分割した。
このように分割した投球コースの打球方向別の打撃指標を見ていく。
wOBAcon
plate_x_cmはStatcastのplate_xをcmに変換したものである。値が低いほど内寄りのコースであることを意味し値が高いほど外寄りのコースであることを意味する。左打者は値を反転させている。
wOBAconは打球当たりの得点創出を表している。値が高いほど得点価値の高い打球を放っていると思ってもらっていい。wOBAconは右打者・左打者とも真ん中より内側は引っ張りの値が最も高くなっている。真ん中の球はセンター返しをするよりも引っ張ったほうが高い価値を生むようだ。外角寄りの球ではセンター返し、流し打ちの打球の価値が高くなる。
真ん中のコースの投球は引っ張ったほうがよいという結果になったが内側の球は引っ張り、外側の球は流し打ちをすると良い結果に繋がりやすいという言説はだいたい当てはまっているようだ。
右と左の違いに注目すると外側の球に対しての右打者の流し打ちより左打者の流し打ちのが効果的そうだ。(特に外のボール球で顕著だ)左打者の流し打ちは内野安打が発生しやすいというのも理由の1つだろう。また引っ張りは右打者の方が全体的に値が高いのも特徴だ。
BAcon
BAconは打球当たりの打率を表している。BAconで見てみると右打者では真ん中より内側では引っ張りが最も高くなっている。一方で左打者では真ん中の球についてはセンター返しが最も高くなっている。
右打者の流し打ちは左打者ほど外角の球に対してもあまり有効ではなくセンター返しの方がむしろ有効となっている。
ISOcon
ISOconは打球当たりの純粋な長打力を表す指標だ。基本的に引っ張りは真ん中より内側ではずば抜けて高い値になっている。長打を狙うには真ん中より内側の球は引っ張った方が良さそうだ。外側の球では引っ張りよりセンター方向や流し打ちのが値が高くなっている。ISOconについては左右とも共通した傾向にあるようだ。
打球角度
内側の球ほど打球の角度が高く引っ張るほど打球角度が低くなる傾向にあるようだ。
打球速度
内側のコースでは比較的引っ張りが打球速度が速くなり外側のコースでは流し打ち・センター方向が比較的打球速度が速くなる。
まとめ
・引っ張りは内側と真ん中では全打球のなかで最も価値が高くなり外側では価値が低くなる。
・流し打ちは内側~真ん中では価値が低く外側では価値が高くなる。
・センター方向は内側では価値が低く真ん中~外側で価値が高くなる。
・左右の違いに注目すると左は流し打ちが右は引っ張りが価値が高くなりやすい。
真ん中はセンター方向ではなく引っ張りが最も価値が高いという結果になったもののよく言われる言説通りの結果になったのではないだろうか。
今回の分析にはNPBでの先行研究がある。(デルタ・ベースボール・リポート2(水曜社)『コースに逆らわない打撃は本当に有効なのか』市川博久)
NPBでの先行研究と比較すると真ん中より内側は引っ張りが有効になる、引っ張りは右打者のが価値が高くなりやすい等、共通する要素がある。これらは野球の構造上強固なものなのかもしれない。
以下、今回の分析に使ったRのコード。
#dfには2015-2020のStatcastの全データが入っている
#必要なデータに絞る
df <- df %>%
select(events, type,game_type,launch_angle,launch_speed,woba_denom,woba_value,iso_value,
batter,plate_x,stand,hc_x, hc_y)
save(df, file="sc_data_for_direction.Rdata")
#データの下処理
df <- df %>% filter(game_type == "R")
df <- df %>% filter(type == "X")
df <- df %>% mutate(
spray_angle = atan2(hc_x - 125.42, 198.27 - hc_y) * 180 / pi,
hand_adj_spray =
ifelse(stand == "L", - spray_angle, spray_angle),
Pull_FL = ifelse(hand_adj_spray <= -17, 1,0),
Cent_FL = ifelse(hand_adj_spray > -17 & hand_adj_spray < 17 , 1, 0),
Opp_FL = ifelse(hand_adj_spray >= 17, 1, 0),
direction = case_when(
hand_adj_spray <= -17 ~ "Pull",
hand_adj_spray > -17 & hand_adj_spray < 17 ~ "Cent",
hand_adj_spray >= 17 ~ "Opp"),
Bat_L_FL = ifelse(stand == "L", 1, 0),
H = case_when(
events == "single" ~ 1,
events == "double" ~ 1,
events == "triple" ~ 1,
events == "home_run" ~ 1,),
#コースをcmに変換、左右で内外の値を揃える
plate_x_r_cm = plate_x * 30.48,
plate_x_cm = ifelse(stand == "R",plate_x_r_cm,-1 * plate_x_r_cm))
#コースを分ける
Group <- seq(-35,35,14)
df$plate_x_bin <- with(df, cut(plate_x_cm, Group))
#コース別、打球方向別、左右別打撃指標を算出。
course_batX <- df%>%
group_by(stand, plate_x_bin,direction)%>%
dplyr::summarise(
mean_angle = mean(launch_angle, na.rm = TRUE),
mean_velo = mean(launch_speed, na.rm = TRUE),
wOBAcon_value = sum(woba_value, na.rm = TRUE),
wOBAcon_denom = sum(woba_denom, na.rm = TRUE),
wOBAcon = wOBAcon_value / wOBAcon_denom,
BAcon = sum(H, na.rm = TRUE)/ (wOBAcon_denom),
ISOcon = mean(iso_value, na.rm = TRUE)
)%>%
select(stand,plate_x_bin,direction,
wOBAcon,
BAcon,
ISOcon,
mean_angle,
mean_velo,
wOBAcon_denom)
write_csv(course_batX,"course_batX.csv")
この記事が気に入ったらサポートをしてみませんか?