各球種の球速・変化タイプ別RV/100 と球種別各球速帯の変化量

RV/100とはストライクを取る、凡打にさせたなど相手の得点を防いだ事象についてはマイナスの得点価値がボール球を投げる、安打を許すなど相手の得点の見込みを増やす事象についてはプラスの得点価値が与えられる指標で投手にとっては低ければ低いほど得点を防ぐことを意味する指標だ。

そのRV/100を各球種の各球速帯、各変化グループにグループ分けをした。グループ化の方法は球速は5km/hで刻み、ボール変化グループは各球速帯の平均変化量より7.5cm未満ならNOMAL、横変化については利き手側に7.5cm以上変化してるならARM、グラブ側に7.5cm以上変化してるならGLOVE、縦変化については上方向に7.5cm以上変化するならRISE、7.5cm以上下方向に落下してるならDROPとする。

これは先行研究であるデルタ・ベースボール・リポート4(水曜社:2021年)『変化量とRun Valueが示す本当に有効なボールとは? (八代 久通)』と全く同じである。

スライダー(RV/100)

SL グループ

スライダーはGLOVE側に変化する球は基本的に有効、球速が遅いとRISEする球質が、球速が速いとDROPする方が有効になるという傾向にあるようだ。

手法は同じはずだが『変化量とRun Valueが示す本当に有効なボールとは?』と比較すると140-145km/hのARM-DROPの結果など若干異なっている。(先行研究ではGLOVE-DROPの方がRVが優れている)これについては理由がよくわからない。(statcastのdelta_run_expの平均をとったり対象期間が2017-2020などやや異なるがそれで差が出た?)

各球種の各球速帯の平均変化量

RV/100の結果については先行研究とやや異なる結果が出たが(他の球種については『変化量とRun Valueが示す本当に有効なボールとは?』を読んでもらったほうが良いと思われる。一応自作のRのコードをこのページの下部には記載しておく)今回気になったのは変化グループについては「各球速帯の平均変化量」を基準にしている点だ。おそらくこれは球種によっては球速帯によって変化量が異なるのを考慮したものだと思われる。ここからは各球種について各球速帯の平均変化量を見ていく。

フォーシーム

画像2

フォーシームは球速によって変化量があまり変わらないという結果になった。

シンカー(ツーシーム)

画像3

シンカーは球速によってやや縦変化が大きくなる傾向にある。

カットボール

画像4

カットボールは球速帯によって縦の変化量が大きく異なっている。

スライダー

スライダー

スライダーは球速が上がると横変化が小さく、縦変化が大きく(RISEする)傾向にある。

カーブ

画像6

カーブもスライダーと同様に球速が上がるごとに変化が小さくなる傾向にあるようだ。

チェンジアップ(スプリット含む)

画像7

チェンジアップは球速が上がるとむしろ縦変化が小さくなる(沈む)傾向にあるようだ。

今回の分析にはMLB17-20のstatcastデータを利用した。データはBaseball Savantから入手した。

library(tidyverse)

#dfには2017-2020のMLBのデータが入っている

df <- df %>%
 mutate(velocity = release_speed * 1.609,
        pfx_x_cm = ifelse(p_throws == "R",pfx_x*30.48,pfx_x*-30.48),
        pfx_z_cm = pfx_z*30.48,
        pitch_type = case_when(
          pitch_type == "FF" ~ "FF", 
          pitch_type == "FT" | pitch_type == "SI" ~ "SI",
          pitch_type == "SL"  ~ "SL",
          pitch_type == "FC"  ~ "FC",
          pitch_type == "CU" | pitch_type == "KC" ~ "CU",
          pitch_type == "CH" | pitch_type == "FS" ~ "CH"),
        strike_count = ifelse(strikes == 2,"2strikes","non2strikes"),
        throw_stand = ifelse(p_throws == "R" & stand == "R" | p_throws == "L" & stand == "L" ,"same","difference"))

Group <- seq(120,160,5)

df$velocity_bin <- with(df,cut(velocity,Group))

pitch_type <- df %>%
 group_by(pitch_type,velocity_bin)%>%
 dplyr::summarise(mean_x = mean(pfx_x_cm,na.rm=TRUE),
                  mean_z = mean(pfx_z_cm,na.rm=TRUE))

df <- left_join(df,pitch_type)

df <- df %>%
 mutate(
   h_mov = case_when(
     pfx_x_cm <= mean_x +7.5 & pfx_x_cm >= mean_x - 7.5 ~ "NOMAL",
     pfx_x_cm > mean_x + 7.5 ~ "GLOVE",
     pfx_x_cm < mean_x - 7.5 ~ "ARM",
     TRUE ~ "ELSE"),
   v_mov = case_when(
     pfx_z_cm <= mean_z + 7.5 & pfx_z_cm >= mean_z - 7.5 ~ "NOMAL",
     pfx_z_cm > mean_z + 7.5 ~ "RISE",
     pfx_z_cm < mean_z - 7.5 ~ "DROP",
     TRUE ~ "ELSE"),
   move_type = paste(h_mov,"-",v_mov))


move_type_RV <- df %>%
 group_by(velocity_bin,pitch_type,move_type)%>%
 dplyr::summarise(N=n(),
                  RV_100 = round(mean(delta_run_exp,na.rm=TRUE)*100,2))%>%
 filter(N>=1000)%>%
 select(velocity_bin,pitch_type,move_type,RV_100)

write_csv(move_type_RV,"変化タイプ別RV.csv")

write_csv(pitch_type,"球速帯別変化量.csv")

この記事が気に入ったらサポートをしてみませんか?