統計データを用いた作図:HTML編

ここでは,消費生活協同組合数の推移の折れ線グラフを作成します。

ここで用いる統計データはExcelファイルではなく,HTMLの表で公開されているものです。

ノート厚生労働省「第1表 組合数及び組合員数の状況(消費生活協同組合(連合会)実態調査(平成11年度調査)結果)」

この表には,1966(昭和41)年度から1999(平成11)年度のデータが示されています。 e-Statには,より長期にわたるデータがあるため,上記の表は授業では使っていません。 このページの目的は,Rで作図の練習をすることですので,やってみましょう。

1 HTMLの表の読み込み

上記リンク先のデータを入手し,Rで読み込みます。

library(rvest)

# 厚生労働省「第1表 組合数及び組合員数の状況」
url <- "https://www.mhlw.go.jp/toukei/saikin/hw/shakai/seikyo/hyo1-1.html"
html <- rvest::read_html(url)

df <- rvest::html_table(html)[[1]]
head(df)
# A tibble: 6 × 11
  X1     X2       X3       X4       X5       X6    X7    X8    X9    X10   X11  
  <chr>  <chr>    <chr>    <chr>    <chr>    <chr> <chr> <chr> <chr> <chr> <chr>
1 "年度" "組合数" "組合数" "組合数" "組合数" "組合員… "組合員… "組合員… "1組合… "1組合… "1組合…
2 "年度" "総数"   "地域"   "職域"   "連合会" "総数"… "地域"… "職域"… "総数"… "地域"… "職域"…
3 ""     "組合"   "組合"   "組合"   "組合"   "人"  "人"  "人"  "人"  "人"  "人" 
4 ""     ""       ""       ""       ""       ""    ""    ""    ""    ""    ""   
5 "41"   "1,225"  "525"    "661"    "39"     "8,1… "4,5… "3,6… "6,8… "8,6… "5,4…
6 "42"   "1,212"  "516"    "658"    "38"     "9,3… "5,4… "3,8… "7,9… "10,… "5,8…

複雑な表ではないため,かなり綺麗に読み取れています。 ただし,数字が文字列として認識されており,このままでは図を描くことはできません。

names(df) <- paste0(paste(df[1, ], df[2, ], sep = "("), ")")
names(df)[1] <- df[1, 1]
Warning: The `value` argument of `names<-()` must be a character vector as of tibble
3.0.0.
df <- df[-c(1:4), ]

dfcoop <- data.frame(df, check.names = FALSE)

# 年度の西暦に変換してから,削除する
dfcoop[dfcoop[, "年度"] == "元", "年度"] <- "1"
dfcoop[, "年度"] <- as.double(dfcoop[, "年度"])
nen <- ifelse(dfcoop[, "年度"] > 31, dfcoop[, "年度"] + 1925, dfcoop[, "年度"] + 1988)
dfcoop[, "年度"] <- nen
rownames(dfcoop) <- dfcoop[, "年度"]
dfcoop <- dfcoop[, -1]
for (i in 1:ncol(dfcoop)) {
  dfcoop[, i] <- as.double(gsub(",", "", dfcoop[, i]))
}

前処理の終わったデータは,以下の表のようになります。

library(DT)

caption <- "消費生活協同組合(連合会)実態調査(平成11年度調査) - 組合数及び組合員数の状況"
x <- DT::datatable(
  dfcoop, caption = caption, rownames = TRUE,
  extensions = 'Buttons',
  options = list(
    pageLength = 10,
    dom = 'Blfrtip',
    buttons = list(
      c('csv', 'excel'),
      I('colvis')
    )
  )
) |>
  DT::formatCurrency(c(1:ncol(dfcoop)), currency = "", interval = 3, mark = ",", digits = 0)
# DT::saveWidget(x, file = file.path(outdir, "dfcoop.html"), selfcontained = FALSE, libdir = "libs")
x

2 折れ線グラフと棒グラフ

まず,折れ線グラフを作成してみる。 横軸に年度を取り,縦軸に組合数(総数)を取った図を描くと以下のようになる。

tmp <- as.matrix(dfcoop[, "組合数(総数)", drop = FALSE])

layout(matrix(1:2, ncol=2))
plot(rownames(tmp), tmp, type = "l", xlab = "年度", ylab = "組合数", las = 1)
plot(rownames(tmp), tmp, type = "l", xlab = "年度", ylab = "組合数", ylim = c(0, max(tmp)), las = 1)

左図からは,年度によって大きく変化している印象を受ける。 1975年度くらいに組合数が多くなり,その後,ほぼ以前の数に戻っている。 ただし,縦軸が0から始まっていない。 縦軸を 0 から始まるように書き直したのが,右図である。 右図からは,左図ほど大きな変化がある印象は受けない。 折れ線グラフの場合,縦軸をどうすべきかに決まりはなく,変化を強調したければ,左図のように描いてもよい。

同じデータで棒グラフを作成すると,以下のようになる。

layout(matrix(1:2, ncol=2))
barplot(t(tmp), ylim = c(1200, max(tmp)), xlab = "年度", ylab = "組合数", col = gray.colors(1), las = 1)
barplot(t(tmp), xlab = "年度", ylab = "組合数", col = gray.colors(1), las = 1)

棒グラフの場合,棒の高さが意味を持つため,縦軸に0を含めなければならず,左図のように描いてはならない。 そもそもRでは,左図のような図は縦軸の端に合わせて描画されないため,図としておかしいことがわかる。 Excelで作図する場合,このようなおかしさに気づきにくいため,注意が必要である。

3 比較可能なグラフ

次に,地域組合と職域組合の比較を試みる。

tmp <- t(as.matrix(dfcoop[, c("組合数(地域)", "組合数(職域)")]))

barplot(tmp, xlab = "年度", ylab = "組合数", las = 1, legend.text = TRUE)

積み上げ棒グラフの場合,地域組合と職域組合の合計の推移と,それぞれの推移が把握可能である。 この図は,地域組合を下に,職能組合を上にして作図した。 地域組合の変化は把握しやすい一方で,職能組合の変化は把握しづらい。 そこで,棒の上下を入れ替えてみよう。 ついでに,凡例がグラフと重なっているのを修正する。

次の図は,職域組合を下に,地域組合を上にして作図した。

par(mar = c(4, 4, 1, 8))
barplot(tmp[2:1,], xlab = "年度", ylab = "組合数", col = rev(gray.colors(2)), yaxt = "n", las = 1)
axis(2, at = seq(0, 1200, 200), label = format(seq(0, 1200, 200), big.mark = ",", scientific = FALSE), las = 1)
par(xpd = TRUE)
legend(par()$usr[2], par()$usr[4], legend = rownames(tmp), col = 1, pch = 22, pt.bg = gray.colors(2), bty = "n")

前の図と違って,職能組合の変化が把握しやすい。 また,地域組合の変化も把握しやすい。 なぜか。 これは,職能組合の変化が単調であることが理由であり,たまたまである。 このため,積み上げ棒グラフが,内容を把握しやすいグラフかどうかはデータに依存するといえる。

次に,積み上げ棒グラフを使わない方法を試みる。 次の棒グラフのように,地域組合と職域組合の棒を横に並べると,それぞれの推移が把握しやすくなる。

par(mar = c(4, 4, 1, 8))
barplot(tmp, beside = TRUE, xlab = "年度", ylab = "組合数", col = gray.colors(2), las = 1)
par(xpd = TRUE)
legend(par()$usr[2], par()$usr[4], legend = rownames(tmp), col = 1, pch = 22, pt.bg = gray.colors(2), bty = "n")

しかしながら,必ずしも見やすいとはいえない。 横軸の項目数が多すぎるためである。 これは棒グラフの限界である。

一方,折れ線グラフは複数の線があっても問題なく比較できる。

ymax <- max(dfcoop[, c("組合数(地域)", "組合数(職域)")])
plot(as.numeric(rownames(dfcoop)), dfcoop[, "組合数(地域)"], type = "l", col = 2, xlab = "年度", ylab = "組合数", ylim = c(0, ymax), las = 1, bty = "n")
par(new = TRUE)
plot(as.numeric(rownames(dfcoop)), dfcoop[, "組合数(職域)"], type = "l", col = 4, xlab = "", ylab = "", ylim = c(0, ymax), axes = FALSE)
legend("bottomright", legend = c("組合数(地域)", "組合数(職域)"), lty = 1, col = c(2, 4))

ggplot2 に慣れた場合,細かい設定が面倒だと感じるようになるだろう。