データ
使うのは前回のデータ。
library(rgdal) f <- "C:\\path\\to\\gm-jpn-bnd_u_2_1" l <- readOGR(f, layer = "polbnda_jpn", encoding = "UTF-8",verbose = TRUE) glimpse(l@data) #> Observations: 2,914 #> Variables: 9 #> $ f_code (fctr) FA001, FA001, FA001, FA001, FA001, FA001, FA001, FA001, FA001, FA001, FA001, FA001, FA001, FA001, FA001, FA001, FA0... #> $ coc (fctr) JPN, JPN, JPN, JPN, JPN, JPN, JPN, JPN, JPN, JPN, JPN, JPN, JPN, JPN, JPN, JPN, JPN, JPN, JPN, JPN, JPN, JPN, JPN, ... #> $ nam (fctr) Hokkai Do, Hokkai Do, Hokkai Do, Hokkai Do, Hokkai Do, Hokkai Do, Hokkai Do, Hokkai Do, Hokkai Do, Hokkai Do, Hokka... #> $ laa (fctr) Sapporo Shi, Hakodate Shi, Otaru Shi, Asahikawa Shi, Muroran Shi, Kushiro Shi, Kushiro Shi, Obihiro Shi, Kitami Shi... #> $ pop (int) 1930496, 274485, 127224, 349057, 91276, 180160, -89999999, 169104, 123401, 9801, 87284, 38240, 23451, 174469, 37248,... #> $ ypc (int) 2014, 2014, 2014, 2014, 2014, 2014, 2014, 2014, 2014, 2014, 2014, 2014, 2014, 2014, 2014, 2014, 2014, 2014, 2014, 20... #> $ adm_code (fctr) 01100, 01202, 01203, 01204, 01205, 01206, 01206, 01207, 01208, 01209, 01210, 01211, 01212, 01213, 01214, 01214, 012... #> $ salb (fctr) UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, ... #> $ soc (fctr) JPN, JPN, JPN, JPN, JPN, JPN, JPN, JPN, JPN, JPN, JPN, JPN, JPN, JPN, JPN, JPN, JPN, JPN, JPN, JPN, JPN, JPN, JPN, ...
これは都道府県ごとのデータなので、単純にleaflet上にのっけるとこうなります。
leaflet() %>% addTiles() %>% addPolylines(data = l, color = "red")
ちょっと細かすぎる。これを都道府県(つまり、num
)でまとめたい。
こういうちょっと高度な操作は、rgeosパッケージにあるみたいです。
gUnaryUnion()
とgUnionCascaded()
がありますが、前者のほうが高度なのでGEOSがバージョン3.3.0以上であればこっちを使うように、とヘルプに書かれています。
library(rgeos) l_union <- gUnaryUnion(l, id = as.character(l@data$nam)) leaflet() %>% addTiles() %>% addPolylines(data = l_union, color = "red")
ただし、注意点として、rgeosが処理すると元データにあったdata
は消えてしまいます。残念ながらdata
を保持したまま処理する方法はないので、必要な場合は手動で紐づける必要があります。
slotNames(l) #> [1] "data" "polygons" "plotOrder" "bbox" "proj4string" slotNames(l_union) #> [1] "polygons" "plotOrder" "bbox" "proj4string"
おまけ:split
してから処理してあとでくっつける
けっきょく上のやり方に行きつきましたが、「split
してくっつければいい?」と思ってつまづいたので後々のためにメモ。
SpatialPolygonsDataFrame
は、ふつうのdata.frame
と同じようにsplit()
することができます。
l_split <- split(l, l@data$nam)
data
スロットもちゃんと保持されています。
slotNames(l_split[[1]]) #> [1] "data" "polygons" "plotOrder" "bbox" "proj4string"
で、これを別々にgUnaryUnion()
してからくっつければいい?と思ってやってみたんですが、、
a <- lapply(l_split, gUnaryUnion) l_union2 <- do.call(rbind, a) #> Error in validObject(res) : #> invalid class “SpatialPolygons” object: non-unique Polygons ID slot values
よくわかりませんがエラーがでます。これはなぜかというと、ポリゴンのID
という値がユニークである必要があるんですが、これが全部同じだからです。
sapply(a, function(x) x@polygons[[1]]@ID)[1:5] Aichi Ken Akita Ken Aomori Ken Chiba Ken Ehime Ken "1" "1" "1" "1" "1"
結局id
を指定する必要があるので、(今回は)けっきょくsplit()
しないほうが楽でした。
a <- lapply(l_split, function(x) gUnaryUnion(x, id = as.character(x@data$nam))) l_union2 <- do.call(rbind, a)
おまけ2:48番目の都道府県
全然本筋と関係ありませんが、split()
してデータをいじっていると、あることに気づきます。
length(l_split) #> [1] 48
???
都道府県で分割したはずなのに、なぜか48個に分割されています...。と、とどうふけんって、47じゃないっけ!?
動揺を隠しきれず、names()
してみます。
names(l_split) #> [1] "Aichi Ken" "Akita Ken" "Aomori Ken" "Chiba Ken" "Ehime Ken" #> [6] "Fukui Ken" "FUKUOKA" "Fukuoka Ken" "Fukushima Ken" "Gifu Ken" #> [11] "Gunma Ken" "Hiroshima Ken" "Hokkai Do" "Hyogo Ken" "Ibaraki Ken" #> [16] "Ishikawa Ken" "Iwate Ken" "Kagawa Ken" "Kagoshima Ken" "Kanagawa Ken" #> [21] "Kochi Ken" "Kumamoto Ken" "Kyoto Fu" "Mie Ken" "Miyagi Ken" #> [26] "Miyazaki Ken" "Nagano Ken" "Nagasaki Ken" "Nara Ken" "Niigata Ken" #> [31] "Oita Ken" "Okayama Ken" "Okinawa Ken" "Osaka Fu" "Saga Ken" #> [36] "Saitama Ken" "Shiga Ken" "Shimane Ken" "Shizuoka Ken" "Tochigi Ken" #> [41] "Tokushima Ken" "Tokyo To" "Tottori Ken" "Toyama Ken" "Wakayama Ken" #> [46] "Yamagata Ken" "Yamaguchi Ken" "Yamanashi Ken"
2行目に、我々が知らない48番目の都道府県がいます。その名もFUKUOKA
。大文字になっているあたり別格さを感じさせます。
いったい何者なんだFUKUOKA
...
(この隠された真実を知りすぎたために消されたりしなければ次回に続く)