← 記事一覧へ

三者凡退でリズムよく終わらせることに意味はあるのでしょうかね.

ちょっと確認してみましょう.

以下, 三者凡退を “3人連続凡退で攻撃終了” とします. ランナーを出してからのゲッツーはダメです. 三者が凡退して三者凡退ですからね.

データ

2013年のメジャーリーグのデータを利用します.

library(data.table)
library(dplyr)
library(ggplot2)
source("../../R/retrosheet.R")

dat <- fread("../../data/all2013.csv")
setnames(dat, fread("../../data/reference/retrosheet-columns.csv", header = FALSE)[[1]])

三者凡退の判定

イニングのアウト推移が長さ3で “012” であれば, 3人が連続でアウトになっています. 先頭打者出塁からのゲッツーで次打者もアウトだとアウト推移は “002” になるので, 区別できます.

sanbon_flag <-
  dat |>
  as_tibble() |>
  summarise(sanbon = paste(OUTS_CT, collapse = "") == "012",
            .by = c(GAME_ID, INN_CT, BAT_HOME_ID))

半イニングごとの得点

得点は各プレーで生還した走者を数えます. SCORE_CT 列はプレー「前」の値なので, 差分では最後のプレーの得点が 次の回に繰り越されてしまいます (R/retrosheet.R).

innings <- half_inning_runs(dat) |> as_tibble()

どのイニングを使うか

../comeback-wins/comeback-wins.Rmd と同じ問題があります.

9回裏はホームが勝っていれば行われません. また, サヨナラ勝ちの回は 3アウトを待たずに終わります. 全イニングを使うと, 「直前が三者凡退だったか」と「次の攻撃が存在するか・最後まで行われるか」が 絡んでしまいます.

イニング1〜8は必ず両チームが攻撃し3アウトで終わるので, そこに絞ります.

analysis <-
  innings |>
  inner_join(sanbon_flag, by = c("GAME_ID", "INN_CT", "BAT_HOME_ID")) |>
  arrange(GAME_ID, INN_CT, BAT_HOME_ID) |>
  mutate(直前が三者凡退 = lag(sanbon), .by = GAME_ID) |>
  filter(!is.na(直前が三者凡退), INN_CT <= 8)

対象は36,438半イニング, そのうち直前が三者凡退だったのは 32.0%です.

集計結果

by_flag <-
  analysis |>
  summarise(半イニング = n(), 平均得点 = mean(runs), 分散 = var(runs),
            .by = 直前が三者凡退) |>
  arrange(直前が三者凡退)
by_flag |> knitr::kable(digits = 4)
直前が三者凡退 半イニング 平均得点 分散
FALSE 24791 0.4746 0.9517
TRUE 11647 0.4666 0.9702

差は -0.0080 点/半イニング, 95%信頼区間は [-0.0296, +0.0137] です.

analysis |>
  summarise(平均得点 = mean(runs), n = n(), sd = sd(runs),
            .by = c(INN_CT, 直前が三者凡退)) |>
  mutate(se = sd / sqrt(n)) |>
  ggplot(aes(x = factor(INN_CT), y = 平均得点,
             colour = 直前が三者凡退, group = 直前が三者凡退)) +
  geom_line() +
  geom_pointrange(aes(ymin = 平均得点 - 1.96 * se, ymax = 平均得点 + 1.96 * se)) +
  xlab("イニング") +
  ggtitle("直前が三者凡退かどうか別の平均得点 (95%信頼区間)")

イニングと表裏を調整しても同じです.

fit <- lm(runs ~ 直前が三者凡退 + factor(INN_CT) + factor(BAT_HOME_ID), data = analysis)
co <- summary(fit)$coefficients["直前が三者凡退TRUE", , drop = FALSE]
round(co, 5)
##                    Estimate Std. Error  t value Pr(>|t|)
## 直前が三者凡退TRUE -0.00806    0.01099 -0.73349  0.46326

交絡: 三者凡退に抑えるのは強い投手

ここで気をつけたいことがあります.

直前の回を三者凡退に抑えたのは, 自軍の投手です. そして三者凡退にできる投手は, そうでない投手より良い投手である傾向があります. 良い投手を擁するチームは, 打線も強いとは限りませんが, 少なくとも独立ではありません.

つまりこの比較は「リズム」ではなく「チームの質」を拾っている可能性があります. チームを固定して見てみます.

fit2 <- lm(runs ~ 直前が三者凡退 + factor(INN_CT) + factor(BAT_HOME_ID) +
             factor(substr(GAME_ID, 1, 3)), data = analysis)
co2 <- summary(fit2)$coefficients["直前が三者凡退TRUE", , drop = FALSE]
round(co2, 5)
##                    Estimate Std. Error  t value Pr(>|t|)
## 直前が三者凡退TRUE -0.00548    0.01099 -0.49844  0.61817

球場 (ホームチーム) を入れても係数は-0.0081から -0.0055とほとんど動きません.

分布も見る

平均だけ見ていると, 「たまに大量得点する」のか「まんべんなく1点入る」のかが 分かりません.

analysis |>
  ggplot(aes(x = runs, fill = 直前が三者凡退)) +
  geom_bar(position = "dodge") +
  scale_x_continuous(breaks = 0:10, limits = c(-0.5, 8)) +
  xlab("その半イニングの得点") +
  ggtitle("得点の分布")

analysis |>
  summarise(無得点 = mean(runs == 0), `1点以上` = mean(runs >= 1),
            `3点以上` = mean(runs >= 3), .by = 直前が三者凡退) |>
  arrange(直前が三者凡退) |>
  knitr::kable(digits = 4)
直前が三者凡退 無得点 1点以上 3点以上
FALSE 0.7328 0.2672 0.0528
TRUE 0.7404 0.2596 0.0502

結論

差は-0.0080点で, 95%信頼区間は [-0.0296, +0.0137]です. 区間は0をまたいでおり, 向きすら確かではありません.

三者凡退で流れが来る, という感覚を支持する結果は出ませんでした.