Rで解析:地図の描写が面白い「tmap」パッケージ

Rの解析に役に立つ記事
スポンサーリンク

ggplot2パッケージと同様にレイヤーの概念で数量データを地図に簡単に示すことが可能なパッケージの紹介です。また、分割基準を設定することで地図を簡単に分割して表示することが可能です。

付与するデータ次第で面白い表現が可能と考えます。

パッケージバージョンは3.3-3。実行コマンドはwindows 11のR version 4.1.2で確認しています。

スポンサーリンク

「tmap」パッケージ利用の前準備

・シェープファイルを準備する

「JPNPref.shp」ファイルに気象庁より観測所一覧を取得して「JPNPref_2.shp」ファイルを作成します。

・Rで解析:「leaflet」パッケージで使える日本のシェープファイルの作成例
 https://www.karada-good.net/analyticsr/r-594

#パッケージの読み込み
library("tcltk")

#「JPNPref.shp」シェープファイルを読み込む
#参考:https://www.karada-good.net/analyticsr/r-594
load(paste0(as.character(tkgetOpenFile(title = "ファイルを選択",
                                       filetypes = '{"ファイル" {".*"}}',
                                       initialfile = c("*.*")))))

###気象庁より観測所一覧を取得#####
#Tmpフォルダに保存しデスクトップにファイル展開後に読み込む
#ファイル名が変更されため下記URLよりリンクを確認する
#https://www.jma.go.jp/jma/kishou/know/amedas/kaisetsu.html
temp <- tempfile()
download.file("https://www.jma.go.jp/jma/kishou/know/amedas/ame_master_20211207.zip",
              temp, mode = "wb")
Kansokujyo <- read.csv(unzip(temp))
unlink(temp)

###&#24517;&#35201;&#12487;&#12540;&#12479;&#12434;&#26085;&#26412;&#22320;&#22259;&#12471;&#12455;&#12540;&#12503;&#12501;&#12449;&#12452;&#12523;&#12395;&#20184;&#19982;&#12375;&#12390;&#20445;&#23384;#####
MasterKansokujyo <- Kansokujyo[, c(1, 4, 7:10)]

#&#21271;&#28023;&#36947;&#12398;&#21508;&#22320;&#26041;&#34920;&#35352;&#12434;&#21271;&#28023;&#36947;&#12395;&#32622;&#25563;
MasterKansokujyo[, 1] <- c(rep("&#21271;&#28023;&#36947;", 227),
                           as.character(MasterKansokujyo[228:nrow(MasterKansokujyo), 1]))

#&#32239;&#24230;&#32076;&#24230;&#12434;&#22793;&#25563;
LatData <- type.convert(paste0(MasterKansokujyo[, 3] + MasterKansokujyo[, 4]/60),
                        as.is = TRUE)
LonData <- type.convert(paste0(MasterKansokujyo[, 5] + MasterKansokujyo[, 6]/60),
                        as.is = TRUE)

#&#12471;&#12455;&#12540;&#12503;&#12501;&#12449;&#12452;&#12523;&#12395;&#20184;&#19982;
#&#25991;&#23383;&#12456;&#12531;&#12467;&#12540;&#12489;&#12434;UTF-8&#12395;&#12377;&#12427;
if(!require("stringi", quietly = TRUE)){
  install.packages("stringi");require("stringi")
}
attributes(JPNPref)$Kansokujyo <- data.frame("&#37117;&#36947;&#24220;&#30476;" = stri_encode(MasterKansokujyo[, 1], "", "utf-8"),
                                             "&#35251;&#28204;&#25152;&#21517;" = stri_encode(MasterKansokujyo[, 2], "", "utf-8"),
                                             "&#32076;&#24230;" = LatData, "&#32239;&#24230;" = LonData)
#&#12471;&#12455;&#12540;&#12503;&#12501;&#12449;&#12452;&#12523;&#12434;&#20445;&#23384;
save(JPNPref, file = "JPNPref_2.shp")

・気象庁より最高気温最新を取得する

コマンドを実行すると前日の最高気温、観測所の緯度経度が付与された「JPNPref_3.shp」と「MaxSpDF.shp」が作成できます。

#&#12497;&#12483;&#12465;&#12540;&#12472;&#12398;&#35501;&#12415;&#36796;&#12415;
library("tcltk")
if(!require("tidyverse", quietly = TRUE)){
  install.packages("tidyverse");require("tidyverse")
}

#&#12300;JPNPref_2.shp&#12301;&#12471;&#12455;&#12540;&#12503;&#12501;&#12449;&#12452;&#12523;&#12434;&#35501;&#12415;&#36796;&#12416;
#&#21442;&#32771;:https://www.karada-good.net/analyticsr/r-594
load(paste0(as.character(tkgetOpenFile(title = "&#12501;&#12449;&#12452;&#12523;&#12434;&#36984;&#25246;",
                                       filetypes = '{"&#12501;&#12449;&#12452;&#12523;" {".*"}}',
                                       initialfile = c("*.*")))))

###&#27671;&#35937;&#24193;&#12424;&#12426;&#26368;&#39640;&#27671;&#28201;&#26368;&#26032;&#12434;&#21462;&#24471;#####
#http://www.data.jma.go.jp/obd/stats/data/mdrr/docs/csv_dl_readme.html
MaxTemp <- read.csv("http://www.data.jma.go.jp/obd/stats/data/mdrr/tem_rct/alltable/mxtemsadext00_rct.csv")

#&#22320;&#28857;&#12487;&#12540;&#12479;&#12398;&#12459;&#12483;&#12467;&#12434;&#21066;&#38500;;&#12459;&#12483;&#12467;&#12395;&#34920;&#35352;&#12422;&#12428;&#12364;&#12354;&#12427;
MaxTemp$&#22320;&#28857; <- str_replace_all(MaxTemp$&#22320;&#28857;, pattern = "\\&#65288;.+?\\&#65289;", replacement = "")
MaxTemp$&#22320;&#28857; <- str_replace_all(MaxTemp$&#22320;&#28857;, pattern = "\\(.+?\\)", replacement = "")
MaxTemp$&#22320;&#28857; <- str_replace_all(MaxTemp$&#22320;&#28857;, pattern = "\\&#65289;", replacement = "")

#&#21508;&#37117;&#36947;&#24220;&#30476;&#12398;&#26368;&#39640;&#27671;&#28201;&#12434;&#25277;&#20986;
#&#12487;&#12540;&#12479;&#20445;&#31649;&#29992;&#22793;&#25968;
NewMaxTemp <- data.frame()
#&#20966;&#29702;
for(n in 1:47){
  #&#37117;&#36947;&#24220;&#30476;&#12434;&#25277;&#20986;
  GetPrefData <- MaxTemp[which(MaxTemp[, 2] %in%
                                 grep(JPNPref@data$name_local[n], MaxTemp[, 2], value = TRUE)),]
  #&#26368;&#39640;&#27671;&#28201;&#12434;&#38477;&#38918;&#12391;&#20006;&#12403;&#26367;&#12360;
  GetPrefData <- GetPrefData[order(GetPrefData[, 10], decreasing = TRUE),]
  #&#35251;&#28204;&#25152;&#12398;&#23550;&#35937;&#37117;&#36947;&#24220;&#30476;
  GetKansokujyo <- JPNPref@Kansokujyo[which(JPNPref@Kansokujyo[, 1] %in%
                                              grep(substr(JPNPref@data$name_local[n], 1, 2),
                                                   as.character(JPNPref@Kansokujyo[, 1]), value = TRUE)),]
  #&#35251;&#28204;&#25152;&#12398;&#32076;&#24230;&#32239;&#24230;&#12434;&#21462;&#24471;
  LatLonData <- GetKansokujyo[which(GetKansokujyo[, 2] %in% GetPrefData[1, 3]),][1, 4:3]
  #1&#20301;&#12398;&#22320;&#28857;&#21517;&#12392;&#26368;&#39640;&#27671;&#28201;,&#32076;&#24230;&#32239;&#24230;&#12434;&#32080;&#21512;
  NewMaxTemp <- rbind(NewMaxTemp, cbind(JPNPref@data$name_local[n], GetPrefData[1, c(3, 10)], LatLonData))}

#1&#21015;&#30446;&#12392;2&#21015;&#30446;&#12434;&#32080;&#21512;&#24460;&#12395;1&#21015;&#30446;&#12434;&#32622;&#12365;&#25563;&#12360;
NewMaxTemp[, 1] <- paste0(NewMaxTemp[, 1], ":", NewMaxTemp[, 2])

#2&#21015;&#30446;&#12434;&#21066;&#38500;
NewMaxTemp <- NewMaxTemp[, -2]

#&#12487;&#12540;&#12479;&#21517;&#12434;&#22793;&#26356;
colnames(NewMaxTemp) <- c("&#37117;&#36947;&#24220;&#30476;:&#22320;&#28857;&#21517;", "&#27671;&#28201;", "lat", "lon")

#JPNPref@data&#12408;&#36861;&#21152;
JPNPref@data <- cbind(JPNPref@data, NewMaxTemp[, 1:2])

#JPNPref&#12501;&#12449;&#12452;&#12523;&#12434;&#20445;&#23384;
save(JPNPref, file = "JPNPref_3.shp")

#SpatialPointsDataFrame&#12434;&#20316;&#25104;
MaxSpDF <- SpatialPointsDataFrame(SpatialPoints(NewMaxTemp[, 3:4],
                                                proj4string = CRS("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs +towgs84=0,0,0")),
                                  data = data.frame(id = as.factor(NewMaxTemp[, 1])))

#MaxSpDF&#12501;&#12449;&#12452;&#12523;&#12434;&#20445;&#23384;
save(MaxSpDF, file = "MaxSpDF.shp")

パッケージのインストール

下記コマンドを実行してください。環境によっては「terra」パッケージのバージョンが古く、「tmap」パッケージがうまく起動しないかもしれません。その場合は「install.packages(“terra”)」を実行してください。

#パッケージのインストール
install.packages("tmap")
#必要に応じて下記実行
install.packages("terra")

コマンドの紹介

詳細はコマンド、パッケージのヘルプを確認してください。また、記事内の「tmap」パッケージ利用の前準備を参考に「JPNPref_3.shp」と「MaxSpDF.shp」を準備してください。

#&#12497;&#12483;&#12465;&#12540;&#12472;&#12398;&#35501;&#12415;&#36796;&#12415;
library("tcltk")
library("tmap")

#&#20316;&#25104;&#12375;&#12383;&#12300;JPNPref_3.shp&#12301;&#12471;&#12455;&#12540;&#12503;&#12501;&#12449;&#12452;&#12523;&#12434;&#35501;&#12415;&#36796;&#12416;
load(paste0(as.character(tkgetOpenFile(title = "&#12501;&#12449;&#12452;&#12523;&#12434;&#36984;&#25246;",
                                       filetypes = '{"&#12501;&#12449;&#12452;&#12523;" {".*"}}',
                                       initialfile = c("*.*")))))

#&#20316;&#25104;&#12375;&#12383;&#12300;MaxSpDF.shp&#12301;&#12471;&#12455;&#12540;&#12503;&#12501;&#12449;&#12452;&#12523;&#12434;&#35501;&#12415;&#36796;&#12416;
load(paste0(as.character(tkgetOpenFile(title = "&#12501;&#12449;&#12452;&#12523;&#12434;&#36984;&#25246;",
                                       filetypes = '{"&#12501;&#12449;&#12452;&#12523;" {".*"}}',
                                       initialfile = c("*.*")))))

#&#12503;&#12525;&#12483;&#12488;&#20986;&#21147;&#12434;&#36984;&#25246;&#12377;&#12427;:tmap_mode&#12467;&#12510;&#12531;&#12489;
#&#12503;&#12525;&#12483;&#12488;&#20316;&#25104;&#21069;&#12395;&#23455;&#34892;&#12377;&#12427;&#12371;&#12392;&#12391;&#20986;&#21147;&#26041;&#27861;&#12434;&#36984;&#25246;&#12377;&#12427;&#12371;&#12392;&#12364;&#12391;&#12365;&#12414;&#12377;
#ggplot2&#12391;&#12503;&#12525;&#12483;&#12488;
#&#12458;&#12503;&#12471;&#12519;&#12531;&#12434;plot&#12395;&#12377;&#12427;
tmap_mode("plot")
#leaflet&#12391;&#12503;&#12525;&#12483;&#12488;
#&#12458;&#12503;&#12471;&#12519;&#12531;&#12434;view&#12395;&#12377;&#12427;
tmap_mode("view")

#&#31777;&#26131;&#12503;&#12525;&#12483;&#12488;:qtm&#12467;&#12510;&#12531;&#12489;
qtm(JPNPref, fill = "&#27671;&#28201;", text = "&#37117;&#36947;&#24220;&#30476;:&#22320;&#28857;&#21517;", style = "gray",
    text.root = 3, legend.show = TRUE)

#&#22522;&#26412;&#12399;tm_shape&#12467;&#12510;&#12531;&#12489;&#12395;tm_XXXX&#12467;&#12510;&#12531;&#12489;&#12434;&#23455;&#34892;&#12375;&#12390;&#20316;&#25104;&#12377;&#12427;
tm_shape(JPNPref) +
  tm_polygons("&#27671;&#28201;", id = "&#37117;&#36947;&#24220;&#30476;:&#22320;&#28857;&#21517;", legend.show = TRUE) +
  tm_shape(MaxSpDF) +
  tm_bubbles(size = .1, "blue") +
  tm_style("gray")

###&#20363;&#12360;&#12400;&#27671;&#28201;&#12391;&#20998;&#21106;&#12375;&#12390;&#12503;&#12525;&#12483;&#12488;###
#&#27671;&#28201;&#12434;&#21306;&#20998;&#20998;&#12369;:&#12300;fancycutp&#12301;&#12497;&#12483;&#12465;&#12540;&#12472;&#12434;&#21033;&#29992;
#https://www.karada-good.net/analyticsr/r-544
if(!require("fancycut", quietly = TRUE)){
  install.packages("fancycut");require("fancycut")
}
#&#20998;&#39006;
CutLabel <- wafflecut(x = JPNPref@data$&#27671;&#28201;,
                      intervals = c("[0, 10)", "[10, 15)", "[15, 20)", "[20, 30]"),
                      buckets = c("0-9", "10-14", "15-19", "20-30"),
                      unmatched.bucket = "&#31684;&#22258;&#22806;")
#&#32080;&#21512;
JPNPref@data <- cbind(JPNPref@data, CutLabel)

####ggplot2&#12391;&#12503;&#12525;&#12483;&#12488;###
tmap_mode("plot") +
  tm_shape(JPNPref) +
  tm_polygons("&#27671;&#28201;", id = "&#37117;&#36947;&#24220;&#30476;:&#22320;&#28857;&#21517;", legend.show = TRUE) +
  tm_facets(by = "CutLabel") +
  tm_shape(MaxSpDF) +
  tm_bubbles(size = .1, "red") +
  tm_style("gray")

