Bóng chày luôn không ngừng biến đổi qua thời gian, nhưng ít có xu hướng nào thể hiện sự chuyển mình rõ rệt như sự gia tăng của những cú home run. Một thế kỷ trước, việc ghi được vài cú home run trong cả mùa giải đã là thành tích đáng kinh ngạc. Ngày nay, đó lại là kỳ vọng tối thiểu đối với mỗi đội bóng. Nhờ sự cải tiến trong huấn luyện, kỹ thuật phân tích dữ liệu và thậm chí là sự thay đổi cấu trúc quả bóng, số lượng home run đã tăng vọt qua từng mốc lịch sử. Hãy cùng khám phá câu chuyện này qua dữ liệu giải bóng chày chuyên nghiệp Mỹ từ năm 1901 đến nay bằng ngôn ngữ lập trình R.

Chuẩn bị và xử lý dữ liệu lịch sử với Lahman
Để thực hiện bài phân tích, chúng ta sử dụng bộ dữ liệu Lahman, một trong những cơ sở dữ liệu lịch sử toàn diện nhất về bóng chày. Dữ liệu chứa thông tin chi tiết về từng mùa giải, đội bóng và cầu thủ qua hơn một thế kỷ.
Bước đầu tiên là cài đặt các thư viện cần thiết và tính toán chỉ số home run trung bình trên mỗi trận đấu cho toàn giải đấu qua từng năm. Vì mỗi trận đấu luôn có hai đội tham gia, tổng số trận của toàn giải sẽ bằng tổng số trận các đội thi đấu chia cho hai.
1packages <- c("tidyverse", "Lahman", "scales", "gganimate", "gifski")
2to_install <- packages[!packages %in% installed.packages()[, "Package"]]
3if (length(to_install)) install.packages(to_install, dependencies = TRUE)
4library(tidyverse)
5library(Lahman)
6library(scales)
7library(gganimate)
8library(gifski)
9season_hr <- Teams %>%
10 filter(!is.na(HR), !is.na(G), yearID >= 1901) %>%
11 group_by(yearID) %>%
12 summarise(
13 hr_total = sum(HR, na.rm = TRUE),
14 games_team_total = sum(G, na.rm = TRUE),
15 .groups = "drop"
16 ) %>%
17 mutate(
18 games_league = games_team_total / 2,
19 hr_per_game = hr_total / games_league
20 )
21peak <- season_hr %>% slice_max(hr_per_game, n = 1)
22latest_year <- max(season_hr$yearID, na.rm = TRUE)Xây dựng biểu đồ xu hướng theo thời gian
Sau khi đã chuẩn bị xong chuỗi dữ liệu, bước tiếp theo là dựng biểu đồ đường để quan sát xu hướng biến động. Chúng ta kết hợp đường xu hướng làm mịn bằng phương pháp loess để thấy rõ định hướng dài hạn, đồng thời đánh dấu điểm đỉnh cao nhất từng ghi nhận trong lịch sử.
1p_static <- ggplot(season_hr, aes(yearID, hr_per_game)) +
2 geom_line(linewidth = 1) +
3 geom_smooth(se = FALSE, method = "loess", span = 0.2) +
4 geom_point(data = peak, aes(yearID, hr_per_game), size = 3) +
5 ggrepel::geom_text_repel(
6 data = peak,
7 aes(label = paste0("Peak: ", yearID, "\n", round(hr_per_game, 2), " HR/game")),
8 nudge_y = 0.1,
9 min.segment.length = 0
10 ) +
11 scale_x_continuous(breaks = pretty_breaks()) +
12 scale_y_continuous(labels = label_number(accuracy = 0.01)) +
13 labs(
14 title = "The Home Run Boom in MLB",
15 subtitle = paste0("League-wide home runs per game, 1901–", latest_year),
16 x = "Season",
17 y = "Home runs per game (league-wide)",
18 caption = "Source: Lahman Baseball Database | Made in R"
19 ) +
20 theme_minimal(base_size = 13) +
21 theme(
22 plot.title = element_text(face = "bold"),
23 plot.caption = element_text(margin = margin(t = 8))
24 )
25ggsave("mlb_hr_per_game.png", p_static, width = 10, height = 6.2, dpi = 220)
So sánh xu hướng giữa Giải Mỹ và Giải Quốc gia
Mỗi liên đoàn trong giải đấu đều có những quy định và đặc thụ vận hành riêng. Việc tách dữ liệu theo hai liên đoàn AL và NL giúp xác định xem liệu đà tăng trưởng này xảy ra trên toàn bộ hệ thống hay chỉ tập trung ở một nhóm đội bóng nhất định.
1season_hr_lg <- Teams %>%
2 filter(!is.na(HR), !is.na(G), yearID >= 1901, !is.na(lgID)) %>%
3 group_by(yearID, lgID) %>%
4 summarise(
5 hr_total = sum(HR, na.rm = TRUE),
6 games_team_total = sum(G, na.rm = TRUE),
7 .groups = "drop_last"
8 ) %>%
9 mutate(games_league = games_team_total / 2, hr_per_game = hr_total / games_league) %>%
10 ungroup()
11p_facets <- ggplot(season_hr_lg, aes(yearID, hr_per_game)) +
12 geom_line() +
13 geom_smooth(se = FALSE, method = "loess", span = 0.25) +
14 facet_wrap(~ lgID, nrow = 2) +
15 labs(
16 title = "AL vs NL: home runs per game over time",
17 subtitle = paste0("1901–", latest_year),
18 x = "Season",
19 y = "HR per game",
20 caption = "Source: Lahman Baseball Database | Made in R"
21 ) +
22 theme_minimal(base_size = 12) +
23 theme(plot.title = element_text(face = "bold"))
24ggsave("mlb_hr_per_game_al_vs_nl.png", p_facets, width = 10, height = 7, dpi = 220)
Tạo hiệu ứng động sinh động với gganimate
Trực quan hóa dạng động giúp người xem theo dõi hành trình lịch sử theo từng năm một cách tự nhiên. Sử dụng gói gganimate, đường biểu đồ sẽ vẽ tiến trình phát triển từ quá khứ đến hiện tại.
1p_anim <- ggplot(season_hr, aes(yearID, hr_per_game)) +
2 geom_line() +
3 geom_point(size = 1.5) +
4 labs(
5 title = "MLB Home Runs per Game — {closest_state}",
6 subtitle = paste0("1901–", latest_year),
7 x = "Season",
8 y = "HR per game",
9 caption = "Source: Lahman Baseball Database | Made in R (gganimate)"
10 ) +
11 theme_minimal(base_size = 13) +
12 transition_reveal(yearID)
13animate(
14 p_anim, width = 900, height = 540, fps = 30, duration = 12, end_pause = 10,
15 renderer = gifski_renderer("mlb_hr_per_game.gif")
16)
Bức tranh lịch sử đằng sau những con số
Nhìn vào đường biểu đồ, các giai đoạn phát triển của thể thao đỉnh cao hiện ra rất rõ ràng qua từng thập kỷ.
Giai đoạn bóng chết từ thập niên 1900 đến 1910 ghi nhận tỷ lệ cực kỳ thấp. Các cầu thủ ném bóng làm chủ hoàn toàn trận đấu do chất liệu quả bóng khi đó khá mềm và chiến thuật thi đấu thiên về kiểm soát bóng ngắn.
Giai đoạn từ thập niên 1920 đến 1950 đánh dấu sự xuất hiện của kỷ nguyên sức mạnh với đại diện tiêu biểu là Babe Ruth. Lối chơi chuyển dịch sang hướng tấn công chủ động và home run trở thành vũ khí hàng đầu.
Giai đoạn thập niên 1990 đến 2000 chứng kiến sự bùng nổ vượt ngưỡng trung bình 1 cú đánh mỗi trận. Kỹ thuật thể lực và chiến thuật tấn công đạt đỉnh cao mới.
Từ thập niên 2010 đến nay là cuộc cách mạng góc phát lực. Việc ứng dụng công nghệ theo dõi quỹ đạo giúp cầu thủ tối ưu hóa góc đánh nhằm tạo ra tầm bay xa nhất. Đến năm 2019, giải đấu đã chạm mốc kỷ lục lịch sử với 1.39 cú home run mỗi trận, gấp hơn 6 lần so với thời kỳ năm 1910.

