日本プロ野球データを作る(打者・投手)
イントロ
自分のラボの人にRの使い方を説明するのに実験データだけではなく、より身近なデータがあるといいのに、とおもって探し始めてプロ野球データにたどり着きました。果たしてプロ野球データが身近なものであるかという疑問は静かに無視しつつ、baseball-reference.comという、古今東西の野球データが公開されているサイトからデータをダウンロードすることにしました。こちらのサイトを激しく参考にしましたが、打者だけではなく投手の情報も取得できるように改変しました。
目的
Rでいろんな実験をしやすくするために日本のプロ野球データを取得し、CSV形式でローカルPCに保存すること。
日本の過去のプロ野球データを取得する
リーグ一覧のうち、日本のプロ野球のリーグとして次の5つのデータを取得してみましょう。今回はイースタンとウェスタンはパスしました。同じように取得は可能なはずです。
League name | code |
---|---|
Japan Central League | JPCL |
Japan Pacific League | JPPL |
Japanese Baseball League | JPBL |
Japanese Baseball League (Fall) | JPBF |
Japanese Baseball League (Spring) | JPBS |
ためしに“Japan Central League”のリンク先のURLをみてみると、次のようになっています:https://www.baseball-reference.com/register/league.cgi?code=JPCL&class=Fgn
実際にリンク先には各年のチーム名が表になって並んでいます。現時点で2020年シーズンのデータはありませんので、2019年の”Yokohama Bay Stars”のリンクをみてみると、次のようになっています。どうも、各チーム・各年ごとにidがふられているっぽいですね(2019のベイスターズであればd2ea2428のように)。
https://www.baseball-reference.com/register/team.cgi?id=d2ea2428
そしてリンク先には打者と投手の成績がズラリと並んでいるわけです。
そこで、日本プロ野球の各チーム・各年ごとにidを取得して、打者と投手のデータをぐるぐるとクローリングしてローカルのcsvファイルに保存してみましょう。うちのそこそこMBPでだいたい1時間くらいかかりました。
# download Japanese Baseball League data library(tidyverse) library(xml2) library(rvest) library(magrittr) library(progress) # create folders to store data dir.create(path = file.path("rawdata"), showWarnings = FALSE, recursive = TRUE) dir.create(path = file.path("data"), showWarnings = FALSE, recursive = TRUE) # leagues and realted infos leagues<-tribble( ~name, ~code, ~start_year, ~end_year, "Japan Central League", "JPCL", 1950, 2020, "Japan Pacific League", "JPPL", 1950, 2020, "Japanese Baseball League", "JPBL", 1939, 1949, "Japanese Baseball League (Fall)", "JPBF", 1936, 1938, "Japanese Baseball League (Spring)", "JPBS", 1936, 1938 ) total_years<-sum(leagues$end_year-leagues$start_year+1) pb <- progress::progress_bar$new( format = "Downloading :what [:bar] :current/:total (:percent)", total = total_years) for (j in seq(leagues$code)){ all_year_html <- read_html(sprintf("http://www.baseball-reference.com/register/league.cgi?code=%s&class=Fgn", leagues[j, "code"])) years <- seq(leagues$end_year[j], leagues$start_year[j]) for (year_id in seq(years)){ pb$tick(1, tokens = list(what = paste(leagues$code[j], years[year_id]))) # links to each team link_team_list <- all_year_html %>% html_nodes(xpath = paste('//*[@id="lg_history"]/tbody/tr[', year_id, ']/td/a', sep = "")) link_list <- link_team_list %>% html_attr("href")# %>% .[-1] team_list <- link_team_list %>% html_text()# %>% .[-1] team_stats_URL <- paste("http://www.baseball-reference.com", link_list, sep="") for (i in seq(team_list)) { html = read_html(team_stats_URL[i]) # retrive batting info batting_player_id <- html %>% html_nodes(xpath = '//*[@id="team_batting"]/tbody/tr/td[1]')%>% html_attr("data-append-csv")%>% str_remove("player\\.fcgi\\?id=") if (!is_empty(batting_player_id)){ batting_stats <- html %>% html_node(xpath = '//*[@id="team_batting"]') %>% html_table %>% select(-Notes) %>% filter(!is.na(Rk)) %>% mutate(League = leagues$name[j]) %>% mutate(Team = team_list[i]) %>% mutate(Year = years[year_id]) %>% mutate(PlayerID = batting_player_id) filename <- file.path("rawdata", sprintf("%s_%s.batting.csv", years[year_id], str_remove(team_list[i], " "))) batting_stats %>% write_csv(filename) } # retrive pitching info pitching_html <- html %>% html_node(xpath = '//comment()[contains(., "team_pitching")]') if (!is_empty(pitching_html)){ pitching_player_id <- pitching_html %>% html_text() %>% read_html() %>% html_node("table") %>% html_nodes(xpath = '//*[@id="team_pitching"]/tbody/tr/td[1]')%>% html_attr("data-append-csv")%>% str_remove('player\\.fcgi\\?id=') if (!is_empty(pitching_player_id)){ pitching_stats <- html %>% html_node(xpath = '//comment()[contains(., "team_pitching")]') %>% html_text() %>% read_html() %>% html_node("table") %>% html_table() %>% select(-Notes) %>% filter(!is.na(Rk)) %>% mutate(League = leagues$name[j]) %>% mutate(Team = team_list[i]) %>% mutate(Year = years[year_id]) %>% mutate(PlayerID = pitching_player_id) filename <- file.path("rawdata", sprintf("%s_%s.pitching.csv", years[year_id], str_remove(team_list[i], " "))) pitching_stats %>% write_csv(filename) } } } } }
打者・投手のデータをそれぞれ1つのファイルにまとめる
rawdataフォルダに80年以上続くプロ野球の歴史が書き出されたわけですが、さらにこれを打者と投手のファイル(batting.csvとpitching.csv)にまとめてしまいます。まとめついでに、右打ち、左打ち、両打ち、をわかりやすく変換し、右投げ、左投げ、両投げ(!?)も変換しておきます。
# merge all data into two files vars <- c("batting", "pitching") col_types <- c("batting" = "iciiiiiiiiiiiiiiddddiiiiiiccic", "pitching" = "iciiiddiiiiiidiiiiiiiiiiiddddddccic") names(col_types) <- vars for (var in vars){ df <- tibble() files <- list.files("rawdata", pattern = sprintf("%s.csv$", var)) pb <- progress::progress_bar$new( format = sprintf("%s data [:bar] :current/:total (:percent)", var), total = length(files)) for (file in files){ temp.df <- read_csv(file.path("rawdata", file), col_types = as.character(col_types[var])) df%<>%bind_rows(temp.df) pb$tick(1) } if (var == "batting"){ df%<>%mutate(Bats = "right") df$Bats[str_which(df$Name, pattern = ".*\\*$")] <- "left" df$Bats[str_which(df$Name, pattern = ".*#$")] <- "both" df$Bats[str_which(df$Name, pattern = ".*\\?$")] <- "unknown" } if (var == "pitching"){ df%<>%mutate(Throws = "right") df$Throws[str_which(df$Name, pattern = ".*\\*$")] <- "left" df$Throws[str_which(df$Name, pattern = ".*#$")] <- "both" df$Throws[str_which(df$Name, pattern = ".*\\?$")] <- "unknown" } write_csv(df, path = file.path("data", sprintf("%s.csv", var))) }
これで、 楽しむ 勉強する準備ができました。
追記
上のソースコードで生成されるデータファイルをこちらからダウンロードできます:
batting.csv
pitching.csv
sessioninfo::session_info(c("tidyverse"))
## ─ Session info ─────────────────────────────────────────────────────────────── ## setting value ## version R version 3.6.3 (2020-02-29) ## os macOS Mojave 10.14.6 ## system x86_64, darwin15.6.0 ## ui RStudio ## language (EN) ## collate ja_JP.UTF-8 ## ctype ja_JP.UTF-8 ## tz Asia/Tokyo ## date 2020-05-15 ## ## ─ Packages ─────────────────────────────────────────────────────────────────── ## package * version date lib source ## askpass 1.1 2019-01-13 [1] CRAN (R 3.6.0) ## assertthat 0.2.1 2019-03-21 [1] CRAN (R 3.6.0) ## backports 1.1.6 2020-04-05 [1] CRAN (R 3.6.2) ## base64enc 0.1-3 2015-07-28 [1] CRAN (R 3.6.0) ## BH 1.72.0-3 2020-01-08 [1] CRAN (R 3.6.0) ## broom 0.5.6 2020-04-20 [1] CRAN (R 3.6.2) ## callr 3.4.3 2020-03-28 [1] CRAN (R 3.6.2) ## cellranger 1.1.0 2016-07-27 [1] CRAN (R 3.6.0) ## cli 2.0.2 2020-02-28 [1] CRAN (R 3.6.0) ## clipr 0.7.0 2019-07-23 [1] CRAN (R 3.6.0) ## colorspace 1.4-1 2019-03-18 [1] CRAN (R 3.6.0) ## crayon 1.3.4 2017-09-16 [1] CRAN (R 3.6.0) ## curl 4.3 2019-12-02 [1] CRAN (R 3.6.0) ## DBI 1.1.0 2019-12-15 [1] CRAN (R 3.6.0) ## dbplyr 1.4.3 2020-04-19 [1] CRAN (R 3.6.2) ## desc 1.2.0 2018-05-01 [1] CRAN (R 3.6.0) ## digest 0.6.25 2020-02-23 [1] CRAN (R 3.6.0) ## dplyr * 0.8.5 2020-03-07 [1] CRAN (R 3.6.0) ## ellipsis 0.3.0 2019-09-20 [1] CRAN (R 3.6.0) ## evaluate 0.14 2019-05-28 [1] CRAN (R 3.6.0) ## fansi 0.4.1 2020-01-08 [1] CRAN (R 3.6.0) ## farver 2.0.3 2020-01-16 [1] CRAN (R 3.6.0) ## forcats * 0.5.0 2020-03-01 [1] CRAN (R 3.6.0) ## fs 1.4.1 2020-04-04 [1] CRAN (R 3.6.3) ## generics 0.0.2 2018-11-29 [1] CRAN (R 3.6.0) ## ggplot2 * 3.3.0 2020-03-05 [1] CRAN (R 3.6.0) ## glue 1.4.0 2020-04-03 [1] CRAN (R 3.6.1) ## gtable 0.3.0 2019-03-25 [1] CRAN (R 3.6.0) ## haven 2.2.0 2019-11-08 [1] CRAN (R 3.6.0) ## highr 0.8 2019-03-20 [1] CRAN (R 3.6.0) ## hms 0.5.3 2020-01-08 [1] CRAN (R 3.6.0) ## htmltools 0.4.0 2019-10-04 [1] CRAN (R 3.6.0) ## httr 1.4.1 2019-08-05 [1] CRAN (R 3.6.0) ## isoband 0.2.1 2020-04-12 [1] CRAN (R 3.6.2) ## jsonlite 1.6.1 2020-02-02 [1] CRAN (R 3.6.0) ## knitr * 1.28 2020-02-06 [1] CRAN (R 3.6.0) ## labeling 0.3 2014-08-23 [1] CRAN (R 3.6.0) ## lattice 0.20-41 2020-04-02 [1] CRAN (R 3.6.3) ## lifecycle 0.2.0 2020-03-06 [1] CRAN (R 3.6.0) ## lubridate 1.7.8 2020-04-06 [1] CRAN (R 3.6.2) ## magrittr 1.5 2014-11-22 [1] CRAN (R 3.6.0) ## markdown * 1.1 2019-08-07 [1] CRAN (R 3.6.0) ## MASS 7.3-51.6 2020-04-26 [1] CRAN (R 3.6.2) ## Matrix 1.2-18 2019-11-27 [1] CRAN (R 3.6.3) ## mgcv 1.8-31 2019-11-09 [1] CRAN (R 3.6.3) ## mime 0.9 2020-02-04 [1] CRAN (R 3.6.0) ## modelr 0.1.7 2020-04-30 [1] CRAN (R 3.6.2) ## munsell 0.5.0 2018-06-12 [1] CRAN (R 3.6.0) ## nlme 3.1-147 2020-04-13 [1] CRAN (R 3.6.2) ## openssl 1.4.1 2019-07-18 [1] CRAN (R 3.6.0) ## pillar 1.4.4 2020-05-05 [1] CRAN (R 3.6.3) ## pkgbuild 1.0.8 2020-05-07 [1] CRAN (R 3.6.3) ## pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 3.6.0) ## pkgload 1.0.2 2018-10-29 [1] CRAN (R 3.6.0) ## plogr 0.2.0 2018-03-25 [1] CRAN (R 3.6.0) ## plyr 1.8.6 2020-03-03 [1] CRAN (R 3.6.0) ## praise 1.0.0 2015-08-11 [1] CRAN (R 3.6.0) ## prettyunits 1.1.1 2020-01-24 [1] CRAN (R 3.6.0) ## processx 3.4.2 2020-02-09 [1] CRAN (R 3.6.0) ## progress 1.2.2 2019-05-16 [1] CRAN (R 3.6.0) ## ps 1.3.2 2020-02-13 [1] CRAN (R 3.6.0) ## purrr * 0.3.4 2020-04-17 [1] CRAN (R 3.6.2) ## R6 2.4.1 2019-11-12 [1] CRAN (R 3.6.0) ## RColorBrewer 1.1-2 2014-12-07 [1] CRAN (R 3.6.0) ## Rcpp 1.0.4.6 2020-04-09 [1] CRAN (R 3.6.3) ## readr * 1.3.1 2018-12-21 [1] CRAN (R 3.6.0) ## readxl 1.3.1 2019-03-13 [1] CRAN (R 3.6.0) ## rematch 1.0.1 2016-04-21 [1] CRAN (R 3.6.0) ## reprex 0.3.0 2019-05-16 [1] CRAN (R 3.6.0) ## reshape2 1.4.4 2020-04-09 [1] CRAN (R 3.6.2) ## rlang 0.4.6 2020-05-02 [1] CRAN (R 3.6.2) ## rmarkdown * 2.1 2020-01-20 [1] CRAN (R 3.6.0) ## rprojroot 1.3-2 2018-01-03 [1] CRAN (R 3.6.0) ## rstudioapi 0.11 2020-02-07 [1] CRAN (R 3.6.0) ## rvest 0.3.5 2019-11-08 [1] CRAN (R 3.6.0) ## scales 1.1.0 2019-11-18 [1] CRAN (R 3.6.0) ## selectr 0.4-2 2019-11-20 [1] CRAN (R 3.6.1) ## stringi 1.4.6 2020-02-17 [1] CRAN (R 3.6.0) ## stringr * 1.4.0 2019-02-10 [1] CRAN (R 3.6.0) ## sys 3.3 2019-08-21 [1] CRAN (R 3.6.0) ## testthat 2.3.2 2020-03-02 [1] CRAN (R 3.6.0) ## tibble * 3.0.1 2020-04-20 [1] CRAN (R 3.6.2) ## tidyr * 1.0.3 2020-05-07 [1] CRAN (R 3.6.3) ## tidyselect 1.0.0 2020-01-27 [1] CRAN (R 3.6.0) ## tidyverse * 1.3.0 2019-11-21 [1] CRAN (R 3.6.0) ## tinytex 0.22 2020-04-17 [1] CRAN (R 3.6.2) ## utf8 1.1.4 2018-05-24 [1] CRAN (R 3.6.0) ## vctrs 0.2.4 2020-03-10 [1] CRAN (R 3.6.0) ## viridisLite 0.3.0 2018-02-01 [1] CRAN (R 3.6.0) ## whisker 0.4 2019-08-28 [1] CRAN (R 3.6.0) ## withr 2.2.0 2020-04-20 [1] CRAN (R 3.6.2) ## xfun 0.13 2020-04-13 [1] CRAN (R 3.6.2) ## xml2 1.3.2 2020-04-23 [1] CRAN (R 3.6.2) ## yaml 2.2.1 2020-02-01 [1] CRAN (R 3.6.0) ## ## [1] /Library/Frameworks/R.framework/Versions/3.6/Resources/library