Rでのデータインポートまとめ(csv, Excel, SPSS, Stata, html, pdf)
はじめに
データ解析の前に必ず必要になる,データのインポート。
Rで様々な形式のデータをインポートする方法をまとめたメモです。
今回はcsv,Excel,SPSS,Stata,html,pdfについてまとめます。
後ろのやつほど面倒です。
csv
まずはすべての基本となるcsvファイルから。
世の中のファイルがすべてcsvになれば苦労しないんですが…
コロナウイルスが話題なので,
データは東京都_新型コロナウイルス陽性患者発表詳細にあるcsvファイルを使用します。
csvファイルのインポートにはbase::read.csv
が元から入っていますが,
やはりreadr::read_csv
を使うのがいいでしょう。
# readrはtidyverseに含まれる
library(tidyverse)
read_csv(file = 'https://stopcovid19.metro.tokyo.lg.jp/data/130001_tokyo_covid19_patients.csv',
locale = locale(encoding = 'UTF-8'))
# A tibble: 1,116 x 16
No 全国地方公共団体コード~ 都道府県名 市区町村名 公表_年月日 曜日 発症_年月日 患者_居住地
<dbl> <dbl> <chr> <lgl> <date> <chr> <lgl> <chr>
1 1 130001 東京都 NA 2020-01-24 金 NA 湖北省武漢市~
2 2 130001 東京都 NA 2020-01-25 土 NA 湖北省武漢市~
3 3 130001 東京都 NA 2020-01-30 木 NA 湖南省長沙市~
4 4 130001 東京都 NA 2020-02-13 木 NA 都内
5 5 130001 東京都 NA 2020-02-14 金 NA 都内
6 6 130001 東京都 NA 2020-02-14 金 NA 都内
7 7 130001 東京都 NA 2020-02-15 土 NA 都内
8 8 130001 東京都 NA 2020-02-15 土 NA 都内
9 9 130001 東京都 NA 2020-02-15 土 NA 都内
10 10 130001 東京都 NA 2020-02-15 土 NA 都内
# ... with 1,106 more rows, and 8 more variables: 患者_年代 <chr>, 患者_性別 <chr>,
# 患者_属性 <lgl>, 患者_状態 <lgl>, 患者_症状 <lgl>, 患者_渡航歴の有無フラグ <lgl>,
# 備考 <lgl>, 退院済フラグ <dbl>
これはまあいいでしょう。
それにしてもtidyなデータですね。
Excel
分析用のデータはcsvなどのテキストファイルで保存するのが基本ですが,
世の中にはExcelでデータを提供してるところもあります。Estatとか。
estat-APIという便利なものも整備されてきてはいるので頑張ってもらいたいところです。
(estat-APIについてはこちらの記事がわかりやすい)
ここでは文部科学省学校基本調査の学校数のデータを使います。
Excelファイルのインポートには,
readxl
パッケージのread_xls
,read_xlsx
, read_excel
が利用できます。
(多分どれでもよい?)
なお先ほどのread_csv
と違って,URLから直接取り込むことはできないようなので,
download.file
で一度ダウンロードします。
library(readxl)
download.file(url = 'https://www.e-stat.go.jp/stat-search/file-download?statInfId=000031852301&fileKind=0',
destfile = 'data/number_of_school.xlsx',
mode = 'wb')
read_excel(path = 'data/number_of_school.xlsx')
# A tibble: 79 x 23
...1 ...2 ...3 ...4 ...5 ...6 ...7 ...8 学 校 数 ...12 ...13 ...14
<chr> <chr> <chr> <chr> <chr> <chr> <chr> <dbl> <chr> <chr> <chr> <chr> <chr> <chr>
1 NA NA NA NA NA NA NA NA NA NA NA NA NA NA
2 区分 幼稚園 "幼保連携~ 小学校~ 中学校~ "義務教~ 高等学校~ NA 中等教育~ 盲学校~ 聾学校~ 養護 ~ 特別支援~ 高等専門~
3 昭和23年~ 1529 "…" 25237 16285 "…" NA 3575 … 74 64 - … …
4 24 1787 "…" 25638 14200 "…" NA 4180 … 74 78 1 … …
5 25 2100 "…" 25878 14165 "…" NA 4292 … 76 82 3 … …
6 26 2455 "…" 26056 13836 "…" NA 4477 … 76 84 3 … …
7 27 2874 "…" 26377 13748 "…" NA 4506 … 77 86 3 … …
8 28 3490 "…" 26555 13685 "…" NA 4572 … 78 92 5 … …
9 29 4471 "…" 26804 13773 "…" NA 4606 … 77 96 5 … …
10 30 5426 "…" 26880 13767 "…" NA 4607 … 77 99 5 … …
# ... with 69 more rows, and 9 more variables: ...15 <chr>, ...16 <chr>, ...17 <chr>,
# ...18 <dbl>, ...19 <chr>, ...20 <chr>, ...21 <chr>, ...22 <lgl>, ...23 <lgl>
あっ…
range
を設定して必要な情報に絞ってインポートします。
read_excel(path = 'data/number_of_school.xlsx', range = 'C4:V76')
# A tibble: 72 x 20
幼稚園 `幼保連携型\r\n認定こども~ 小学校 中学校 `義務教育\r\n学校`~ 高等学校 ...7 `中等教育 学校`~
<dbl> <chr> <dbl> <dbl> <chr> <dbl> <dbl> <chr>
1 1529 … 25237 16285 … NA 3575 …
2 1787 … 25638 14200 … NA 4180 …
3 2100 … 25878 14165 … NA 4292 …
4 2455 … 26056 13836 … NA 4477 …
5 2874 … 26377 13748 … NA 4506 …
6 3490 … 26555 13685 … NA 4572 …
7 4471 … 26804 13773 … NA 4606 …
8 5426 … 26880 13767 … NA 4607 …
9 6141 … 26957 13724 … NA 4575 …
10 6620 … 26988 13622 … NA 4577 …
# ... with 62 more rows, and 12 more variables: 盲学校 <chr>, 聾学校 <chr>, `養護
# 学校` <chr>, `特別支援 学校` <chr>, `高等専門 学校` <chr>, 短期大学 <dbl>,
# ...15 <chr>, 大学 <dbl>, ...17 <dbl>, 専修学校 <chr>, `各種 学校` <dbl>,
# 区分 <chr>
うん…だいぶマシ,かな…
いずれにせよ壮絶な前処理が待ってそうです。
SPSS,Stata
どちらも有料の統計ソフトウェアです。個人で持つにはかなり高額。
さて,savファイル(SPSSのデータ)を渡されて,
「これでちょっと分析してよ」と言われたとします。
ふざけるな!という感じですが,Rにはこれらを処理するパッケージがちゃんとあります。
foreign
とhaven
です。私はhaven
の方が好きなのでそちらを今回は紹介します。
haven
パッケージでは,
SPSS→read_sav
またはread_spss
Stata→read_stata
でファイルを読むことができます。
では実際にやってみましょう。
使用データはPenn World Table version 9.1のStataデータです。
library(haven)
read_stata(file = 'http://www.rug.nl/ggdc/docs/pwt91.dta')
# A tibble: 12,376 x 52
countrycode country currency_unit year rgdpe rgdpo pop emp avh hc ccon
<chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 ABW Aruba Aruban Guild~ 1950 NA NA NA NA NA NA NA
2 ABW Aruba Aruban Guild~ 1951 NA NA NA NA NA NA NA
3 ABW Aruba Aruban Guild~ 1952 NA NA NA NA NA NA NA
4 ABW Aruba Aruban Guild~ 1953 NA NA NA NA NA NA NA
5 ABW Aruba Aruban Guild~ 1954 NA NA NA NA NA NA NA
6 ABW Aruba Aruban Guild~ 1955 NA NA NA NA NA NA NA
7 ABW Aruba Aruban Guild~ 1956 NA NA NA NA NA NA NA
8 ABW Aruba Aruban Guild~ 1957 NA NA NA NA NA NA NA
9 ABW Aruba Aruban Guild~ 1958 NA NA NA NA NA NA NA
10 ABW Aruba Aruban Guild~ 1959 NA NA NA NA NA NA NA
# ... with 12,366 more rows, and 41 more variables: cda <dbl>, cgdpe <dbl>, cgdpo <dbl>,
# cn <dbl>, ck <dbl>, ctfp <dbl>, cwtfp <dbl>, rgdpna <dbl>, rconna <dbl>,
# rdana <dbl>, rnna <dbl>, rkna <dbl>, rtfpna <dbl>, rwtfpna <dbl>, labsh <dbl>,
# irr <dbl>, delta <dbl>, xr <dbl>, pl_con <dbl>, pl_da <dbl>, pl_gdpo <dbl>,
# i_cig <dbl+lbl>, i_xm <dbl+lbl>, i_xr <dbl+lbl>, i_outlier <dbl+lbl>,
# i_irr <dbl+lbl>, cor_exp <dbl>, statcap <dbl>, csh_c <dbl>, csh_i <dbl>,
# csh_g <dbl>, csh_x <dbl>, csh_m <dbl>, csh_r <dbl>, pl_c <dbl>, pl_i <dbl>,
# pl_g <dbl>, pl_x <dbl>, pl_m <dbl>, pl_n <dbl>, pl_k <dbl>
無事読めてますね。
これならわざわざSPSSとか買う必要もないかも。
html
これまではデータが単体のファイルとして存在していましたが,
htmlとpdfに関してはデータがどこにあるのかを特定して取得するという作業が必要になります。
いわゆるスクレイピングです。この章ではまずhtmlのスクレイピングを紹介します。
例として日経平均株価(https://kabutan.jp/stock/kabuka?code=0000&ashi=day&page=1)
のデータをスクレイピングします。
Rでのスクレイピングはrvest
パッケージを使うのが良いでしょう。
主な流れとしては,
read_html
でスクレイピングしたいサイトのhtmlを読み込む。
→html_node
で欲しいデータがページ内のどこにあるのか指定する。
→html_attr
,html_text
,html_table
なりで欲しいデータを取り出す。
のようになります。
では実際にやってみましょう。
library(rvest)
# 何度もスクレイピングするのはwebサイトにもPCにも負荷がかかるので一度保存しておく
html <- read_html('https://kabutan.jp/stock/kabuka?code=0000&ashi=day&page=1')
html %>%
html_node(xpath = '//*[@id="stock_kabuka_table"]/table[2]') %>%
html_table()
途中の//*[@id="stock_kabuka_table"]/table[2]はxpathというやつで,
ページ中段の表を指定するパスです。
google chromeならば,
右クリック→検証から開けるデベロッパツールから引っ張ってくるのが楽です。
こちらのページが参考になります。
https://www.octoparse.jp/blog/essential-for-web-scraping-xpath-introduction/
以上のコードを走らせた結果がこちら。
日付 始値 高値 安値 終値 前日比 前日比% 売買高(株)
1 20/04/06 17,857.99 18,672.26 17,802.62 18,576.30 +756.11 4.2 1,679,620,000
2 20/04/03 17,951.44 18,059.15 17,646.50 17,820.19 +1.47 0.0 1,499,110,000
3 20/04/02 17,934.42 18,132.04 17,707.66 17,818.72 -246.69 -1.4 1,644,260,000
4 20/04/01 18,686.12 18,784.25 17,871.62 18,065.41 -851.60 -4.5 1,661,420,000
5 20/03/31 19,181.90 19,336.19 18,834.16 18,917.01 -167.96 -0.9 1,862,450,000
6 20/03/30 18,884.07 19,084.97 18,578.20 19,084.97 -304.46 -1.6 1,924,440,000
7 20/03/27 19,021.97 19,389.43 18,832.21 19,389.43 +724.83 3.9 2,368,330,000
8 20/03/26 19,234.77 19,240.29 18,512.81 18,664.60 -882.03 -4.5 2,049,670,000
9 20/03/25 18,446.80 19,564.38 18,446.80 19,546.63 +1,454.28 8.0 2,280,280,000
10 20/03/24 17,206.88 18,100.39 17,197.14 18,092.35 +1,204.57 7.1 2,256,860,000
11 20/03/23 16,570.57 17,049.03 16,480.95 16,887.78 +334.95 2.0 2,697,390,000
12 20/03/19 16,995.77 17,160.97 16,358.19 16,552.83 -173.72 -1.0 3,017,690,000
13 20/03/18 17,154.08 17,396.84 16,698.46 16,726.55 -284.98 -1.7 2,718,810,000
14 20/03/17 16,726.95 17,557.04 16,378.94 17,011.53 +9.49 0.1 3,065,170,000
15 20/03/16 17,586.08 17,785.76 16,914.45 17,002.04 -429.01 -2.5 2,345,690,000
16 20/03/13 18,183.47 18,184.46 16,690.60 17,431.05 -1,128.58 -6.1 3,459,380,000
17 20/03/12 19,064.51 19,142.18 18,339.27 18,559.63 -856.43 -4.4 2,583,520,000
18 20/03/11 19,758.26 19,974.83 19,392.25 19,416.06 -451.06 -2.3 1,996,320,000
19 20/03/10 19,474.89 19,970.35 18,891.77 19,867.12 +168.36 0.9 2,570,370,000
20 20/03/09 20,343.31 20,347.19 19,472.26 19,698.76 -1,050.99 -5.1 2,518,470,000
21 20/03/06 21,009.80 21,061.20 20,613.91 20,749.75 -579.37 -2.7 1,749,640,000
22 20/03/05 21,399.87 21,399.87 21,220.76 21,329.12 +229.06 1.1 1,383,840,000
23 20/03/04 20,897.20 21,245.93 20,862.05 21,100.06 +17.33 0.1 1,507,670,000
24 20/03/03 21,651.99 21,719.78 21,082.73 21,082.73 -261.35 -1.2 1,764,900,000
25 20/03/02 20,849.79 21,593.11 20,834.29 21,344.08 +201.12 1.0 2,035,150,000
26 20/02/28 21,518.01 21,528.13 20,916.40 21,142.96 -805.27 -3.7 2,420,870,000
27 20/02/27 22,255.83 22,272.26 21,844.29 21,948.23 -477.96 -2.1 1,811,410,000
28 20/02/26 22,374.14 22,456.55 22,127.42 22,426.19 -179.22 -0.8 1,677,170,000
29 20/02/25 22,949.37 22,950.23 22,335.21 22,605.41 -781.33 -3.3 1,778,020,000
取れてますね。
ここにいくつかの前処理を施すと以下のようになります。
# A tibble: 29 x 8
日付 始値 高値 安値 終値 前日比 `前日比%` `売買高(株)`
<date> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 2020-04-06 17858. 18672. 17803. 18576. 756. 4.2 1679620000
2 2020-04-03 17951. 18059. 17646. 17820. 1.47 0 1499110000
3 2020-04-02 17934. 18132. 17708. 17819. -247. -1.4 1644260000
4 2020-04-01 18686. 18784. 17872. 18065. -852. -4.5 1661420000
5 2020-03-31 19182. 19336. 18834. 18917. -168. -0.9 1862450000
6 2020-03-30 18884. 19085. 18578. 19085. -304. -1.6 1924440000
7 2020-03-27 19022. 19389. 18832. 19389. 725. 3.9 2368330000
8 2020-03-26 19235. 19240. 18513. 18665. -882. -4.5 2049670000
9 2020-03-25 18447. 19564. 18447. 19547. 1454. 8 2280280000
10 2020-03-24 17207. 18100. 17197. 18092. 1205. 7.1 2256860000
# ... with 19 more rows
いよいよラストです。あんまりpdfからデータセットを収集するという機会はないと思いますが一応…
(むしろpdfでしかそのデータがないのは,提供者のリテラシーが相当ひどいと考えられますが…)
pdfからデータを取るパッケージは主に3つあります。
tabulizer
, pdftools
, tesseract
です。
このうちtesseract
はocr,
つまり画像pdfを解析してテキストを取り出すことメインに行うパッケージです。
当然エラーが増えますし,
そもそも画像pdfをデータソースにするくらいならば分析しないほうがマシです。
ただフリーのocrソフトとして考えれば,結構優秀な気がします。
次にtabulizer
とpdftools
です。
これらはテキストが埋め込まれたpdfからテキストを取り出すことがメインになります。
(pdftools
はtesseract
と連携していて,ocrもできます)
このうちtabulizer
はJavaと連携させるためにひと手間要るということで,
今回はpdftools
を使ってデータを収集していきます。
(ここら辺のパッケージの話は以下のページを参考にしました。)
https://blog.az.sg/posts/reading-pdfs-in-r/
今回分析するpdfは,2020-03-31における都道府県別のコロナウイルス感染者数のデータです。
URL: https://www.mhlw.go.jp/content/10906000/000617888.pdf
テキストの取得方法はいたって簡単です。これだけでok。
library(pdftools)
text <- pdf_text('https://www.mhlw.go.jp/content/10906000/000617888.pdf')
text
[1] " 新型コロナウイルス感染症(国内事例)の状況(PCR検査陽性者数の累積)(単位:人)\r\n 3月31日(火) 対前日比 うち現在は入院等 うち退院 うち死亡\r\n 東京都 527 78 484 92% 37 7% 6 1% <0件>\r\n 大阪府 245 28 173 71% 70 29% 2 1%\r\n 岩手\r\n 北海道 177 0 46 26% 124 70% 7 4%\r\n 愛知県 176 6 110 63% 47 27% 19 11% 鳥取\r\n 千葉県 164 4 144 88% 19 12% 1 1%\r\n 島根\r\n 兵庫県 147 11 118 80% 18 12% 11 7%\r\n神奈川県 120 5 87 73% 27 23% 6 5%\r\n 埼玉県 98 14 80 82% 15 15% 3 3%\r\n 京都府 68 14 53 78% 15 22% 0 0%\r\n 福岡県 43 20 41 95% 2 5% 0 0%\r\n 新潟県 31 0 21 68% 10 32% 0 0%\r\n 大分県 29 1 28 97% 1 3% 0 0%\r\n 茨城県 24 4 24 100% 0 0% 0 0%\r\n 岐阜県 23 2 21 91% 2 9% 0 0%\r\n 群馬県 19 1 18 95% 0 0% 1 5%\r\n 高知県 17 2 5 29% 12 71% 0 0%\r\n和歌山県 17 0 3 18% 13 76% 1 6%\r\n 福井県 16 1 16 100% 0 0% 0 0%\r\n 熊本県 14 3 11 79% 3 21% 0 0%\r\n 栃木県 14 2 12 86% 2 14% 0 0%\r\n 石川県 13 2 8 62% 5 38% 0 0%\r\n 奈良県 11 0 3 27% 8 73% 0 0%\r\n 三重県 11 0 9 82% 2 18% 0 0%\r\n 愛媛県 9 5 7 78% 2 22% 0 0%\r\n 沖縄県 9 0 7 78% 2 22% 0 0%\r\n 青森県 8 1 8 100% 0 0% 0 0%\r\n 長野県 8 0 5 63% 3 38% 0 0%\r\n 宮城県 7 1 6 86% 1 14% 0 0%\r\n 滋賀県 7 1 5 71% 2 29% 0 0%\r\n 秋田県 6 2 4 67% 2 33% 0 0%\r\n 静岡県 6 2 3 50% 3 50% 0 0%\r\n 山梨県 6 1 4 67% 2 33% 0 0%\r\n 山口県 6 0 3 50% 3 50% 0 0%\r\n 広島県 6 0 5 83% 1 17% 0 0%\r\n 福島県 4 2 4 100% 0 0% 0 0%\r\n 岡山県 4 0 4 100% 0 0% 0 0%\r\n 富山県 3 2 3 100% 0 0% 0 0%\r\n 徳島県 3 2 2 67% 1 33% 0 0%\r\n 宮崎県 3 0 2 67% 1 33% 0 0%\r\n 香川県 2 1 2 100% 0 0% 0 0%\r\n 佐賀県 2 1 2 100% 0 0% 0 0%\r\n 長崎県 2 0 1 50% 1 50% 0 0%\r\n 山形県 1 1 1 100% 0 0% 0 0%\r\n鹿児島県 1 0 1 100% 0 0% 0 0%\r\n 総計 2107 220 1594 76% 456 22% 57 3%\r\n"
あれっ,めっちゃ横に長いですね。
実はテキスト取得自体はこれだけなんですが,
分析できるデータにするには膨大な前処理が必要になります。
ちょっとやってみましょう。
まずは\n
(改行)部分でベクトルを切ります。ついでにデータフレームにしておきます。
text %>%
str_split('\n') %>%
as_tibble(.name_repair = 'unique')
# A tibble: 50 x 1
...1
<chr>
1 " 新型コロナウイルス感染症(国内事例)の状況(PCR検査陽性者数の累積)(単位:人)\r"~
2 " 3月31日(火) 対前日比 うち現在は入院等 うち退院 うち死亡\r"~
3 " 東京都 527 78 484 92% 37 7% 6 1% <0件>\r"
4 " 大阪府 245 28 173 71% 70 29% 2 1%\r"
5 " 岩手\r"
6 " 北海道 177 0 46 26% 124 70% 7 4%\r"
7 " 愛知県 176 6 110 63% 47 27% 19 11% 鳥取\r"
8 " 千葉県 164 4 144 88% 19 12% 1 1%\r"
9 " 島根\r"
10 " 兵庫県 147 11 118 80% 18 12% 11 7%\r"
# ... with 40 more rows
これならなんか行けそうな気がしませんか?
text %>%
str_split('\n') %>%
as_tibble(.name_repair = 'unique') %>%
# 続き
# タイトルが入っている1,2行目を削る
slice(-c(1, 2)) %>%
# 各列の両端の空白を削る
mutate(...1 = str_trim(...1, side = 'both')) %>%
# 文字の間の空白で行を分ける。
separate(col = ...1, into = as.character(c(1:10)), sep = '\\s+') %>%
# 10行目はいらないので削る,また元のpdfを見ながら列名を埋める
select(都道府県 = 1, PCR陽性者数 = 2, 前日比 = 3, うち現在入院等 = 4,
'入院(%)' = 5, うち退院 = 6, '退院(%)' = 7, うち死亡 = 8, '死亡(%)' = 9) %>%
# 都道府県にマッチする者のみ残す(総計や,データの入っていない県を落とす)
filter(grepl(x = 都道府県, pattern = '(東京都|北海道|(?:京都|大阪)府|.{2,3}県)')) %>%
# 型変換
mutate_at(vars(PCR陽性者数:'死亡(%)'), parse_number)
# A tibble: 44 x 9
都道府県 PCR陽性者数 前日比 うち現在入院等 `入院(%)` うち退院 `退院(%)` うち死亡
<chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 東京都 527 78 484 92 37 7 6
2 大阪府 245 28 173 71 70 29 2
3 北海道 177 0 46 26 124 70 7
4 愛知県 176 6 110 63 47 27 19
5 千葉県 164 4 144 88 19 12 1
6 兵庫県 147 11 118 80 18 12 11
7 神奈川県 120 5 87 73 27 23 6
8 埼玉県 98 14 80 82 15 15 3
9 京都府 68 14 53 78 15 22 0
10 福岡県 43 20 41 95 2 5 0
# ... with 34 more rows, and 1 more variable: `死亡(%)` <dbl>
これなら使えます。
ただpdfからデータフレームを起こすのは労力が半端じゃないので,
あまりデータソースとしては良くないですね。
まとめ
ファイル形式ごとのインポートの仕方を見てきました。
後半の大変さを見るとやはりcsvでデータは用意しておいて欲しいのと,
tidyデータ(こちらを参考に)という概念がもっと広がってほしいなと思いました…
Author And Source
この問題について(Rでのデータインポートまとめ(csv, Excel, SPSS, Stata, html, pdf)), 我々は、より多くの情報をここで見つけました https://qiita.com/Sickle-Sword/items/32d8c6e10ef477a64ff1著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .