西原史暁 (Fumiaki Nishihara)氏のページ,
「Rによるデータクリーニング実践――政府統計からのグラフ作成を例として」
で,「まずは、e-Stat から男女別学校数をまとめた統計表の Excel ファイルをダウンロードしよう。先に述べたように、1年度につき1ファイルなので、必要となる年度の Excel ファイルを1つずつ手動でダウンロードする。この作業もできれば自動化したいところであったが、自動化のスクリプトを書く方がよほど時間がかかりそうだったので、手動で処理することにした。」
と,あった。ダウンロードすべきファイルは実に 1986 年から 2016 年までの 31 個である。私は,手動ではやりたくない。結果として,プログラムもそんなに複雑ではなかった。
1. 「学校基本調査,男女別学校数」のページを開く。以下の 2 ページ。
https://www.e-stat.go.jp/stat-search/files?page=1&query=%E7%94%B7%E5%A5%B3%E5%88%A5%E5%AD%A6%E6%A0%A1%E6%95%B0&layout=dataset&toukei=00400001&tstat=000001011528&metadata=1&data=1
https://www.e-stat.go.jp/stat-search/files?page=1&query=%E7%94%B7%E5%A5%B3%E5%88%A5%E5%AD%A6%E6%A0%A1%E6%95%B0&layout=dataset&toukei=00400001&tstat=000001011528&metadata=1&data=2
このページを表示させて,1 ファイルずつ指定して,保存したのだろうか。
しかも,「ファイル名を西暦年としたことには理由がある。おそろしいことに、e-Stat から手に入る Excel ファイルには、それが何年の調査結果なのかを示す情報がまったく入っていない。このため、ファイル名に西暦年の情報を入れておくことで、あとでデータクリーニングをするときにファイル名から西暦年の情報が得られるようにしておくのだ。」というように,名前を変えながら(間違えないように)保存しないといけなかったのか。大変だ。
2. このページの html ファイルには,ダウンロードすべきファイルの情報が書かれている。
ページを別ファイルで保存する。2 ページあるので,page1.html, page2.htmlと して保存する。
3. 年度とそ年度の結果の url を取り出す。
調査年度は '<span class="stat-sp">調査年月 </span>2019年</li>' のような行にある。
ここから 2019 を取り出すのは簡単だ。
ダウンロードすべきファイル情報は,キーワード"EXCEL" を含む行にある。
'<a href="https://www.e-stat.go.jp/stat-search/file-download?statInfId=000031893802&fileKind=0" class="stat-dl_icon stat-icon_0 stat-icon_format js-dl stat-download_icon_left" data-file_id="000008560862" data-release_count="1" data-file_type="EXCEL" tabindex="22">'
ここから 'https://www.e-stat.go.jp/stat-search/file-download?statInfId=000031893802&fileKind=0' のような部分を取り出す。ただし,実際にアクセするときには,& は 単に一文字の & にしないといけないので注意。
4. utils::download.file() でファイル(*.xls, *.xlsx) をダウンロードする。
実は,2015 年以降は *.xlsx なので openxlsx::read.xlsx で読めるのだが,2014 年以前は *.xls なので読めない。
xls, xlsx の両方が読めるのは eadxl::read_excel() だが,これは URL を指定してネットから読むことができない。
そこでまず,utils::download.file() を使って,上記 3. で取り出した url の内容を保存する。保存時に年度により適切な拡張子を付けてやる。
5. *.xls, *.xlsx を readxl::read_excel() で読み込み,write.csv() で csv ファイルに書き出す。
プログラムは以下のようになる。使用するしないにかかわらず,1963 年〜2019 年までのデータをダウンロードした。
library(readxl) # read_excel() を使うため
url.info.pages = c("page1.html", "page2.html") # ダウンロードするファイル情報を含むページの html ファイル
last.file = FALSE # 年次が同じ2種類のファイルが掲載されているので,必要な最後のファイルが来たらおしまいにする
for (page in url.info.pages) { # 2 ページについて
text = readLines(page) # テキストとして読み込む
for (i in 1:length(text)) { # 各行を見ていく
txt = text[i] # 当該行
if (grepl("調査年月", txt)) { # 「調査年月」を含む行から 4 桁の西暦年 year を残す
year = sub("^.+</span>", "", txt)
year = sub("年.+", "", year)
}
if (grepl("data-file_type=\"EXCEL\"", txt)) { # キーワード EXCEL を含む行から,URL を残す
url = sub("<a href=\"", "", txt)
url = sub("&fileKind=0.*", "&fileKind=0", url)
if (year < 2015) { # 2015 年以前は *.xls
file.name = paste0(year, ".xls")
} else { # 2015 年以降は *.xlsx
file.name = paste0(year, ".xlsx")
}
download.file(url, file.name) # url からファイルを(そのまま)ダウンロードし,保存
df = read_excel(file.name) # Excel ファイルを読み込む
write.csv(df, file= paste0(year, ".csv")) # csv ファイルとして書き出す。ファイル名は 2019.csv のように
cat('output to ', paste0(year, ".csv"), "\n\n")
if (year == 1970) { # 処理したフィあるが 1970 年のものならこれでおしまい(調査年順に掲載されていない)
last.file = TRUE # 最後のファイルだとして内側の for ループを抜ける
break
}
}
if (last.file) { # 最後のファイルなら外側の for ループも抜ける(終了)
break
}
}
}
「e-Stat から入手したデータの利用にあたり,やるべき事は単純だ」 へと続く
※コメント投稿者のブログIDはブログ作成者のみに通知されます