R advent calendar201320140102分

1,303 views
1,180 views

Published on

R Advent Calendar 2013(http://atnd.org/events/45043)
2014/1/2分として作成したものです。

オープンデータとR、をテーマとして、今回は流山市のオープンデータを利用してみました。(http://www.city.nagareyama.chiba.jp/10763/index.html)

Published in: Technology
0 Comments
5 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,303
On SlideShare
0
From Embeds
0
Number of Embeds
95
Actions
Shares
0
Downloads
13
Comments
0
Likes
5
Embeds 0
No embeds

No notes for slide

R advent calendar201320140102分

  1. 1. R Advent Calendar 2013 2014/1/2分 オープンデータとR ggmapとTSPパッケージを使って 施設巡回経路を考えてみる かわはら
  2. 2. 概要 突然ですが、公園を巡回する経路を考えてみます。流山市のオー プンデータとして公開されているデータとGoogleMapを利用して、公 園を効率的にまわる経路を表示してみました。 「オープンデータとR」というテーマで何かやってみることないかな、 と考え、前回(http://www.slideshare.net/hiroki84/rlinked-opendata-in-29087495)はgoogleVisパッケージを使った施設の可視化 だったので、今回はggmapパッケージを使った可視化とルートの検 出をテーマにして簡単にまとめてみました。
  3. 3. 1. データの取得、抽出、確認 流山市のオープンデータトライアルHPから、「平和台」の公園データ を使います。CVSファイルを読み込み、対象データを抽出します。 #CSVファイルのURL url.parks <"http://www.city.nagareyama.chiba.jp/dbps_data/_material _/localhost/shisetsu_kouen.csv" #公園データの取得 parks <- read.csv(url.parks) #平和台が付く公園の収集 parks.selected <- parks[grep("平和台", parks$名称), 1:7] http://www.city.nagareyama.chiba.jp/10763/index.html
  4. 4. 1. データの取得、抽出、確認 抽出したデータの内容を確認します。 • 公園は全部で10ヶ所 • 今回は名称、緯度、経度を使用
  5. 5. 1. データの取得、抽出、確認 ggmapパッケージを利用してGoogle Map(*)上にプロットします。 まずは、周辺地図の表示です。 #ggmapの利用 install.packages("ggmap"); library(ggmap) #経度緯度情報のまとめ lat <- parks.selected$緯度 lon <- parks.selected$経度 loc <- c(min(lon), min(lat), max(lon), max(lat)) #結果のプロット M <- ggmap(get_map(location = loc, zoom=15, source = "google")) + xlab("") + ylab("") *オープンデータ関連なのでOpenStreetMapを考えたましたが、 ggmap(…, source=“osm”)がうまくいかずGoogle Mapを使いました。
  6. 6. 1. データの取得、抽出、確認 取得データをもとに公園をプロット(●)します。 MP <- M + geom_point(data = parks.selected, aes(x=経度, y=緯度), size=7, colour="red") しかし、いくつかの公園は、実際にHPで紹介さ れている位置とは違う位置にあるようです(下 記、平和台1号公園)。左図のプロットはとりあ えずの目安と考えて下さい。 HPの緯度経度 からのプロット HPで紹介され ている位置
  7. 7. 2. データの加工 「平和台」の公園データを同じ箇所を通らないように、最短で巡回す る経路を考えてみます。まず、各公園間の移動時間を計算します。 各公園(1~10)間の移動時間を、 route関数で計算した結果。単位は min。徒歩移動とした。車移動の場合 は、travelmode=“driving” 1 2 3 4 5 6 7 8 9 10 1 0.0 5.3 5.8 0.0 5.4 3.0 4.9 5.1 2.2 11.2 2 5.3 0.0 6.1 5.7 11.1 4.5 8.9 9.3 4.8 6.5 3 5.8 6.1 0.0 5.2 8.0 5.5 9.2 9.5 3.2 10.4 4 0.0 5.7 5.2 0.0 5.4 3.0 4.9 5.1 2.2 11.2 5 5.4 11.1 8.0 5.4 0.0 7.1 5.2 4.1 6.0 16.0 6 3.0 4.5 5.5 3.0 7.1 0.0 5.1 5.5 2.8 9.5 7 4.9 8.9 9.2 4.9 5.2 5.1 0.0 2.9 6.3 11.5 8 5.1 9.3 9.5 5.1 4.1 5.5 2.9 0.0 6.2 13.4 9 2.2 4.8 3.2 2.2 6.0 2.8 6.3 6.2 0.0 10.6 10 11.2 6.5 10.4 11.2 16.0 9.5 11.5 13.4 10.6 0.0 #徒歩で移動する場合 travelmode = "walking" #nr x nrの時間行列と距離行列の作成 nr <- nrow(parks.selected) time <- matrix(0, nr, nr) distance <- matrix(0, nr, nr) for (i in 1:nr){ parks.selected.i <- parks.selected[i,] loc.i <- c(parks.selected.i$経度, parks.selected.i$緯度) for (j in (i+1):nr){ parks.selected.j <- parks.selected[j,] loc.j <- c(parks.selected.j$経度, parks.selected.j$緯度) route.ij <- route(loc.i, loc.j, mode=travelmode, structure="route") #時間行列と距離行列に代入 time[i, j] = time[j, i] <- sum(route.ij$minutes, na.rm=T) distance[i, j] = distance[j, i] <- sum(route.ij$km, na.rm=T) } }
  8. 8. 2. データの加工 10ヶ所の公園を1回ずつ経由するルートを、TSPパッケージを使っ て計算します。 install.packages("TSP"); library(TSP) ans <- solve_TSP(TSP(time)) • TSP関数で、距離の行列をTSP形式に変換 TSP: symmetric traveling salesperson problem(セールスマン巡回問題) • solve_TSP関数で、最短経路を求める これだけです。。。 solve_TSP(x, method, control)のように使います。methodは指定が無ければ、最近挿 入法が採用されます。
  9. 9. 2. データの加工 10ヶ所の公園を1回ずつ経由するルートを、TSPパッケージを使っ て計算します。 install.packages("TSP"); library(TSP) ans <- solve_TSP(TSP(time)) • TSP関数で、距離の行列をTSP形式に変換 TSP: symmetric traveling salesperson problem(セールスマン巡回問題) • solve_TSP関数で、最短経路を求める これだけです。。。 solve_TSP(x, method, control)のように使います。methodは指定が無ければ、最近挿 入法が採用されます。 この順で公園をまわっていけばいいということらしい。
  10. 10. 3. データの表示 公園の巡回順路、所用時間、距離をプロットしていきます。 #経路のプロット。ans[k]番目からans[k+1]番目の公園への移動経路のプロット for (k in 1:(nr-1)){ h1 <- ans[k]; h2 <- ans[k+1] route <- na.omit(route(c(lon[h1], lat[h1]), c(lon[h2], lat[h2]), mode=travelmode, structure="route")) #与えられた座標をそのまま使用すると正しく表示されないことがあるので、 #移動経路の始点(最後にまわる公園については終点)を公園の位置とした。 M <- M + geom_point(data=route[1,], aes(x=lon, y=lat), size=10, colour="red", alpha=0.75) M <- M + geom_text(data=route[1,], aes(x=lon, y=lat), label=k, colour="white") M <- M + geom_text(data=route[1,], aes(x=lon, y=lat+0.0005), label=parks.selected$名称[h1], colour=“red”, size=4) M <- M + geom_path(data=route, aes(x=lon, y=lat), size=1.5, colour="red", alpha=0.75) M <- M + geom_text(data=route, aes(x=mean(lon), y=mean(lat)), label=paste(sprintf("%3.1f", sum(route$min)), "min, ", sprintf("%3.1f", sum(route$km)), "km", sep=""), colour="white", size=4) if (nrow(route)<2){ lonlat <- data.frame(lon=lon[c(h1, h2)], lat=lat[c(h1, h2)]) M <- M + geom_path(data=lonlat, aes(x=lon, y=lat), size=0.75, colour="red", alpha=0.75, type="dotted") } } M <- M + geom_point(data=route[nrow(route),], aes(x=lon, y=lat), size=10, colour="red", alpha=0.75) M <- M + geom_text(data=route[nrow(route),], aes(x=lon, y=lat), label=k+1, colour="white") M <- M + geom_text(data=route[nrow(route),], aes(x=lon, y=lat+0.0015), label=parks.selected$名称[h1], colour="red", size=4)
  11. 11. 3. データの表示 プロットの結果です。ちょっとご ちゃごちゃして見にくくなってしま いました。。。 ●: 公園(数値は巡回順) 赤字: 公園名 白字: 公園間移動距離・時間 以上です

×