はじめに
地理情報講座の3回目、ラスト回です。今回は店舗間の距離を計算して、それが価格にどのような影響を与えているのかを分析してみます.店舗間の距離は市場の競争度の代理変数として使えそうです。店舗間の距離が近ければ近いほど、バチバチに競争してそうですよね。
やること
前半の2つで距離計算の仕方を学んで、最後に分析に応用してみるといった流れです。
1. 2店舗間の距離計算
2. 複数の店舗間の距離を一気に計算する
3. 競合の店舗数と価格の関係を分析する
1. 2つの店舗間の距離計算
**geosphereとImap**の2種類のライブラリがあるみたいです。詳細はリンクを載せたサイトを見てみてください。まずは、geosphereからやってみましょう。distGeo
というコマンドで距離計算が出来ます。単位はmです。()内で距離を測りたい2組の緯度経度を指定します。
# geosphereというライブラリ
install.packages("geosphere")
library("geosphere")
distGeo(gas_naha[1, c("longitude", "latitude")], gas_naha[2, c("longitude", "latitude")])
次にImap
です。単位が指定出来ることが便利そうですね。書き方はちょっとめんどくさいですね。ちなみに、どっちのライブラリでも値は等しいです。個人的にはgeosphereの方が書きやすいのでおすすめです。
# Imapというライブラリでも出来るみたいです。
install.packages("Imap")
library(Imap)
# gdistというコマンドで距離計算ができる。単位は指定可能
gdist(lon.1 = gas_naha[1, "longitude"], lon.2 =gas_naha[2, "longitude"] , lat.1 = gas_naha[1, "latitude"], lat.2 = gas_naha[2, "latitude"], units = "m")
2. 複数の店舗間の距離を一気に計算する
那覇市にはガソリンスタンドが48店あります。1店舗ずつ距離を上のようなコードで書いていたら、日が暮れてしまいます。似たような処理を自動化する時に役立つのが、for構文でした。1個ずつ丁寧に見ていきましょう。
2.1. 1行目の店舗との距離を各店舗に対して算出
まずは、データの1行目にある店舗と全ての店舗との距離を計算していきます。コードを回してみた結果を見てみると、そのコードがどんな操作をしたのかがわかるはずです。
for (i in 1:48){
gas_naha[i,"1" ] <- distGeo(gas_naha[1, c("longitude", "latitude")], gas_naha[i, c("longitude", "latitude")])
}
2.2. 全店舗に対して同じことをやってみます。これぞ自動化。
上のコードを1行目の店舗から48行目の店舗まで繰り返してあげれば、全店舗間の距離がわかります。それをやっているのが下のコードになります。上のコードを再度繰り返すので、for構文の中にfor構文が入っているのです。
# エラーが出たので、店舗名をFactorから文字列にしています。
gas_naha$store <- as.character(gas_naha$store)
# i行目の店舗との距離を各店舗j(1~48行目)に対して測っている。
for (i in 1:48){
for (j in 1:48){
colname <- gas_naha[i, "store"]
gas_naha[j,colname ] <- distGeo(gas_naha[i, c("longitude", "latitude")], gas_naha[j, c("longitude", "latitude")])
}
}
2.3. 競合店舗の数を集計する
半径2000m内にある店舗を競合する店舗として算出してみます。ガソリンスタンドの商圏は2kmと言われているからです。集計の過程としては、2ステップです。
①2000m以内かどうかのダミー変数を作成する
②そのダミー変数の和から自分の店舗分の1を引いた値が競合の店舗数となる。
# ①2000m以内かどうかのダミー変数を作成する
for (i in 1:48){
for (j in 1:48){
colname <- gas_naha[i, "store"]
gas_naha[j,colname ] <- distGeo(gas_naha[i, c("longitude", "latitude")], gas_naha[j, c("longitude", "latitude")])
gas_naha[j,colname ] <- ifelse(gas_naha[j,colname ] <= 2000, 1, 0)
}
}
# ②そのダミー変数の和から自分の店舗分の1を引いた値が競合の店舗数となる。
for (i in 1:48){
# 競合の店舗数がcompeという変数とします。
gas_naha[i, "compe"] <- sum(gas_naha[i, 10:57]) -1
}
3. 競合の店舗数と価格の関係を分析する
3.0. テーマ設定
ここでは、競合の店舗数とガソリンの販売価格を分析してみます。**競合の店舗数が多ければ多いほど、価格競争が起こり、価格が低下する傾向にあるのでは?**という仮説を検証してみたいと思います。被説明変数は価格、説明変数は競合の店舗数、観察単位はメッシュ地域ではなく店舗となります。
分析の全体像
- 価格データを結合してデータを整える
- 回帰分析で検証
3.1. 価格データを結合してデータを整える
今まで何度も登場したコードたちですね。
# 分析に必要なデータだけを抽出する
gas_compe <- gas_naha[, c(1, 58)]
# 価格データを結合する
price <- read.csv("price.csv")
gas_compe <- merge(gas_compe, price, by = 'store')
# 欠損があるデータは削除する
gas_compe <- na.omit(gas_compe)
3.2. 回帰分析で検証
また有意な結果は出ませんでしたね。突っ込みどころ満載の推定式なので仕方ないですね、、分析のイメージが沸けばOKということで!
out <- lm(data = gas_compe, Price ~ compe)
summary(out)
さいごに
スクレイピングから4回分お疲れ様でした〜。こんなことも出来るのかぁと思ってい頂ければ嬉しい限りです。前回も今回も分析結果が面白くないですね、説明変数とサンプルが少ないことが原因だとは思いますが…。沖縄県那覇市じゃない場所だったら結果は変わってたかもしれませんが、沖縄行きたさに選んでしまいました。