Ý nghĩa đối với phân tích dữ liệu và thị trường dự đoán
Sự thay đổi về tần suất home run mang lại nhiều bài học giá trị cho các nhà phân tích dữ liệu và mô hình hóa:
Điều chỉnh hạn mức điểm số: Khi tổng số cú đánh tăng, điểm số trung bình mỗi trận tăng theo. Các mô hình dự đoán phải cập nhật điểm mốc tổng số bàn thắng lên cao hơn so với lịch sử.
Chỉ số ảnh hưởng của sân thi đấu: Kích thước và độ cao của các sân vận động tác động trực tiếp đến khả năng bóng ra ngoài biên. Sự kết hợp giữa lối đánh tối ưu góc vung gậy và yếu tố địa lý tạo ra biến số lớn cho các chỉ số dự báo cá nhân.
Tránh thiên kiến dữ liệu gần: Tỷ lệ home run không tăng cố định mà luôn biến động theo các điều kiện vật lý như cấu tạo bóng hay quy định vùng ném bóng. Việc chỉ dùng dữ liệu ngắn hạn dễ dẫn đến những dự báo sai lệch khi luật chơi thay đổi.
✨ Giá trị đắt giá từ bài phân tích:
Phân tích chuỗi thời gian cần gắn liền với bối cảnh lịch sử. Sự thay đổi trong dữ liệu không chỉ đến từ yếu tố ngẫu nhiên mà phản ánh trực tiếp sự tiến hóa của công nghệ, vật liệu và chiến thuật trong thực tế. Việc kết hợp kỹ năng xử lý dữ liệu bằng R cùng tư duy lịch sử giúp nhà phân tích nhìn thấy bản chất thực sự đằng sau những đỉnh nhọn trên biểu đồ.
Câu hỏi tư duy hoặc bài tập ứng dụng:
Thử sử dụng gói dữ liệu Lahman để tính toán tỷ lệ strikeout trên mỗi trận đấu cùng giai đoạn 1901 đến nay. Hãy kiểm tra xem liệu sự gia tăng của home run có đi kèm với việc gia tăng số lần cầu thủ đánh hụt hay không, và biểu diễn sự tương quan đó trên cùng một biểu đồ trong R.