####leaflet&#12391;&#12503;&#12525;&#12483;&#12488;###
tmap_mode("view") +
tm_shape(JPNPref) +
  tm_polygons("&#27671;&#28201;", id = "&#37117;&#36947;&#24220;&#30476;:&#22320;&#28857;&#21517;", legend.show = TRUE) +
  #&#20998;&#21106;:tm_facets&#12467;&#12510;&#12531;&#12489;;
  #sync&#12458;&#12503;&#12471;&#12519;&#12531;:TRUE&#12434;&#35373;&#23450;&#12377;&#12427;&#12392;&#21508;&#20998;&#21106;&#12364;&#21516;&#26399;&#12375;&#12414;&#12377;
  tm_facets(by = "CutLabel", sync = TRUE) +
  tm_shape(MaxSpDF) +
  tm_bubbles(size = .1, "red") +
  tm_style("gray")

出力例

・例えば気温で分割してggplot2でプロット

・例えば気温で分割してリーフレットでプロット

拡大・縮小の下にあるレイヤーボタンより表示レイヤーを選択することが可能です。

補足:国土数値情報の郵便局データを利用する

国土交通省で公開している国土数値情報の郵便局データを利用して各都道府県の郵便局の所在地をプロットする方法です。なお、データは全国(ファイル名:P30-13.zip)を使用しています。

国土数値情報の郵便局データ:https://nlftp.mlit.go.jp/ksj/gml/datalist/KsjTmplt-P30.html#prefecture00

#&#24517;&#35201;&#12497;&#12483;&#12465;&#12540;&#12472;&#12398;&#35501;&#12415;&#36796;&#12415;&#12392;&#12452;&#12531;&#12473;&#12488;&#12540;&#12523;
if(!require("rgdal", quietly = TRUE)){
  install.packages("rgdal");require("rgdal")
}
if(!require("tidyverse", quietly = TRUE)){
  install.packages("tidyverse");require("tidyverse")
}
library("tcltk")
library("tmap")

#&#12480;&#12454;&#12531;&#12525;&#12540;&#12489;&#12375;&#12383;shp&#12487;&#12540;&#12479;&#12434;&#35501;&#12415;&#36796;&#12415;
#&#35501;&#12415;&#36796;&#12415;&#12395;&#26178;&#38291;&#12364;&#12363;&#12363;&#12426;&#12414;&#12377;
JPNPref <- readOGR(paste0(as.character(tkgetOpenFile(title = "shp&#12501;&#12449;&#12452;&#12523;&#12434;&#36984;&#25246;",
                                                     filetypes = '{"shp&#12501;&#12449;&#12452;&#12523;" {".shp"}}',
                                                     initialfile = c("*.shp")))),
                   GDAL1_integer64_policy = TRUE, use_iconv = TRUE,
                   #&#29872;&#22659;&#12395;&#12424;&#12387;&#12390;&#12399;"utf-8"&#12395;&#22793;&#26356;
                   encoding = "shift-jis")

#&#21015;&#21517;&#12434;&#35469;&#35672;&#12391;&#12365;&#12427;&#12424;&#12358;&#12395;&#22793;&#26356;
JPNPref@data <- JPNPref@data %>%
  rename(latitude = X, longtude = Y)

#&#12300;ggplot2&#12301;&#12497;&#12483;&#12465;&#12540;&#12472;&#12391;&#12503;&#12525;&#12483;&#12488;
tmap_mode("plot")
tm_shape(JPNPref) +
  tm_bubbles(size = .0001,
             col = "blue",
             border.col = NA,
             border.lwd = NA,
             alpha = 0.2) +
  tm_style("gray")

#&#12300;leaflet&#12301;&#12497;&#12483;&#12465;&#12540;&#12472;&#12391;&#12503;&#12525;&#12483;&#12488;
tmap_mode("view")
tm_shape(JPNPref) +
  tm_bubbles(size = .0001,
             col = "blue",
             border.col = NA,
             border.lwd = NA,
             alpha = 0.2) +
  tm_style("gray")

出力例

郵便局の所在位置で日本列島が浮かび上がりました。


少しでも、あなたの解析が楽になりますように!!

タイトルとURLをコピーしました