これをleafletで描きたい。
こういうデータが手元にあるとする。(以前の記事で前処理したd_spread
をdput()
した結果です。dput()
はオブジェクトをコードとしてダンプできる便利な関数です)
d <- structure( list( pref_alpha = c("aichi", "akita", "aomori", "chiba", "ehime", "fukui", "fukuoka", "fukushima", "gifu", "gunma", "hiroshima","hokkaido", "hyogo", "ibaraki", "ishikawa", "iwate", "kagawa", "kagoshima", "kanagawa", "kochi", "kumamoto", "kyoto", "mie", "miyagi", "miyazaki", "nagano", "nagasaki", "nara", "niigata", "oita", "okayama", "okinawa", "osaka", "saga", "saitama", "shiga", "shimane", "shizuoka", "tochigi", "tokushima", "tokyo", "tottori", "toyama", "wakayama", "yamagata", "yamaguchi", "yamanashi"), チョコレート = c( 5092, 4639, 3470, 4633, 5038.66666666667, 5235.33333333333, 4090.83333333333, 4922.33333333333, 4804.66666666667, 4839, 5313.33333333333, 5478, 4881, 4805.66666666667, 6543, 4315.66666666667, 5478.33333333333, 5237.66666666667, 5003.75, 5428.33333333333, 4577, 5456, 4986.66666666667, 5063, 4534.66666666667, 5252, 4075.66666666667, 5619, 4799.66666666667, 5377, 4618.66666666667, 4174, 4114.33333333333, 4702.66666666667, 5238.66666666667, 4651.33333333333, 4539, 4790.83333333333, 5797.33333333333, 4477.33333333333, 5247, 5380, 5634.66666666667, 4501, 5697, 5852.33333333333, 5056.66666666667), チョコレート菓子 = c( 1147.66666666667, 1214.66666666667, 1125.66666666667, 1196.33333333333, 1667.33333333333, 1612.66666666667, 979.5, 1372.33333333333, 1229.66666666667, 1151.66666666667, 1308, 1975.66666666667, 1183.33333333333, 1221.66666666667, 1905.66666666667, 1358.66666666667, 1343.66666666667, 1629.33333333333, 1343.625, 1933.66666666667, 1080.66666666667, 1188.66666666667, 1354.66666666667, 1499.33333333333, 1247, 1474, 974, 1554.66666666667, 1161.66666666667, 1556.33333333333, 1466.33333333333, 1035.33333333333, 993.833333333333, 1537, 1184, 1395.33333333333, 1580.33333333333, 1400.16666666667, 1713.66666666667, 1557, 1123.33333333333, 1756.33333333333, 1682.66666666667, 1098.33333333333, 1720.66666666667, 1950, 1343.33333333333), 合計 = c( 6239.66666666667, 5853.66666666667, 4595.66666666667, 5829.33333333333, 6706, 6848, 5070.33333333333, 6294.66666666667, 6034.33333333333, 5990.66666666667, 6621.33333333333, 7453.66666666667, 6064.33333333333, 6027.33333333333, 8448.66666666667, 5674.33333333333, 6822, 6867, 6347.375, 7362, 5657.66666666667, 6644.66666666667, 6341.33333333333, 6562.33333333333, 5781.66666666667, 6726, 5049.66666666667, 7173.66666666667, 5961.33333333333, 6933.33333333333, 6085, 5209.33333333333, 5108.16666666667, 6239.66666666667, 6422.66666666667, 6046.66666666667, 6119.33333333333, 6191, 7511, 6034.33333333333, 6370.33333333333, 7136.33333333333, 7317.33333333333, 5599.33333333333, 7417.66666666667, 7802.33333333333, 6400) ), .Names = c("pref_alpha", "チョコレート", "チョコレート菓子", "合計"), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA,-47L) )
地図データの読み込み
まず、地図データを読み込み、都道府県ごとにまとめます。これもやり方は以前の記事をご参照ください。
library(rgdal) library(rgeos) f <- "C:\\path\\to\\gm-jpn-bnd_u_2_1" l <- readOGR(f, layer = "polbnda_jpn", encoding = "UTF-8",verbose = TRUE) l_union <- gUnaryUnion(l, id = as.character(l@data$nam))
leafletでポリゴンを色分けをする方法
leafletにSpatialPolygonsDataFrameなどのGIS系のデータを渡すときにはdata
という引数に渡すとだいたいいい感じに処理してくれます。
なので、単一の色でよければ以下のような感じになります。
leaflet() %>% addTiles() %>% addPolygons(data = l_union)
これに色を付けるには単純で、ポリゴンの数と同じ長さの色名のベクトルをcolor
とかfillColor
という変数に渡すことになります。適当に塗り分けるならこんな感じです。
colors <- rep(c("cyan", "magenta", "yellow"), length.out = length(l_union)) leaflet() %>% addTiles() %>% addPolygons(data = l_union, fillColor = colors, stroke = FALSE)
地図とデータを紐づける
d
の値に応じて色分けするには、以下の処理が必要です。
l_union
から県名を取り出す。- 県名をキーにして、
d
のデータをl_union
と同じ順に並べる - データの値から色を生成する
addPolygons()
に色を渡す
まず、l_union
から県名を取り出します。これは、@polygons
のID
というところに値が入っています。
l_union@polygons[[1]]@ID #> [1] "Aichi Ken"
これを取り出します。d
と合わせるため、Ken
などのsuffixは省いて小文字にします。
ids <- sapply(l_union@polygons, function(x) x@ID) %>% str_to_lower %>% str_split(" ") %>% sapply(`[`, 1)
これでだいたい合うんですが、北海道だけはhokkaido
でないと困るので修正します。めんどくさい。。
ids #> [1] "aichi" "akita" "aomori" "chiba" "ehime" "fukui" "fukuoka" "fukuoka" "fukushima" "gifu" "gunma" #> [12] "hiroshima" "hokkai" "hyogo" "ibaraki" "ishikawa" "iwate" "kagawa" "kagoshima" "kanagawa" "kochi" "kumamoto" #> [23] "kyoto" "mie" "miyagi" "miyazaki" "nagano" "nagasaki" "nara" "niigata" "oita" "okayama" "okinawa" #> [34] "osaka" "saga" "saitama" "shiga" "shimane" "shizuoka" "tochigi" "tokushima" "tokyo" "tottori" "toyama" #> [45] "wakayama" "yamagata" "yamaguchi" "yamanashi" ids[13] <- "hokkaido"
これとd
を紐づける方法はたぶんいろいろありますが、いちどdata.frameをつくってからleft_join()
するのが簡単そうです。
d_ordered <- data.frame(ids = ids, stringsAsFactors = FALSE) %>% left_join(d, by = c("ids" = "pref_alpha")) head(d_ordered) #> ids チョコレート チョコレート菓子 合計 #> 1 aichi 5092.000 1147.667 6239.667 #> 2 akita 4639.000 1214.667 5853.667 #> 3 aomori 3470.000 1125.667 4595.667 #> 4 chiba 4633.000 1196.333 5829.333 #> 5 ehime 5038.667 1667.333 6706.000 #> 6 fukui 5235.333 1612.667 6848.000
色を決める
次に、値の大きさに応じて色を割り当てます。
leafletには、そういうための関数がいくつか用意されています(colorXXX()
という名前です)。今回は連続値が対象なのでcolorNumeric()
を使います。これは、色のパレットと値の範囲を渡せば、色を割り当てる関数を作ってくれます。
values <- d_ordered$チョコレート color_generator <- colorNumeric("Oranges", domain = range(values)) color_generator(5000) #> [1] "#FD8E3D" color_generator(values) #> [1] "#FB8534" "#FDAD69" "#FFF5EB" "#FDAD6A" "#FC8A39" "#F67825" "#FED8B3" "#FED8B3" "#FD9447" "#FE9F55" "#FE9C51" "#F4701D" "#EC620F" #> [14] "#FD984C" "#FE9E55" "#7F2704" "#FEC997" "#EC620F" "#F67825" "#FD8D3C" "#EF6611" "#FDB271" "#ED6410" "#FD8F3F" "#FB8837" "#FEB678" #> [27] "#F67624" "#FED9B5" "#E35608" "#FE9F56" "#F16A15" "#FDAE6C" "#FDD4A9" "#FED7B0" "#FDA761" "#F67825" "#FDAC68" "#FEB577" "#FEA057" #> [40] "#D64701" "#FEBB80" "#F67724" "#F16A14" "#E25407" "#FEB97C" "#DE4F04" "#CE4402" "#FC8837"
値の範囲じゃなくて値そのままを渡しても結果は同じなんですけどよくわかりません。。
color_generator <- colorNumeric("Oranges", domain = values)
ともあれ色も決まったのでこれをleafletに渡せば完成です。
描く
leaflet() %>% addTiles() %>% addPolygons(data = l_union, color = color_generator(values), fillOpacity = 1, stroke = FALSE)
動くバージョンはRpubsに置きました:RPubs - choropleth map with leaflet package
まとめ
けっこう道のりは長かったですが、choroplethrとくらべてどうでしょうか? shapefileの扱いがけっこうめんどくさいですけど、自由度は高そうです。
そんなかっこいい地図を描けるleafletパッケージについてぞうさんこと@kazutanさんがわかりやすく解説してくれるJapan.Rは 12/5 です。さあ、いますぐ参加登録だ!!!