R における集計データの作成:for 文を用いて(教材:経済セミナー 連載「実証ビジネス・エコノミクス」第5回)

以下のページで個人的に難しいと感じた(理解を要するのに時間がかかった)部分についてのメモです。

経済セミナー 連載「実証ビジネス・エコノミクス」
第5回 「競争の激しさをデータで読み解く:参入ゲームの推定[基礎編]」

「3データの準備」における、病院レベルデータを市区町村レベルデータに集計する部分です。
用いるデータやコード全体はここからダウンロードできます。

元々のデータは病院レベルのデータで、病院レベルの変数(病床数など)と病院が位置している市区町村の変数(人口など)が含まれています。

扱うもの

R における for 文

前準備
listCode <- unique(data$CityCode)

NumMRI <- numeric(length(listCode))
Pop <- numeric(length(listCode))
Menseki <- numeric(length(listCode))
PopDen <- numeric(length(listCode))
Income <- numeric(length(listCode))

listCode にデータ内に存在している市区町村コードを入れています。
unique を用いるのは重複をなくすためです。特定の市区町村に複数の病院があるとき、unique なしでは市区町村コードがダブってしまいます。

その後、使用する各変数のベクトルを用意します。その長さは、直前で作成した listCode の長さにしてます。

メイン
for (i in 1:length(listCode)){
  subdata <- data[data$CityCode==listCode[i],]
  NumMRI[i] <- sum(subdata$MRIOwnDum)
  Pop[i] <- as.integer(unique(subdata$Population))
  Menseki[i] <- as.integer(unique(subdata$Menseki)[1])
  PopDen[i] <- unique(subdata$PopDensity)
  Income[i] <- as.integer(unique(subdata$TaxableIncome))
}

個人的に初学者キラーだと思っている for 文がメインです。

for 文の導入

構造を把握しやすくするためにシンプルにすると、以下のようになります。

for (i in 1:length(listCode)){
  ~~~
}

言葉で書くと、~~~ の部分を、length(listCode) の数に当たる回数繰り返しています。
もちろん繰り返し書いていても同様の結果は得られますが、腱鞘炎になって時間を喰うので、素直に for 文使いましょう。
大体どんなプログラミング言語にもこのような繰り返し作業を簡略化してくれるコマンドはあると思います。

本題
for (i in 1:length(listCode)){
  subdata <- data[data$CityCode==listCode[i],]
  NumMRI[i] <- sum(subdata$MRIOwnDum)
  Pop[i] <- as.integer(unique(subdata$Population))
  Menseki[i] <- as.integer(unique(subdata$Menseki)[1])
  PopDen[i] <- unique(subdata$PopDensity)
  Income[i] <- as.integer(unique(subdata$TaxableIncome))
}

まず、data の CityCode の値が、listCode の i 番目のものと一致している観測値を、subdata に格納します。
言い換えると、特定の市区町村に存在している病院のみを data から取ってきています。
data[~, ] で、~ 行の行ベクトルを取り出せます(例えば、これ
プログラマーのためのR言語入門 - Qiita
を参照)

変数の集計
for (i in 1:length(listCode)){
  subdata <- data[data$CityCode==listCode[i],]
  NumMRI[i] <- sum(subdata$MRIOwnDum)
}

次に、NumMRI の i 番目の要素に、subdata の MRIOwnDum (MRIがあれば1をとるダミー変数)の合計値を入れます。
これは、ある市区町村において、MRI を導入している病院がいくつあるのかを示しています。

市区町村レベル変数
for (i in 1:length(listCode)){
  subdata <- data[data$CityCode==listCode[i],]
  Pop[i] <- as.integer(unique(subdata$Population))
  Menseki[i] <- as.integer(unique(subdata$Menseki)[1])
  PopDen[i] <- unique(subdata$PopDensity)
  Income[i] <- as.integer(unique(subdata$TaxableIncome))
}

各変数のベクトルの i 番目に subdata の対応する変数の値を代入しています。
unique を使っているのは、特定の市区町村に複数の病院が存在する時、unique なしではベクトルが取り出されてしまうためです。
この時のベクトルの要素は全て同じです。特定の市区町村における病院のみのサブサンプルなので。
unique を使うことでスカラーとなって解決です。

Menseki[i] <- as.integer(unique(subdata$Menseki)[1])

上記の部分については、以下の二通りのようにもかけます。

Menseki[i] <- as.integer(unique(subdata$Menseki))

Menseki[i] <- as.integer(subdata$Menseki[1])
まとめ

集計は、集計後の単位ごとのサブサンプルにデータを分けて、
for 文を使うのが R だと一つの候補になります。

終わり。