スクレイピングとぞいふもの
へー,webからデータを取ってくることをスクレイピングっていうんだ,というレベルから始めたのですがね。
毎年,データ演習の授業では色々なデータを使うのだけど,分布が偏ってるのもあって,適度に関係性が見られて,カテゴリカル変数もあって,それでいて身近な例で,というような丁度いいデータってのが欲しいもんなのですよ。
なので私はいつも,プロ野球データFreak さんのデータをコピペして,データを作っていました。
が,これが簡単にできるパッケージがあるらしい。のでやってみた。
library(rvest)
p.data <- read_html("http://baseball-data.com/ranking-salary/all/p.html") #ピッチャーの年俸など
h.data <- read_html("http://baseball-data.com/ranking-salary/all/h.html") #野手のそれ
avg5 <- read_html("http://baseball-data.com/stats/hitter2-all/avg-5.html") #規定打数1/3以上の打者基本成績
era5 <- read_html("http://baseball-data.com/stats/pitcher2-all/era-5.html") #規定投球回1/3以上の投手基本成績
p.df <- as.data.frame(html_table(p.data,head=T))
head(p.df)
## 順位 選手名 チーム 年俸.推定. 守備 年数 年齢 生年月日 身長 体重 血液型 投打 出身地 ## 1 1 杉内 俊哉 巨人 50,000万円 投手 14年 34歳 1980/10/30 175cm 82kg A型 左左 福岡 ## 2 1 金子 千尋 オリックス 50,000万円 投手 11年 31歳 1983/11/08 180cm 77kg O型 右左 新潟 ## 3 3 内海 哲也 巨人 40,000万円 投手 12年 33歳 1982/04/29 186cm 93kg A型 左左 京都 ## 4 3 松坂 大輔 ソフトバンク 40,000万円 投手 9年 35歳 1980/09/13 183cm 93kg O型 右右 東京 ## 5 3 黒田 博樹 広島 40,000万円 投手 12年 40歳 1975/02/10 185cm 93kg B型 右右 大阪 ## 6 3 攝津 正 ソフトバンク 40,000万円 投手 7年 33歳 1982/06/01 181cm 97kg O型 右右 秋田
同様に読み込んでデータ化していけばいいんだけど,残念ながらデータによっては数字じゃないところがあったり,最後にも変数名が入っていたりして,全部chr型になってたりする。
面倒だけど,これを修正する作業を行いました。
ピッチャーの年俸データを整える
文字列操作パッケージstringrの解説を参考に,文字列操作をしていく。
library(stringr) # 文字列操作パッケージ
p.df$順位 <- NULL
p.df$チーム <- as.factor(p.df$チーム) # チーム名はfactor型
#年俸の「万円」と「,」を除外して数字に
p.df$年俸.推定. <- str_replace(p.df$年俸.推定.,"万円","") %>% str_replace(",","") %>% as.numeric()
p.df$年数 <- str_replace(p.df$年数,"年","") %>% as.numeric() #年数の「年」を除外して数字に
p.df$年齢 <- str_replace(p.df$年齢,"歳","") %>% as.numeric() #年齢の「歳」を除外して数字に
# 生年月日を"/"で区切って数値データにし,行列に組み上げてからデータフレームとして元データに結合
birth.data <- p.df$生年月日 %>% str_split("/") %>% unlist() %>% as.numeric() %>% matrix(ncol=3,byrow=T) %>% as.data.frame()
p.df <- cbind(p.df,birth.data)
p.df$身長 <- str_replace(p.df$身長,"cm","") %>% as.numeric() #身長の「cm」を除外して数字に
p.df$体重 <- str_replace(p.df$体重,"kg","") %>% as.numeric() #体重の「kg」を除外して数字に1
p.df$血液型 <- as.factor(p.df$血液型)
p.df$投 <- str_sub(p.df$投打, start=1, end=1) %>% as.factor() #投げる腕を切り出してfactor型に
p.df$打 <- str_sub(p.df$投打, start=2, end=2) %>% as.factor() #打つ腕を切り出してfactor型に
p.df$出身地 <- as.factor(p.df$出身地)
p.df$守備 <- NULL #データを作り変えた変数は除外しておく
p.df$生年月日 <- NULL
p.df$投打 <- NULL
# 変数名を英語にしておく
names(p.df) <- c("name","team","pay","year","age","height","weight","blood","home","BirthY","BirthM","BirthD","throw","hit")
summary(p.df) # 確認
## name team pay year age height weight ## Length:100 ソフトバンク:15 Min. : 4200 Min. : 1.0 Min. :21.00 Min. :167.0 Min. : 67.00 ## Class :character 巨人 :12 1st Qu.: 6000 1st Qu.: 4.0 1st Qu.:29.00 1st Qu.:179.0 1st Qu.: 80.00 ## Mode :character オリックス :10 Median : 9000 Median : 8.0 Median :31.00 Median :181.5 Median : 86.00 ## ヤクルト : 9 Mean :12579 Mean : 8.1 Mean :31.53 Mean :183.2 Mean : 88.27 ## 日本ハム : 9 3rd Qu.:15000 3rd Qu.:12.0 3rd Qu.:34.25 3rd Qu.:186.2 3rd Qu.: 95.25 ## DeNA : 7 Max. :50000 Max. :24.0 Max. :45.00 Max. :205.0 Max. :121.00 ## (Other) :38 ## blood home BirthY BirthM BirthD throw hit ## AB型: 5 アメリカ:16 Min. :1970 Min. : 1.00 Min. : 1.00 右:76 右:71 ## A型 :34 福岡 : 8 1st Qu.:1980 1st Qu.: 5.00 1st Qu.: 9.00 左:24 左:29 ## B型 :15 愛知 : 6 Median :1983 Median : 7.00 Median :14.00 ## O型 :22 京都 : 6 Mean :1983 Mean : 7.35 Mean :15.75 ## 不明:24 大阪 : 6 3rd Qu.:1986 3rd Qu.:10.00 3rd Qu.:24.25 ## 広島 : 4 Max. :1994 Max. :12.00 Max. :31.00 ## (Other) :54
バッターの年俸データを整える
同じような作業。
h.df <- as.data.frame(html_table(h.data,head=T))
h.df$順位 <- NULL
h.df$チーム <- as.factor(h.df$チーム) # チーム名はfactor型
#年俸の「万円」と「,」を除外して数字に
h.df$年俸.推定. <- str_replace(h.df$年俸.推定.,"万円","") %>% str_replace(",","") %>% as.numeric()
h.df$年数 <- str_replace(h.df$年数,"年","") %>% as.numeric() #年数の「年」を除外して数字に
h.df$年齢 <- str_replace(h.df$年齢,"歳","") %>% as.numeric() #年齢の「歳」を除外して数字に
# 生年月日を"/"で区切って数値データにし,行列に組み上げてからデータフレームとして元データに結合
birth.data <- h.df$生年月日 %>% str_split("/") %>% unlist() %>% as.numeric() %>% matrix(ncol=3,byrow=T) %>% as.data.frame()
h.df <- cbind(h.df,birth.data)
h.df$身長 <- str_replace(h.df$身長,"cm","") %>% as.numeric() #身長の「cm」を除外して数字に
h.df$体重 <- str_replace(h.df$体重,"kg","") %>% as.numeric() #体重の「kg」を除外して数字に1
h.df$血液型 <- as.factor(h.df$血液型)
h.df$投 <- str_sub(h.df$投打, start=1, end=1) %>% as.factor() #投げる腕を切り出してfactor型に
h.df$打 <- str_sub(h.df$投打, start=2, end=2) %>% as.factor() #打つ腕を切り出してfactor型に
h.df$出身地 <- as.factor(h.df$出身地)
h.df$守備 <- NULL #データを作り変えた変数は除外しておく
h.df$生年月日 <- NULL
h.df$投打 <- NULL
names(h.df) <- c("name","team","pay","year","age","height","weight","blood","home","BirthY","BirthM","BirthD","throw","hit")
summary(h.df) # 確認
## name team pay year age height weight ## Length:100 巨人 :12 Min. : 4800 Min. : 1.00 Min. :21.00 Min. :169.0 Min. : 67.00 ## Class :character ソフトバンク:11 1st Qu.: 7200 1st Qu.: 4.00 1st Qu.:28.00 1st Qu.:177.0 1st Qu.: 79.75 ## Mode :character オリックス :10 Median :10000 Median : 9.50 Median :32.00 Median :180.0 Median : 88.00 ## 楽天 :10 Mean :14342 Mean : 9.28 Mean :31.78 Mean :180.8 Mean : 88.43 ## ヤクルト : 8 3rd Qu.:18500 3rd Qu.:13.00 3rd Qu.:35.00 3rd Qu.:185.0 3rd Qu.: 95.00 ## ロッテ : 8 Max. :51000 Max. :27.00 Max. :44.00 Max. :198.0 Max. :130.00 ## (Other) :41 ## blood home BirthY BirthM BirthD throw hit ## AB型: 8 アメリカ : 9 Min. :1970 Min. : 1.00 Min. : 1.00 右:95 右:60 ## A型 :26 大阪 : 7 1st Qu.:1980 1st Qu.: 4.00 1st Qu.: 7.75 左: 5 左:36 ## B型 :17 ドミニカ共和国: 6 Median :1983 Median : 7.00 Median :15.00 両: 4 ## O型 :28 東京 : 6 Mean :1983 Mean : 6.68 Mean :15.29 ## 不明:21 神奈川 : 5 3rd Qu.:1987 3rd Qu.: 9.00 3rd Qu.:23.00 ## 千葉 : 5 Max. :1994 Max. :12.00 Max. :31.00 ## (Other) :62
成績のデータを整える。
最後の一行に変なのが入っているせいで全部キャラクターになっちゃってる。
#打者
avg5.df <- as.data.frame(html_table(avg5,head=T))
avg5.df <- avg5.df[-nrow(avg5.df),]
avg5.df$順位 <- NULL
avg5.df$チーム <- as.factor(avg5.df$チーム)
avg5.df[3:24] <- apply(avg5.df[3:24],2,as.numeric) #あとは数字変数
# 変数名の変更
# "選手名" "チーム" "打率" "試合" "打席数" "打数" "得点" "安打" "二塁打" "三塁打" "本塁打" "塁打"
# "打点" "盗塁" "盗塁刺" "犠打" "犠飛" "四球" "敬遠" "死球" "三振" "併殺打" "長打率" "出塁率"
names(avg5.df) <- c("name","team","BA","games","PA","AB","R","Hit","Double","Three","HR","TB",
"RBI","steal","CS","SH","SF","BB","HWHI","HBP","K","DP","SLG","OBP")
#投手
era5.df <- as.data.frame(html_table(era5,head=T))
era5.df <- era5.df[-nrow(era5.df),]
era5.df$順位 <- NULL
era5.df$チーム <- as.factor(era5.df$チーム)
era5.df[3:25] <- apply(era5.df[3:25],2,as.numeric) #あとは数字変数
# 変数名の変更
# "選手名" "チーム" "防御率" "試合" "勝利" "敗北" "セlブ" "ホlルド" "HP"
# "完投" "完封勝" "無四球" "勝率" "打者" "投球回" "被安打" "被本塁打" "与四球" "敬遠"
# "与死球" "奪三振" "暴投" "ボlク" "失点" "自責点"
names(era5.df) <- c("name","team","ERA","games","win","lose","save","hold","HP",
"CG","SHO","No.walks","win.rate","batter","times","hits","HR","BB","HWHI",
"DB","K","W.pitch","balk","R","ER")
成績と年棒を合わせる
ホームラン一本おいくら万円とか知りたいじゃないですか。
名前でマージします。
batter <- merge(h.df,avg5.df,by="name")
pitcher <- merge(p.df,era5.df,by="name")
これで出来上がり。あとはwrite.tableでもなんでもどうぞー。