Skip to content

Instantly share code, notes, and snippets.

@uribo
Created February 23, 2023 07:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save uribo/1054d24b3b0fd0a06d994fe7d820e5b9 to your computer and use it in GitHub Desktop.
Save uribo/1054d24b3b0fd0a06d994fe7d820e5b9 to your computer and use it in GitHub Desktop.
作物統計調査のデータをダウンロードして綺麗な形でRに読み込む
##############################
# 作物統計調査のデータをダウンロードして綺麗な形でRに読み込む
# 表分類: 品目別結果樹面積、収穫量及び出荷量累年統計(昭和48年~)
##############################
# 1. 対象のデータを一覧にする ---------------------------------------------------------
base_url <- "https://www.e-stat.go.jp"
df_item <-
seq.int(2) |>
purrr::map(
function(page) {
x <-
glue::glue("{base_url}/stat-search/files?page={page}&layout=datalist&toukei=00500215&tstat=000001013427&cycle=7&year=20210&month=0&tclass1=000001032287&tclass2=000001037847&tclass3val=0&metadata=1&data=1") |>
httr2::request() |>
httr2::req_perform() |>
httr2::resp_body_html() |>
rvest::html_element("div.stat-dataset_list > div") |>
rvest::html_elements("article > div > ul")
x2 <-
x |>
rvest::html_elements(css = "li > div > div > div > a")
df_item <-
tibble::tibble(
`統計表名` = x |>
rvest::html_elements(css = "li > div:nth-child(1) > div > span") |>
rvest::html_text(trim = TRUE) |>
stringr::str_subset("(日)$", negate = TRUE),
`表名区分1` = x |>
rvest::html_element(css = "li > div > div > a") |>
rvest::html_text(trim = TRUE) |>
na.omit() |>
c(),
format = x2 |>
rvest::html_text(trim = TRUE),
url = x2 |>
rvest::html_attr(name = "href") |>
xml2::url_absolute(base = base_url))
df_item
}
) |>
purrr::list_rbind()
# エクセルファイルはurlからダウンロード可能
df_item
# 2. ダウンロード ------------------------------------------------------------------
# 数が多いので「みかん」に限定
library(dplyr)
fs::dir_create("~/Downloads/品目別結果樹面積_収穫量及び出荷量累年統計/みかん", recurse = TRUE)
df_item |>
filter(`統計表名` == "みかん") |>
ensurer::ensure(nrow(.) == 48L) |>
mutate(row_id = stringr::str_pad(row_number()-1, width = 2, pad = "0"),
.before = 2) |>
purrr::pwalk(
function(`統計表名`, row_id, `表名区分1`, url, ...) {
Sys.sleep(7)
download.file(url,
destfile = glue::glue("~/Downloads/品目別結果樹面積_収穫量及び出荷量累年統計/{統計表名}/{row_id}_{表名区分1}.xls"))
}
)
# 3. 読み込み・整形 -----------------------------------------------------------------
read_toukei_00500215 <- function(path, tidy = TRUE) {
d_raw <-
suppressMessages(
readxl::read_xls(path,
sheet = 1,
skip = 4,
na = c("-", "\u2026", "x", "nc"))
# ^^
# 欠損値として扱う文字列は「利用上の注意」を参照
# https://www.maff.go.jp/j/tokei/kouhyou/sakumotu/sakkyou_kazyu/gaiyou/index.html#12
)
d_colname_fixed <-
d_raw |>
purrr::set_names(paste(
d_raw |>
colnames() |>
stringr::str_replace_all("\\.{3}", NA_character_) |>
zoo::na.locf(),
d_raw[1, ] |>
purrr::flatten_chr() |>
stringr::str_replace_na(""),
d_raw[2, ] |>
purrr::flatten_chr() |>
stringr::str_replace_na(""),
sep = "_") |>
stringr::str_remove("_{1,}$"))
d <-
d_colname_fixed |>
dplyr::slice(seq.int(3, nrow(d_colname_fixed)))
if (tidy == TRUE) {
d <-
.tidy__toukei_00500215(d)
}
d
}
.tidy__toukei_00500215 <- function(df) {
df |>
tidyr::pivot_longer(cols = tidyselect::contains("_"),
names_to = c("細目", "var", "unit"),
names_pattern = "(.+)_(.+)_(.+)") |>
readr::type_convert(col_types = "ccccd") |>
tidyr::pivot_wider(names_from = c(var, unit),
values_from = c(value))
}
# 一つのファイルを読み込む
read_toukei_00500215("~/Downloads/品目別結果樹面積_収穫量及び出荷量累年統計/みかん/00_全国.xls",
tidy = FALSE)
# 一つのファイルを読み込む。処理しやすいように縦長に変形させる
read_toukei_00500215("~/Downloads/品目別結果樹面積_収穫量及び出荷量累年統計/みかん/00_全国.xls",
tidy = TRUE)
# 「みかん」についてすべてのファイルを読み込み、一つのデータフレームにする
df_toukei_00500215 <-
fs::dir_ls("~/Downloads/品目別結果樹面積_収穫量及び出荷量累年統計/みかん/",
regexp = ".xls$") |>
purrr::map(
function(file) {
d_meta <-
readxl::read_xls(file,
sheet = 1,
skip = 2,
n_max = 1)
read_toukei_00500215(file) |>
dplyr::mutate(`品目` = colnames(d_meta),
`地域` = d_meta[[1]],
.after = 1)
}
) |>
purrr::list_rbind()
# 「みかん」についてすべて(全国+47都道府県)のファイルを読み込み、一つのデータフレームにしたもの
glimpse(df_toukei_00500215)
# 全国、北海道...沖縄まで読み込まれているのを確認
df_toukei_00500215 |>
head()
df_toukei_00500215 |>
tail()
# みかんの5つの細目が格納されていることを確認
df_toukei_00500215 |>
count(`年次`, `品目`, `地域`) |>
filter(n != 5)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment