RubyとRで競馬分析

コード表の用意

DataLab.で提供されているデータでは、いろいろなコード(ID)が使われています。
計算の途中ではコード値のままのほうが扱いやすいかもしれませんが、最終的な表示では、コード値の「01」とかではなく、「札幌」などと表示した方が分かりやすいでしょう。

そこで、コード値と対応する日本語と英語を格納したコード表を用意します。
コード表は、使い回しが効くように、.csvファイルとして用意しています。

ファイル名 種 類 格納されているカラム名
C2001.csv 競馬場コード CD,Name,NameEng
C2001EX.csv 拡張競馬場コード CD,Name,NameEng
C2002.csv 曜日コード CD,Name,NameEng
C2003.csv グレードコード CD,Name
C2005.csv 競走種別コード CD,Name,NameEng
C2006.csv 競走記号コード CD,Name,NameEng
C2007.csv 競走条件コード CD,Name,NameEng
C2008.csv 重量種別コード CD,Name,NameEng
C2009.csv トラックコード CD,Name,NameEng
C2010.csv 馬場状態コード CD,Name,NameEngSiba,NameEngDirt
C2011.csv 天候コード CD,Name,NameEng
C2101.csv 異常区分コード CD,Name,NameEng
C2102.csv 着差コード CD,Name,NameEng
C2201.csv 品種コード CD,Name
C2202.csv 性別コード CD,Name
C2203.csv 毛色コード CD,Name,NameEng
C2204.csv 馬記号コード CD,Name,NameEng
C2301.csv 東西所属コード CD,Name1,Name2
C2302.csv 騎乗資格コード CD,Name
C2303.csv 騎手見習コード CD,Name

「C2001EX.csv」の拡張競馬場コードは、「馬場改修を考慮した競馬場コード」説明したコードです。

各.csvファイルには、「CD」カラムに「コード値」、「Name」カラムに「コードの日本語名」、「NameEng」カラムに「コードの英語名」を格納します。ただし、若干の例外があります。

「コード表」を読み込んだ「Rオブジェクト」の用意

私はRubyでデータの前処理をして、最終的な出力はRを主に使っています。そのため、この.csvファイルは、主にRで使うのですが、その際、いちいち.csvファイルとして読み込むのも時間の無駄です。
そこで、Rスクリプト「DataLab_SaveCD.r」で、あらかじめ.csvファイルを読み込んだ「Rオブジェクト」を作って「RData」フォルダに保存しておきます。

このスクリプトでは、各.csvファイルが「CD」フォルダ内に用意されていて、変換したRオブジェクトは「RData」フォルダ内に保存するものと仮定しています。
フォルダの有無はチェックしていないので、「RData」フォルダは、スクリプトを実行する前に手動で用意しておく必要があります。

このRスクリプトを実行するには、Rのコンソール上で、次のように入力します。

> source("DataLab_SaveCD.r")

以降、load関数を使って、保存したデータフレーム・オブジェクトをいつでも再読み込みできるようになります。
たとえば、「競馬場コード」を読み込みたい場合は、次のようにします。

> load("RData/C2001.rdata")

これで、データフレーム「C2001」が使えるようになります。

メモ

read.csv関数でCSVファイルを読み込むときに、colClasses引数を指定して各カラムのデータ型を明示的に指定しています。
colClasses引数を指定しないと、read.csv関数は自動的にデータ型を設定しますが、コード値である「00」や「01」などは数値としては扱って欲しくないので、ここではデータ型を明示的に指定して誤変換が起こらないようにしています。

read.csv関数で読み込んだデータフレーム・オブジェクトは、save関数で保存した後、rm関数で削除しています。

使用例 競馬場コードを競馬場名に変換する

以上で用意したRオブジェクトを使って、競馬データのコード値が格納されている配列を元に、対応する文字列を格納した配列を作るには、次のようにします。

競馬場コードの値が格納されている配列「KeibajyoCD」に対応する競馬場名の配列「KeibajyoName」を作っています。このとき、競馬場名として、「コード値」+「:」+「競馬場の英語名」という文字列を作っています。
「C2001$NameEng」の代わりに「C2001$Name」を使えば日本語名も使えますが、Rで表などを作るときは、英語のほうが桁がそろって都合がよいので、英語を使っています。
(出力状況を見ると、Rは、文字の幅を「文字数×半角文字の文字幅」で単純計算しているようです。

#競馬場のコードを読み込む
load("RData/C2001.rdata")

#競馬場コードを競馬場名に変換する
KeibajyoName <- as.character(KeibajyoCD)
for(index in 1:length(C2001$CD)) {
  KeibajyoName[KeibajyoName == C2001$CD[index]] <-
      paste(C2001$CD[index], ":", C2001$NameEng[index])
}

コード表変換関数

以上の処理はよく行なう処理なので、Rスクリプト「DataLab_Code2Name.r」に、汎用的な関数「Code2Name」として定義しておきます。
この関数は、次のように使います。

#Code2Nameを定義する
source("DataLab_Code2Name.r")

#競馬場のコードを読み込む
load("RData/C2001.rdata")

#競馬場コードを競馬場名に変換する
KeibajyoName <- Code2Name(KeibajyoCD, C2001$CD, C2001$NameEng)

DataLab_SaveCD.r

#DataLabで使われるコード表をデータフレームに読み込み、
#データフレーム・オブジェクトを保存する

#[競馬場コード](C2001)
C2001 <- read.csv("CD/C2001.csv",
                  colClasses=c("factor","character","character"))
save(C2001, file="RData/C2001.rdata")
rm(C2001)

#[曜日コード](C2002)
C2002 <- read.csv("CD/C2002.csv",
                  colClasses=c("factor","character","character"))
save(C2002, file="RData/C2002.rdata")
rm(C2002)

#[グレードコード](C2003)
C2003 <- read.csv("CD/C2003.csv",
                  colClasses=c("factor","character"))
save(C2003, file="RData/C2003.rdata")
rm(C2003)

#[競走種別コード](C2005)
C2005 <- read.csv("CD/C2005.csv",
                  colClasses=c("factor","character","character"))
save(C2005, file="RData/C2005.rdata")
rm(C2005)

#[競走記号コード](C2006)
C2006 <- read.csv("CD/C2006.csv",
                  colClasses=c("factor","character","character"))
save(C2006, file="RData/C2006.rdata")
rm(C2006)

#[競走条件コード](C2007)
C2007 <- read.csv("CD/C2007.csv",
                  colClasses=c("factor","character","character"))
save(C2007, file="RData/C2007.rdata")
rm(C2007)

#[重量種別コード](C2008)
C2008 <- read.csv("CD/C2008.csv",
                  colClasses=c("factor","character","character"))
save(C2008, file="RData/C2008.rdata")
rm(C2008)

#[トラックコード](C2009)
C2009 <- read.csv("CD/C2009.csv",
                  colClasses=c("factor","character","character"))
save(C2009, file="RData/C2009.rdata")
rm(C2009)

#[馬場状態コード](C2010)
C2010 <- read.csv("CD/C2010.csv",
                  colClasses=c("factor","character","character","character"))
save(C2010, file="RData/C2010.rdata")
rm(C2010)

#[天候コード](C2011)
C2011 <- read.csv("CD/C2011.csv",
                  colClasses=c("factor","character","character"))
save(C2011, file="RData/C2011.rdata")
rm(C2011)

#[異常区分コード](C2101)
C2101 <- read.csv("CD/C2101.csv",
                  colClasses=c("factor","character","character"))
save(C2101, file="RData/C2101.rdata")
rm(C2101)

#[着差コード](C2102)
C2102 <- read.csv("CD/C2102.csv",
                  colClasses=c("factor","character","character"))
save(C2102, file="RData/C2102.rdata")
rm(C2102)

#[品種コード](C2201)
C2201 <- read.csv("CD/C2201.csv",
                  colClasses=c("factor","character"))
save(C2201, file="RData/C2201.rdata")
rm(C2201)

#[性別コード](C2202)
C2202 <- read.csv("CD/C2202.csv",
                  colClasses=c("factor","character"))
save(C2202, file="RData/C2202.rdata")
rm(C2202)

#[毛色コード](C2203)
C2203 <- read.csv("CD/C2203.csv",
                  colClasses=c("factor","character","character"))
save(C2203, file="RData/C2203.rdata")
rm(C2203)

#[馬記号コード](C2204)
C2204 <- read.csv("CD/C2204.csv",
                  colClasses=c("factor","character","character"))
save(C2204, file="RData/C2204.rdata")
rm(C2204)

#[東西所属コード](C2301)
C2301 <- read.csv("CD/C2301.csv",
                  colClasses=c("factor","character","character"))
save(C2301, file="RData/C2301.rdata")
rm(C2301)

#[騎乗資格コード](C2302)
C2302 <- read.csv("CD/C2302.csv",
                  colClasses=c("factor","character"))
save(C2302, file="RData/C2302.rdata")
rm(C2302)

#[騎手見習コード](C2303)
C2303 <- read.csv("CD/C2303.csv",
                  colClasses=c("factor","character","character"))
save(C2303, file="RData/C2303.rdata")
rm(C2303)

#[拡張競馬場コード](C2001EX)
C2001EX <- read.csv("CD/C2001EX.csv",
                  colClasses=c("factor","character","character"))
save(C2001EX, file="RData/C2001EX.rdata")
rm(C2001EX)

DataLab_Code2Name.r

#コードから名前に変換する関数
Code2Name <-  function(dataCD, CD, NameEng) {
  dataName <- as.character(dataCD)
  for(index in 1:length(CD)) {
    dataName[dataName == CD[index]] <- paste(CD[index], ":", NameEng[index], sep = "")
  }
  return(dataName)
}

Creative Commons License
この作品は、クリエイティブ・コモンズ・ライセンスの下でライセンスされています。

(C) 2006 NARITA, Takuro
E-Mail:narita@a1.mbn.or.jp