Rで野球のデータを分析してみよう 1(大谷翔平のボール変化量等を算出)
2があるかはわかりません。
とりあえず目的設定してそのためにはどんな関数使うと便利かをまとめたものにします。
RとRstudioをインストールして初期設定をする
ここが詳しいです。(自分で書くよりいいと判断しました)
基本の操作:実行
これから実行という言葉を使ったら、とりあえず書いたコードの部分をドラッグしてCtrl+Enterを押すことだと思ってください。
tidyverseをインストールしよう!
便利なパッケージ、tidyverseをインストールしましょう。
細かいことを抜きにすればR Stduioのコード記述箇所に以下のコードを入力、実行しましょう。
install.packages("tidyverse")
細かい説明:install.packageという関数は「このパッケージをインストールします」というものです。つまり上記のコードが意味してるのは「"tidyverse"というパッケージをインストールします」ということです。
tidyverseはRで便利な関数を追加するものみたいな認識でOKです。
インストールしたらあとはR Studioを起動する度に以下のコードを実行するようにします。(これでtidyverseを使えます)
library(tidyverse)
※面倒ですがRを起動する度にこれを実行する必要があります。
自分はRでコードを書く時は先頭行にこれを書くようにしています。
投手大谷の球種別データを算出しよう!
とりあえず何か目的を設定して実行してみるのが取得の近道な気がします。
今回は投手大谷の大雑把な球種データ(球速や変化量等)の取得を目指します。
基データを入手する
大谷の2022年の投球データを入手しましょう。
今回はBaseball SavantのStatcast Searchを使います。
![](https://assets.st-note.com/img/1673482944769-hMrUHTPLVS.png?width=1200)
![](https://assets.st-note.com/img/1673483199727-vl74l32lTQ.png?width=1200)
とりあえずファイル名は"Ohtani_P.csv"にしましょう。(どんなファイル名でもいいですがアルファベット推奨)
保存場所については初期設定時の
"デフォルトの作業ディレクトリ(Working Directory)の設定"
で設定した場所にします。
![](https://assets.st-note.com/img/1673483351971-k9vRAxVSej.png?width=1200)
より
関数の紹介
ここからは関数を紹介していきます。
read.csv(csvファイルを読み込む関数)
#()内は先程保存したファイル名で
df <- read.csv("Ohtani_P.csv")
read.csvはcsvファイルを読み込むための関数です。
read.csv以外にも色々出たので説明していきます。
dfはここでは入れ物のようなものと思ってください。
(好きなアルファベットで可能です)
<- は矢印です。「←」でなく半角の「<」「-」で作ってください。
入れ物にしまうための指示記号と思ってください。
read.csvはRにcsvファイルを読み込むための関数です。
まとめると上記のコードは以下のことを実行しています。
dfという名前の入れ物に、read.csvで読み込んだデータ(Ohtani_P.csvの中身)を入れておくよ。
これでdfに大谷のデータが入りました。ここからはデータを加工する段階にはいります。
mutate(新しい列の作成)
Statcastのデータにはさまざまなデータが入っています。ところがそこにあるデータは日本人にとっては馴染みのない単位が使われています。
例えば…
release_speed … 投球の初速。mph表記。
pfx_x … 自由落下(重力のみの影響を受けたボールの変化量)を0としたときのボールの横変化量。feet表記。
pfx_z … 自由落下(重力のみの影響を受けたボールの変化量)を0としたときのボールの縦変化量。feet表記。
release_pos_x … ボールのリリース横位置。feet表記。
release_pos_z … ボールのリリース縦位置。feet表記。
メートル法に慣れた日本人にとってマイルやフィートは馴染みがなくこのまま計算してもピンと来ないでしょう。というわけでデータを加工します。
df <- df %>%
mutate(
release_speed_km = release_speed * 1.609,
pfx_x_cm = pfx_x * 30.48,
pfx_z_cm = pfx_z * 30.48,
release_x_cm = release_pos_x * 30.48,
release_z_cm = release_pos_z * 30.48))
mutateは新しい列を作成するということです。
()内にどんな列を作成するか書いてあげます。ここでは単位をメートル法にするために他の列の値を基に計算したものを入れます。
mutateの他に %>% が出てきました。これはパイプ演算子と呼ばれるものです。詳しい説明は置いておきましょう。とりあえずmutateとか関数を書く前に置いておきましょう。
まとめると上記のコードは以下のことを実行しています。
同じ行にあるrelease_speed に1.609を掛け算して得られた値をrelease_speed_kmという新しい名前の列に入れるよ。
同じ行にあるpfx_x に30.48を掛け算して得られた値をpfx_x_cmという新しい名前の列に入れるよ。
(以下略)
これでメートル法に直した新しい列が作成されました。
group_by(グループ分けする)
球種ごとにデータを算出するにはグループ分けする必要があります。
そのために使うのはgroup_by関数です。()内に列名を入れてその中の値ごとにグループ分けします。
ここではgropu_by()の()の中にはpitch_type(球種を表す列名)を入力します。
summarise(データの集計を行う)
summariseはデータの集計を行う関数です。
とりあえずよく使うもの。
n()…データの数を数える
sum()…合計
mean()…平均
sd()…標準偏差
max()…最大値
min()…最小値
median()…中央値
※()内は列名を入れる
na.rm=TRUE(欠損値を除く)
関数とは違いますが欠損値を除いて計算するために必要なもの。
Rは欠損値があると計算結果が全てNA(欠損値)扱いになります。
欠損値を除いて計算するためにはこれを()内に入れます。
↓使用例
mean_velo = mean(release_speed_km,na.rm=TRUE)
ここまでを踏まえてコードを書くとこうなります。
player_stats <- df %>%
group_by(pitch_type)%>%
dplyr::summarise(
N=n(),
mean_release_x = mean(release_x_cm,na.rm=TRUE),
mean_release_z = mean(release_z_cm,na.rm=TRUE),
max_velo = max(release_speed_km,na.rm=TRUE),
mean_velo = mean(release_speed_km,na.rm=TRUE),
mean_pfx_x = mean(pfx_x_cm,na.rm=TRUE),
mean_pfx_z = mean(pfx_z_cm,na.rm=TRUE),
mean_spin = mean(release_spin_rate,na.rm=TRUE))
このコードは以下のような意味になります。
player_statsという入れ物にdfという入れ物内のデータを基に計算(summarise)します。
計算する際は球種(pitch_type)でグループ分け(group_by)します。
計算内容:
データの数を数えます。(n),
平均値を計算します。(mean),
最大値を計算します。(max)
欠損値は無視します。(na.rm=TRUE)
write.csv(csvに入れ物内のデータを書き込む)
作ったデータをcsvファイルに書き出します。書き出したものは作業フォルダ内に出力されます。
write.csv(入れ物の名前(ここではplayer_statsです),"ファイル名.csv")
write.csv(player_stats,"球質.csv")
ここまでのコードを全て記述した結果
ここまでのコードを全て記述するとこんな感じになります。
実行してみましょう。
library(tidyverse)
df <- read.csv("Ohtani_P.csv")
df <- df %>%
mutate(release_speed_km = release_speed * 1.609,
pfx_x_cm = pfx_x*30.48,
pfx_z_cm = pfx_z*30.48,
release_x_cm = release_pos_x*30.48,
release_z_cm = release_pos_z*30.48)
player_stats <- df %>%
group_by(pitch_type)%>%
dplyr::summarise(
N=n(),
mean_release_x = mean(release_x_cm,na.rm=TRUE),
mean_release_z = mean(release_z_cm,na.rm=TRUE),
max_velo = max(release_speed_km,na.rm=TRUE),
mean_velo = mean(release_speed_km,na.rm=TRUE),
mean_pfx_x = mean(pfx_x_cm,na.rm=TRUE),
mean_pfx_z = mean(pfx_z_cm,na.rm=TRUE),
mean_spin = mean(release_spin_rate,na.rm=TRUE))
write.csv(player_stats,"球質.csv")
実行結果によって作られたフォルダの中身はこんな感じになるはずです。
![](https://assets.st-note.com/img/1673490356749-3uwXgSLW02.png?width=1200)
データを大雑把に見てわかること
・カーブの時はリリース高さがかなり高め
・スライダー・カットボールはリリースが横になりやすい
・スライダーは30cm以上曲がる
等々…
今回の関数を応用してみよう
とりあえず今回の関数を応用してみるなどして操作に慣れてみましょう。
例えばMLB入団以降の大谷の全てのデータを入手してgroup_byにgame_yearを追加すれば、年度ごとの球種の変化を見ることもできます。
![](https://assets.st-note.com/img/1673490776578-BcW4B4B6oW.png?width=1200)
次回があるとしたら、球種別の空振り率の出し方、打球速度や角度を一定の値で区切ってそれぞれの価値を算出する、球種を再定義してラベルを付けて分析するとかやるかもしれません。(やらないかもしれません)
この記事が気に入ったらサポートをしてみませんか?