千葉県市区町村の高齢化率
sf パッケージを用いたコロプレス・マップのプロット。
今回は千葉県市区町村の高齢化率を例にとる。
まずは、千葉県行政区分のシェイプファイルが必要だが、これは ESRI ジャパンが無償配布している「全国市区町村界データ」から、千葉県の部分を取り出して利用する。
入手先は、
ダウンロードした zip ファイルを解凍、Rに読み込んで、千葉県のデータのみを抽出する。なお、末尾(60番目)のオブジェクトは「所属未定地」なので削除しておく。
library(dplyr)
jp <- sf::st_read("japan_ver81.shp")
jp %>% filter(KEN %in% "千葉県") -> chiba
chiba <- chiba[-60,]
次に、人口の最新データを千葉県の公式サイトから入手する。
ここにある「第1表 男女別、年齢(3区分)別人口-県・市区町村・11地域(エクセル:19KB)」に65歳以上の人口及び、その割合が市区町村別に掲載されている。
このエクセル・ファイルをRに直接読み込んでもいいのだが、処理が煩雑になるので、必要な部分だけ CSVファイルに変換したものを作成して gist にアップロードしてある。
これをダウンロードしRに読み込んで、シェイプファイルとマージする。
pop <- read.csv("chiba_pop_20180401.csv")
chiba2 <- left_join(chiba, pop, by = c("SIKUCHOSON" = "sikuchoson"))
もとの人口データで、コラム名「r65」が高齢化率を表している。
これを cut_interval 関数で5%刻みの階級に分類して、それぞれ異なる色で塗り分ける。
library(ggplot2)
library(ggthemes)ggplot() +
geom_sf(data = chiba2,
aes(fill = cut_interval(r65, length = 5)),
alpha = 0.8, colour = 'grey20', size = 0.1) +
scale_fill_brewer(palette = "YlOrRd",
name = "Residents of \nage 65 and older(%)") +
theme_bw() +
theme(axis.line = element_blank(),
axis.text.x = element_blank(),
axis.text.y = element_blank(),
axis.ticks = element_blank(),
panel.border = element_blank()) +
theme(legend.position = c(0.95, 0.22))
太平洋ひとりぼっち
これの第2章に、アカウミガメの移動軌跡の例が載っている。
発信機をつけて人工衛星で追跡したら、メキシコから日本まで、太平洋横断の旅が観察された。その経過をプロットするというもの。
データファイルとRスクリプトは上記サイトからダウンロードできる(Data sets and script の “2”)。
###################################################
### code chunk number 52: cm.Rnw:1002-1004
###################################################
turtle_df <- read.csv("seamap105_mod.csv")
summary(turtle_df)
###################################################
### code chunk number 54: cm.Rnw:1021-1027
###################################################
timestamp <- as.POSIXlt(strptime(as.character(turtle_df$obs_date), "%m/%d/%Y %H:%M:%S"), "GMT")
turtle_df1 <- data.frame(turtle_df, timestamp=timestamp)
turtle_df1$lon <- ifelse(turtle_df1$lon < 0, turtle_df1$lon+360, turtle_df1$lon)
turtle_sp <- turtle_df1[order(turtle_df1$timestamp),]
coordinates(turtle_sp) <- c("lon", "lat")
proj4string(turtle_sp) <- CRS("+proj=longlat +ellps=WGS84")
###################################################
### code chunk number 55: cm.Rnw:1031-1034
###################################################
library(maptools)
gshhs.c.b <- system.file("share/gshhs_c.b", package="maptools")
pac <- Rgshhs(gshhs.c.b, level=1, xlim=c(130,250), ylim=c(15,60), verbose=FALSE)
###################################################
### code chunk number 56: cm.Rnw:1039-1051
###################################################
plot(pac$SP, axes=TRUE, col="khaki2", xaxs="i", yaxs="i")
plot(turtle_sp, add=TRUE)
m_rle <- rle(months(turtle_sp$timestamp))
clen <- cumsum(m_rle$lengths[-length(m_rle$lengths)])-1
crds <- coordinates(turtle_sp)
text(crds[clen,], labels=m_rle$values[-1], pos=3, offset=1.5, srt=45)
同じような図を、ggplot2 で描いてみた。
library(ggplot2)
library(ggthemes)
turtle_df <- read.csv("seamap105_mod.csv")
timestamp <- as.POSIXlt(strptime(as.character(turtle_df$obs_date),
"%m/%d/%Y %H:%M:%S"), "GMT")
turtle_df1 <- data.frame(turtle_df, timestamp = timestamp)
turtle_df1$lon <- ifelse(turtle_df1$lon < 0, turtle_df1$lon + 360, turtle_df1$lon)
turtle_sp <- turtle_df1[order(turtle_df1$timestamp),]
m_rle <- rle(months(turtle_sp$timestamp))
clen <- cumsum(m_rle$lengths[-length(m_rle$lengths)]) - 1
turtle_sp_pts <- turtle_sp[clen,]
turtle_sp_pts <- cbind(turtle_sp_pts, label = m_rle$values[-1])
world <- map_data('world2')
p <- ggplot() + geom_map(data = world, map = world,
aes(x = long, y = lat, group = group, map_id =r egion),fill = "#ffffbb", colour = "#7f7f7f", size = 0.5)
p <- p + xlim(115, 270) + ylim(0, 60)
p <- p + geom_line(data = turtle_sp, aes(x = lon, y = lat),
colour = "darkblue", alpha=0.4)
p <- p + geom_point(data = turtle_sp_pts, aes(x = lon, y = lat),
colour = "darkblue", size = 3)
p <- p + geom_text(data = turtle_sp_pts,aes(x = lon + 1, y = lat + 1, label = label), angle = 45,
colour = "darkred", hjust = -0.1, nudge_x = -0.1)
p <- p + coord_equal() + theme_map()
print(p)
なお、このアカウミガメのデータは、だいぶ以前に Nature で紹介された研究からのものと思われる。
関東甲信の梅雨/期間と降水量の関係
以前の記事「関東甲信・梅雨入り日の推移」の続き。
気象庁のウェブページにある表:
これをスクレイピングして、各年の梅雨の期間(日数)を求め、これと降水量の平年比との関係を調べる。
library(rvest)
library(dplyr)
library(stringr)
library(ggplot2)dt <- read_html("https://www.data.jma.go.jp/fcd/yoho/baiu/kako_baiu09.html")
dt %>% html_nodes(xpath = "//table") %>% html_text() %>%
str_replace_all(pattern = "-", replacement = ",") %>%
str_replace_all(pattern = "ごろ", replacement = ",") %>%
str_replace_all(pattern = "年", replacement = "-") %>%
str_replace_all(pattern = "月", replacement = "-") %>%
str_replace_all(pattern = "日", replacement = "") %>%
str_split("\n", simplify = T) -> tabtab2 <- str_split(tab[2,], ",", simplify = T)
tab3 <- tab2[6:(nrow(tab2)-2),]
ここまで実行すると、以下のような文字列のテーブルができる。
> head(tab3)
[,1] [,2] [,3]
[1,] "1951-6-15" "7-18" "121 "
[2,] "1952-6-14" "7-16" "151 "
[3,] "1953-6- 1" "7-24" "149 "
[4,] "1954-6- 6" "7-25" "135 "
[5,] "1955-6-13" "7- 9" "60 "
[6,] "1956-6- 9" "7-26" "81 "
以下、梅雨入りの日と梅雨明けの日の差分を求め、年号および降水量とともにデータフレームを作る。
tab3[,1] %>% str_sub(start = 1, end = 4) -> Year
Duration <- as.Date(paste0(Year, "-", tab3[,2])) - as.Date(tab3[,1])
duration <- as.numeric(Duration)
rainfall <- as.numeric(tab3[,3])
year <- as.numeric(Year)df <- data.frame(year, duration, rainfall)
梅雨の日数の推移のプロット:
g <- ggplot(df,aes(x = year, y = duration))
g <- g + geom_line(color = "darkblue", size = 0.5, alpha = 0.4)
g <- g + geom_point(color = "darkblue")
g <- g + theme(axis.title = element_text(size = 14))
g <- g + ylim(0,80)
g <- g + ylab("Duration (days)")
g <- g + ggtitle("梅雨の期間(日)")
g <- g + theme(plot.title = element_text(size=18))
print(g)
降水量平年比の推移のプロット:
g <- ggplot(df,aes(x = year, y = rainfall))
g <- g + geom_line(color = "darkblue", size = 0.5, alpha = 0.4)
g <- g + geom_point(color = "darkblue")
g <- g + theme(axis.title = element_text(size = 14))
g <- g + ylim(0,160)
g <- g + ylab("Rainfall (average ratio; %)")
g <- g + ggtitle("降水量平年比(%)")
g <- g + theme(plot.title = element_text(size = 18))
print(g)
最後に期間と降水量の散布図:
g <- ggplot(df,aes(x = duration, y = rainfall))
g <- g + geom_point(color = "darkblue")
g <- g + theme(axis.title = element_text(size = 14))
g <- g + xlim(20,80) + ylim(40,160)
g <- g + xlab("Duration (day)") + ylab("Rainfall (average ratio; %)")
g <- g + ggtitle("梅雨の期間と降水量平年比")
g <- g + theme(plot.title = element_text(size = 18))
g <- g + stat_smooth(method = "lm", se = T, color = "grey60")
print(g)
ほんの少し、正の相関があるように見えるが、
> cor.test(df$rainfall, df$duration, use = "complete.obs")
Pearson's product-moment correlation
data: df$rainfall and df$duration
t = 1.459, df = 65, p-value = 0.1494
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
-0.06491531 0.40112109
sample estimates:
cor
0.17807
p-value = 0.1494 なので、有意ではない。
積み上げ折れ線グラフ
例として、国立がんセンターの「がんに関する統計データ」の子宮頸がん死亡データを使う。
ここからエクセルファイルをダウンロードしRに読み込む。
エクセルデータを読み込むためのパッケージには各種あるが、ここでは gdata を用いている。
続いて、子宮頸部のコード(=17)を確認して、該当データを抽出する。
なお、データは5歳刻みの年齢階級に分割されているが、この並びを反転させておくのが、グラフをプロットするためのポイント。
library(gdata)
library(ggthemes)
library(ggplot2)
library(reshape2)
fn <- "cancer_mortality(1958-2017).xls"
url <- paste0("https://ganjoho.jp/data/reg_stat/statistics/dl/", fn)
download.file(url, destfile = fn)
d <- read.xls(fn, sheet = 3)
cr <- d[d$コード == 17,]
year <- cr$死亡年
num <- cr[25:8]colnames(num) <- rev(c( "0-4", "5-9", "10-14", "15-19",
"20-24", "25-29", "30-34", "35-39", "40-44",
"45-49", "50-54", "55-59", "60-64", "65-69",
"70-74", "75-79", "80-84", "85-"))
積み上げ折れ線グラフは geom_area で簡単にプロットできる。
df <- melt(cbind(year, num), id.var = "year")
colnames(df) <- c("Year", "Age", "Number")cols = colorRampPalette(c("#0068b7", "white", "#f39800"))
p <- ggplot(df, aes(x = Year, y = Number))
p <- p + geom_area(aes(group = Age, fill = Age))
p <- p + scale_fill_manual(values = cols(18))
p <- p + theme_economist()
p <- p + theme(axis.title = element_text(size = 14))
p <- p + ggtitle("子宮頸がん死亡数(1958〜2017)")
print(p)
関東甲信・梅雨入り日の推移
気象庁のウェブサイトに「昭和26年(1951年)以降の梅雨入りと梅雨明け(確定値):関東甲信」のページがある。
ここに掲載されている表(table)を例に、ウェブスクレイピングを行ってみた(それに続く処理は参考である)。
library(rvest)
library(dplyr)
dt <- read_html("https://www.data.jma.go.jp/fcd/yoho/baiu/kako_baiu09.html")dt %>% html_nodes(xpath = "//table") %>% html_text() -> tab
tab2 <- unlist(strsplit(tab [ [ 2 ] ], "\n"))
> head(tab2)
[1] "関東甲信"
[2] "年"
[3] "入り"
[4] "明け"
[5] "梅雨の時期の降水量の平年比(地域平均値)(%)"
[6] "1951年6月15日ごろ7月18日ごろ121 "
> tail(tab2)
[1] "2014年6月 5日ごろ7月21日ごろ116 "
[2] "2015年6月 3日ごろ7月10日ごろ128 "
[3] "2016年6月 5日ごろ7月29日ごろ74 "
[4] "2017年6月 7日ごろ7月 6日ごろ71 "
[5] "2018年6月 6日ごろ6月29日ごろ92 "
[6] "平 年6月 8日ごろ7月21日ごろ "
このように、ヘッダー部分が5個、その後に各年のデータ、そして最後に平年データという具合に、表の要素が文字列として取得できる。
以下は、これらの文字列から梅雨入り日を抽出し、回帰直線とともにプロットするスクリプト。
library(ggplot2)
library(ggthemes)
date <- chartr("月", "-", substr(tab2[6:(length(tab2) - 1)], 6, 9))
Date <- as.Date(paste0("2000-", date))
year <- 1951:(1950 + length(Date))
df <- data.frame(year, Date)
g <- ggplot(data = df, aes(x = year, y = Date))
g <- g + geom_line(color = "darkblue", size = 0.5, alpha = 0.4)
g <- g + geom_point(color = "darkblue")
g <- g + stat_smooth(method = "lm", se = F, color = "grey60")
g <- g + theme_economist()
g <- g + theme(axis.title = element_text(size = 15))
print(g)
太陽黒点数の推移プロット
国立天文台のサイト:
http://solarwww.mtk.nao.ac.jp/mitaka_solar1/data03/sunspots/number
から、太陽黒点の月平均個数を取得して、折れ線グラフを描く。
もうだいぶ前に作ったものなので、稚拙なスクリプトではあるが、いちおう動作する。
library(ggplot2)
library(ggthemes)
last.year <- as.numeric(substr(Sys.time(), 1, 4))
url <- "http://solarwww.mtk.nao.ac.jp/mitaka_solar1/data03/sunspots/number/rz"
df <- data.frame(NULL, NULL, NULL)for(year in 1929:last.year) {
url2 <- paste(url, as.character(year), ".txt", sep = "")
rz <- file(url2, "r")
while(length(str <- readLines(con = rz, 1)) != 0) {
if(length(grep("Mon", str)) == 1) {
vec <- unlist(strsplit(str, " "))
vec <- vec[vec != ""]
df <- rbind(df, as.numeric(tail(vec, n = 3)))
}
}
}seq <- 0:(nrow(df) - 1)
yy <- as.character(seq %/% 12 + 1929)
mm <- as.character(seq %% 12 + 1)
date <- as.Date(paste(yy, "-", mm, "-01", sep = ""))
sunspots.df <- cbind(date, df)
names(sunspots.df) <- c("Date", "North", "South", "Total")str <- substr(tail(sunspots.df$Date, 1), 1, 7)
substring(str, 5, 5) <- "/"
title <- paste("太陽黒点相対数の推移(月平均; 1929/01 ~ ", str, ")", sep ="")
g <- ggplot(sunspots.df, aes(x = Date, y = Total))
g <- g + geom_line(color = "darkblue", size = 0.1)
g <- g + geom_point(size = 0.5)
g <- g + xlab("year") + ylab("Number of Sun Spots")
g <- g + ggtitle(title)
g <- g + theme_economist()
g <- g + theme(axis.title=element_text(size=14))
print(g)
sf パッケージでGIS
ここでは例として、
で配布されているシェイプファイルとデータファイルから、単純なコロプレスマップの描画を行ってみる。
まず、次の zip ファイルをダウンロード、解凍する。
- 小選挙区ポリゴン(shape形式)(2017年6月9日アップロード、6月10日14時修正:川崎市麻生区の飛び地を表示)
とりあえず、sf パッケージの st_read 関数で、これを読み込み、「白地図」を描いてみよう。
library(ggplot2)
jp <- sf::st_read("senkyoku289polygon.shp")
ggplot() + geom_sf(data = jp, size = 0.1)
続いて、国勢調査データをダウンロードし、解凍。
なお、Linux OS などの utf8 な環境ではファイル名が文字化けするので、unzip にオプションを付ける。
unzip -O sjis H27kokucho_senkyoku289.zip
R に戻り、以下のようにして、男女別人口及び世帯数のデータファイルを読み込む。
pop <- read.csv(
"289選挙区_H27_02_男女別人口及び世帯数.csv",
fileEncoding = "Shift_JIS")
上で読み込んだ2つのオブジェクトをマージする。
このとき、小選挙区コード(“kucode”と“KuCode”)が一致するようにデータの並びを整える。
library(dplyr)
jp2 <- left_join(jp, pop, by = c("kucode" = "KuCode"))
最後に、再び地図をプロット。
最初の「白地図」に各選挙区の人口総数による明暗を付加する。
ggplot(jp2, aes(fill=総数)) +
geom_sf(size=0.1) +
scale_fill_distiller(direction=1)