こんにちは,shun(@datasciencemore)です!
R前処理講座も徐々にゴールが見えてきました!
ここが踏ん張りどころですよ,頑張って乗り越えましょう!
今回は入出力処理のためのパッケージ{readr}について紹介していきます.
目次
0.{readr}ってなに??
データを読み込んだり,加工したデータを出力したりすることができるよ.
データと一口にいっても様々な形式がありますよね.
CSV, XML, JSONなどなど...
今回は,1番代表的なCSVを例にとって説明していきますね.
他のフォーマットでも基本は同じですのでご安心ください.
そこまで難しくはないと思うよ.
ただ,知らないとハマる要素も少なからずあるから,そういうところを重点的にみていくね!
っということで,さっそく紹介していきましょう!
今回は,データセットにeconomics_longを使用します.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
> economics_long # A tibble: 2,870 x 4 date variable value value01 <date> <chr> <dbl> <dbl> 1 1967-07-01 pce 507. 0 2 1967-08-01 pce 510. 0.000265 3 1967-09-01 pce 516. 0.000762 4 1967-10-01 pce 512. 0.000471 5 1967-11-01 pce 517. 0.000916 6 1967-12-01 pce 525. 0.00157 7 1968-01-01 pce 531. 0.00207 8 1968-02-01 pce 534. 0.00230 9 1968-03-01 pce 544. 0.00322 10 1968-04-01 pce 544 0.00319 # … with 2,860 more rows |
1.CSVの出力 write_csv
データフレームにいろいろな処理を加えたらそれをCSVに出力したくなりますよね.
そのようなときに使用するのがwrite_csvです.
データフレーム %>% write_csv("出力するCSVのパス名")で,出力するCSVのパス名を指定してあげます.
今回は,economics_longをファイル名「df_economics_long.csv」としてワーキングディレクトリに格納してあげましょう.
ワーキングディレクトリっていうのは,文字どおり作業しているフォルダってことです.
私たちが普段使用しているPCには通常,様々なフォルダがありますよね.
なのでコンピュータにファイルの場所を教えてあげるにはそのファイルがどこにあるかを教えてあげなくてはいけません.
そのための基準になるフォルダのことをワーキングディレクトリといいます.
1 2 3 |
# economics_longをワーキングディレクトリに出力 economics_long %>% write_csv("df_economics_long.csv") |
ワーキングディレクトリにちゃんと出力されているか,各自,確認してくださいね.
ちなみにワーキングディレクトリは,
1 |
getwd() |
で確認できますよ~
ぼくのR前処理講座で説明したDockerからRStudioを動かしてるのであれば,ワーキングディレクトリはデスクトップの「r-preprocess-lecture」フォルダになるはずです.
厳密にいうと,ワーキングディレクトリは,"/home/rstudio/r-preprocess-lecture"で,デスクトップの「r-preprocess-lecture」フォルダはそれをマウントしているのですが,細かいことは気にしない方針の本講座はこれ以上立ち入りません笑
write_csvで出力されるファイルは,すべてUTF-8でエンコーディングされます.
もし宗教上の理由などでShift-JISでエンコーディングしたい場合は,baseRのwrite.csvを使用しましょう.
1 2 3 |
# df_economics_long_datetimeをShift-JISでエンコーディングして出力 df_economics_long%>% write.csv("df_economics_long_sjis.csv", fileEncoding = "shift-jis", row.names = FALSE) |
2.CSVの入力 read_csv
1.1 基本
CSVの出力が終わったら,今度はCSVの入力をやりましょう.
こいつは使用頻度ベスト1なので,しっかり慣れてくださいね!
read_csv("入力するCSVのパス名")で指定したCSVを読むことができます.
1 2 |
# csvの入力 read_csv("df_economics_long.csv") |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────── cols( date = col_date(format = ""), variable = col_character(), value = col_double(), value01 = col_double() ) # A tibble: 2,870 x 4 date variable value value01 <date> <chr> <dbl> <dbl> 1 1967-07-01 pce 507. 0 2 1967-08-01 pce 510. 0.000265 3 1967-09-01 pce 516. 0.000762 4 1967-10-01 pce 512. 0.000471 5 1967-11-01 pce 517. 0.000916 6 1967-12-01 pce 525. 0.00157 7 1968-01-01 pce 531. 0.00207 8 1968-02-01 pce 534. 0.00230 9 1968-03-01 pce 544. 0.00322 10 1968-04-01 pce 544 0.00319 # … with 2,860 more rows |
出力部分の上部のColumn specificationというところに注目してください.
cols( date = col_date(format = ""), variable = col_character(), value = col_double(), value01 = col_double() ) と出力されていますね.
read_csvを使用すると,データの最初の1000行を読み込むことにより,各列のデータ型を推測し,一番可能性が高いデータ型に自動で変換してくれます.
なんてできる子...
もちろん,自動で変換してくれたデータ型が気に入らないときは,後述の引数col_typesを設定することで好きなデータ型に変更することができます.
1.2 列の型の指定
例えば,自動だとdate列をdategata型に変換してくれますが,chr型にしたいときは次のようにします.
1 2 3 |
# csvの入力 引数col_typesでdate列をchr型に変換 両者,同じ出力になる. read_csv("df_economics_long.csv", col_types = cols(date = col_character())) read_csv("df_economics_long.csv", col_types = cols(date = "c")) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# A tibble: 2,870 x 4 date variable value value01 <chr> <chr> <dbl> <dbl> 1 1967-07-01 pce 507. 0 2 1967-08-01 pce 510. 0.000265 3 1967-09-01 pce 516. 0.000762 4 1967-10-01 pce 512. 0.000471 5 1967-11-01 pce 517. 0.000916 6 1967-12-01 pce 525. 0.00157 7 1968-01-01 pce 531. 0.00207 8 1968-02-01 pce 534. 0.00230 9 1968-03-01 pce 544. 0.00322 10 1968-04-01 pce 544 0.00319 # … with 2,860 more rows |
date列のデータ型がchr型になりましたね.
このように,もし自動変換が気に入らなかった場合は引数col_typesになってほしいデータ型を指定してあげましょう.
1.3 全部の列をchr型で読み込む→変換
さて,読み込むデータが汚い場合,有能なread_csvでもうまく読み込めず,エラーになってしまうことがよくあります.
そんな場合に一番うまくいく可能性が高いのが以下の処理です.
- すべての列をchr型で読み込み
- type_convertで変換
このコンボ技,地味にかなり使えます.
1 2 3 |
# csvの入力 引数col_typesで全列をchr型に変換⇒type_convertで変換 read_csv("df_economics_long.csv", col_types = cols(.default = "c")) %>% type_convert() |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────── cols( date = col_date(format = ""), variable = col_character(), value = col_double(), value01 = col_double() ) # A tibble: 2,870 x 4 date variable value value01 <date> <chr> <dbl> <dbl> 1 1967-07-01 pce 507. 0 2 1967-08-01 pce 510. 0.000265 3 1967-09-01 pce 516. 0.000762 4 1967-10-01 pce 512. 0.000471 5 1967-11-01 pce 517. 0.000916 6 1967-12-01 pce 525. 0.00157 7 1968-01-01 pce 531. 0.00207 8 1968-02-01 pce 534. 0.00230 9 1968-03-01 pce 544. 0.00322 10 1968-04-01 pce 544 0.00319 # … with 2,860 more rows |
いい感じに出力されました!
1.4 エンコーディング
上のやり方もうまく読み込めないときはエンコーディング問題が起こっているかもしれません.
基本,tidyverseはUTF-8でのエンコーディングを前提にしているんだけど,Windowsの日本語は標準だとShift-JISでエンコーディングしているから,Windowsだと文字化けしやすいんだ...
この問題,ほんとになんとかしてほしいですよね...
回避方法としては,read_csvの引数localeでエンコード方式を設定できるので,Shift-Jisのファイルを読み込むときは,次のように設定してあげましょう.
※ちなみに何も指定しなかったときは,UTF-8でエンコーディングします.
1 2 |
# csvの入力 引数localeでエンコーディングをShift-JISにする. read_csv("df_economics_long.csv", locale = locale(encoding = "shift-jis")) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────── cols( date = col_date(format = ""), variable = col_character(), value = col_double(), value01 = col_double() ) # A tibble: 2,870 x 4 date variable value value01 <date> <chr> <dbl> <dbl> 1 1967-07-01 pce 507. 0 2 1967-08-01 pce 510. 0.000265 3 1967-09-01 pce 516. 0.000762 4 1967-10-01 pce 512. 0.000471 5 1967-11-01 pce 517. 0.000916 6 1967-12-01 pce 525. 0.00157 7 1968-01-01 pce 531. 0.00207 8 1968-02-01 pce 534. 0.00230 9 1968-03-01 pce 544. 0.00322 10 1968-04-01 pce 544 0.00319 # … with 2,860 more rows |
今回は日本語が含まれていないので,エンコーディング方式をShift-jisにしてもしなくても結果は一緒です.
もし日本語が含まれていて,エラーが起きたり,文字化けしたりしてみたら,エンコーディングをShift-JISにすればうまくいくかもしれないので,試してみてください.
3.オブジェクトの出力 write_rds
CSVは,数値とか文字列しか出力できません.
しかし,tibbleはそれ以外にも様々な形式(画像やモデルやデータフレームなど)を格納できるのでしたね.
そのようなtibbleを出力することはできないのでしょうか?
実は,write_rdsを使用すれば,そのようなtibbleでもオブジェクトにすることでRDSと呼ばれるファイル形式で出力できます.
また,tibble以外でもオブジェクトであればなんでも出力できます.
言葉でいうと難しいけど要は,=の左辺だと思えばOK!
オブジェクトはなんでもOKです.
スカラーでもベクトルでもデータフレームでもモデルでも画像でも...
オブジェクトにできるものならなんでも入出力できます.
これは,処理時間が長い処理をあらかじめオブジェクト化しておいて,それを出力して,後で入力するパターンが多いですね.
言葉だとイメージしづらいですね笑
さっそく実例をみてみましょう.
今回は,df_economics_longをvariableでネストしたものをdf_economics_long_nestというオブジェクトにして,それを出力してみましょう.
1 2 3 4 |
# df_economics_longをvariableでネスト df_economics_long_nest = df_economics_long %>% nest_by(variable) |
1 2 3 4 5 6 7 8 9 10 |
> df_economics_long_nest # A tibble: 5 x 2 # Rowwise: variable variable data <chr> <list<tbl_df[,3]>> 1 pce [574 × 3] 2 pop [574 × 3] 3 psavert [574 × 3] 4 uempmed [574 × 3] 5 unemploy [574 × 3] |
このようなlistが混じったデータフレームは普通のCSVでは出力できません.
これを出力するには,write_csvを使って,RDSで出力してあげればいいのです.
1 2 3 |
# RDSの出力 df_economics_long_nest %>% write_rds("df_economics_long_nest.rds") |
write_csvと使い方はほとんど一緒ですので,簡単ですよね笑
4.オブジェクトの入力 read_rds
RDSを読み込むのもCSVを読み込むのとほとんど同じです.
さきほど作成したdf_economics_long_nest.rdsを読み込んでみましょう.
1 2 |
# RDSの入力 read_rds("df_economics_long_nest.rds") |
1 2 3 4 5 6 7 8 9 |
# A tibble: 5 x 2 # Rowwise: variable variable data <chr> <list<tbl_df[,3]>> 1 pce [574 × 3] 2 pop [574 × 3] 3 psavert [574 × 3] 4 uempmed [574 × 3] 5 unemploy [574 × 3] |
はい,先ほどのRDSファイルが無事に読み込めましたね.
こちらもcsvがrdsに変わっただけなので簡単ですね!
まとめ
今回はファイルの入出力について以下の4つを学びました.
- CSVの入力 read_csv
- CSVの出力 write_csv
- オブジェクトの出力 read_rds
- オブジェクトの入力 write_rds
CSVだけでなく,RDSも使いこなせると,ファイルの入出力処理が非常に楽になりますよ!
それじゃ,お疲れ様でした!!