読者です 読者をやめる 読者になる 読者になる

300億円欲しい

メジャーリーグのデータ解析します

Rからデータベースに接続したい

R 野球

Rの話です

PostgreSQLを使う

野球データの数が大きくなり, ファイルもフォルダも管理できなくなりました.
こういうときのデータベースです.
データベースにデータを投げて, 整理します.
7年分の打席結果データをPostgreSQLに読ませました.

baseball_data=# \d
          List of relations
 Schema |    Name     | Type  | Owner 
--------+-------------+-------+-------
 public | all2007     | table | gg_hatano
 public | all2008     | table | gg_hatano
 public | all2009     | table | gg_hatano
 public | all2010     | table | gg_hatano
 public | all2011     | table | gg_hatano
 public | all2012     | table | gg_hatano
 public | all2013     | table | gg_hatano
 public | fullname_id | table | gg_hatano
 public | master      | table | gg_hatano

SQLコマンドを覚えるのが面倒なので, Rから使います.
Rからデータベースと接続して, データを読み込みます.

今回はPostgreSQLを使っているので, RPoistgreSQLパッケージを使えばいいです.
SQLiteならRSQLite, MySQLならRMySQLを使えばいいです.

ただ, dataframe型で読み込みが行われるので, データの扱いが面倒です.
読み込みも遅いです.

> # SQLから読み込み
> system.time(data <- dbReadTable(conn, "all2013"))
   ユーザ   システム       経過  
     2.933      1.103      5.350 
> # csvファイルから 
> system.time(data <- data.table::fread("all2013.csv"))
   ユーザ   システム       経過  
     1.088      0.143      1.581 

もっと速く処理したいです.

dplyrでデータベース接続

簡単な処理なら, データベースをdplyrでいじれるらしいです.
dplyrとデータベース - BOD
ちょうど, 野球のデータをPostgreSQLにぶちこんだところだったので,
dplyrから集計してみます.

ヒット数の集計は, こんな感じになります.

library(RPostgreSQL)
library(dplyr)
library(pingr)
# データベース接続
my_db = src_postgres(dbname="baseball_data")

# 2013年の打席結果テーブルを読み込み
dat_psql = tbl(my_db, "all2013")

# 名前とidのテーブルを読み込み
fullname_id = tbl(my_db, "fullname_id")

# dplyrで処理
dat_hit <- dat_psql %.%
  filter(EVENT_CD >= 19 & EVENT_CD <= 23) %.%
  group_by(BAT_ID) %.% 
  dplyr::summarise(HIT = n()) %.% 
  inner_join(fullname_id, by="BAT_ID") %.%
  select(FULLNAME, HIT)%.%
  arrange(desc(HIT))
head(dat_hit)

# 終了の音
ping()

2013年のヒット数ランキングです

> head(dat_hit)
        FULLNAME HIT
1  Adrian Beltre 202
2 Dustin Pedroia 196
3 Miguel Cabrera 195
4  Daniel Murphy 193
5  Manny Machado 191
6  Robinson Cano 190

簡単な操作なら, dplyrの中でSQLコマンドに翻訳して集計してくれます.
ちょっと変なことをするなら,
データベースからテーブルをデータフレームとして読み込むほうがいいかもしれません.
自由に扱えますし.
ただ, データフレームの読み込みは速くないので,
簡単な操作ならdplyrからDBに接続させて頑張って書くほうが高速に処理できると思います.

データファイルはこちら
gghatano/baseball_data · GitHub

>library(data.table)
>dat = fread("all2013.csv")
>fields = fread("fields.csv")
>setnames(dat, fields$Header)

とすれば, 2013年のMLB全打席結果データになります