Rでデータファイルを読み込むとき、{base}
パッケージにはread.XXXという関数が備わっています。
私もcsvファイルを読み込むときは、ずっとread.csvを使用していましたが、{readr}
を使うともっと高速に、そして処理のしやすい形でデータを読みこむことができます!
これを使いこなせば、データの読み込みでストレスを感じることはなくなるでしょう!
{readr}
は何が違うのか?
{readr}
には、Rの基本関数と比較して、以下のようなメリットがあります。
- 読み込みが高速
- 上手く読み込めなかった場合はレポートしてくれる
- 勝手に文字列をfactore型に変換しない
- 良い込まれたデータはtibble型になる
- 読み込む列や行、欠損値の指定が分かりやすい
などなど、{base}
では力不足を感じていたことができるようになります。
練習データファイルの作成
今回は、練習のために色々な型を含んだデータセットを作成しましょう。下記を実行すると、作業フォルダにpractice.csvというファイルが作成されます。(練習が終わったら削除するのをお忘れなく)
今回はcsvの読み込みを主に説明しますが、他の種類でも同じように使えるのでご心配なく!
library(readr) library(dplyr) set.seed(123) ID <- seq(1,10) day <- ymd("2019/2/1")+days(sample(seq(1,10),replace = T,10)) dweek <- wday(day,label = T) age <- sample(seq(20,60),replace = T,10) age[2] <- "30才" sex <- sample(c("Men","Women"),replace = T,10) sex[5] <- "NA" sales <-sample(c(seq(500,10000)),replace = T,10) sales[5] <-"NULL" #データセットの作成と書き出し data_frame(ID=ID,Day=day,weeks=dweek,Age=age,Sex=sex,Sales = sales) %>% write_csv("practice.csv")
このデータセットは、あるお店の売り上げのデータで、購買者の年齢や性別、購入日、購入単価など10人分が変数として記録されています。 欠損値もちらほらみられます。
ID | Day | weeks | Age | Sex | Sales |
---|---|---|---|---|---|
1 | 2019-02-04 | 月 | 59 | Women | 9649 |
2 | 2019-02-09 | 土 | 30才 | Women | 9072 |
3 | 2019-02-06 | 水 | 47 | Women | 7062 |
4 | 2019-02-10 | 日 | 43 | Women | 8057 |
5 | 2019-02-11 | 月 | 24 | NA | NULL |
6 | 2019-02-02 | 土 | 56 | Women | 5039 |
7 | 2019-02-07 | 木 | 30 | Women | 7706 |
8 | 2019-02-10 | 日 | 21 | Women | 2556 |
9 | 2019-02-07 | 木 | 33 | Men | 3523 |
10 | 2019-02-06 | 水 | 59 | Men | 2700 |
データセットの読み込み
まずは普通に読み込んでみましょう。
> df <- read_csv("practice.csv") Parsed with column specification: cols( ID = col_integer(), Day = col_date(format = ""), weeks = col_character(), Age = col_character(), Sex = col_character(), Sales = col_character() ) # A tibble: 10 x 6 ID Day weeks Age Sex Sales <int> <date> <chr> <chr> <chr> <chr> 1 1 2019-02-04 月 59 Women 9649 2 2 2019-02-09 土 30才 Women 9072 3 3 2019-02-06 水 47 Women 7062 4 4 2019-02-10 日 43 Women 8057 5 5 2019-02-11 月 24 NA NULL 6 6 2019-02-02 土 56 Women 5039 7 7 2019-02-07 木 30 Women 7706 8 8 2019-02-10 日 21 Women 2556 9 9 2019-02-07 木 33 Men 3523 10 10 2019-02-06 水 59 Men 2700 >
実際にやってみると分かりますが、文字がたくさん出てきて最初は驚きます。
しかし、この読み込んだ後の文字には重要な情報が含まれているのです。
Parsed with column specification: cols( ID = col_integer(), Day = col_date(format = ""), weeks = col_character(), Age = col_character(), Sex = col_character(), Sales = col_character() )
この部分ですね。これは各列をどんな型で読み込んだのかが記されています。 {readr}は最初の100行のデータから勝手に型を推測して、変換してくれます。なんと素晴らしい心遣い。
今回は、Dayはcol_date
、つまり日付情報、IDはcol_interger
で整数、その他はcol_character
、文字で読み込まれています。
ここで、Age、Salesは数値情報として読み込みたいのに文字になっていましました。
データをよくみてみると、"才"と"NULL"が文字として入っているため文字列として推定されてしまったようです。
欠損値の扱い
こんな時にna=
を指定することで、欠損値として扱う文字を指定して読み込むことができます。ちなみにデフォルトはna=NA
となっているので、SexのNAは欠損値として処理されています。
#欠損値の数 >sum(is.na(df$Sex)) [1] 1 > sum(is.na(df$Sales)) [1] 0
それでは、欠損として扱う文字列をNAとNULLの二つを指定して読み込んでみましょう。
df <- read_csv("practice.csv",na = c("NA","NULL")) Parsed with column specification: cols( ID = col_integer(), Day = col_date(format = ""), weeks = col_character(), Age = col_character(), Sex = col_character(), Sales = col_integer() ) # A tibble: 10 x 6 ID Day weeks Age Sex Sales <int> <date> <chr> <chr> <chr> <int> 1 1 2019-02-04 月 59 Women 9649 2 2 2019-02-09 土 30才 Women 9072 3 3 2019-02-06 水 47 Women 7062 4 4 2019-02-10 日 43 Women 8057 5 5 2019-02-11 月 24 NA NA 6 6 2019-02-02 土 56 Women 5039 7 7 2019-02-07 木 30 Women 7706 8 8 2019-02-10 日 21 Women 2556 9 9 2019-02-07 木 33 Men 3523 10 10 2019-02-06 水 59 Men 2700
Salesを見てみるとNULLが欠損として扱われたため、しっかりと整数として読み込まれています。
型を指定して読み込む
さて、今度は自分で型を指定してデータを読み込んでみましょう。指定できる型は、
- [c] col_character(): 文字列
- [i] col_integer(): 整数
- [d] col_double(): 実数
- [D] col_date(format=''): 日付
- [t] col_time(format=''): 時間
- [T] col_datetime(format=''): 日付
- [n] col_number(): 文字が含まれていても数字を返す
- [?] col_guess(): 推測
- [_] col_skip(): 列を読まない
などがあります。IDは文字で、Ageは才が含まれているのでnumberで指定してみます。col_type=cols(列名=型)
と指定します。
> read_csv("practice.csv",na = c("NA","NULL"),col_types = cols(Age = col_number(),ID=col_character())) # A tibble: 10 x 6 ID Day weeks Age Sex Sales <chr> <date> <chr> <dbl> <chr> <int> 1 1 2019-02-04 月 59 Women 9649 2 2 2019-02-09 土 30 Women 9072 3 3 2019-02-06 水 47 Women 7062 4 4 2019-02-10 日 43 Women 8057 5 5 2019-02-11 月 24 NA NA 6 6 2019-02-02 土 56 Women 5039 7 7 2019-02-07 木 30 Women 7706 8 8 2019-02-10 日 21 Women 2556 9 9 2019-02-07 木 33 Men 3523 10 10 2019-02-06 水 59 Men 2700
上手く読み込めました。型を指定するとParsed with column specification:~
は出てこないようですね。
さらにcols(.defalt = 型)
を指定すると、指定した列以外の列はその型で読み込まれます。普段は.default = col_guess()
となっているので、勝手に推測されていたたんですね。
また、さっきの型リストを見て頂くとかっこの中に文字があるのがわかると思います。
実はこの一文字で指定することもできるんです。こっちのが楽ですねー
#col_number()を一文字”n”で指定する #.defaultに文字を指定すると、Age以外は文字として読み込まれる read_csv("practice.csv",na = c("NA","NULL"),col_types = cols(Age = "n",.default = "c")) # A tibble: 10 x 6 ID Day weeks Age Sex Sales <chr> <chr> <chr> <dbl> <chr> <chr> 1 1 2019-02-04 月 59 Women 9649 2 2 2019-02-09 土 30 Women 9072 3 3 2019-02-06 水 47 Women 7062 4 4 2019-02-10 日 43 Women 8057 5 5 2019-02-11 月 24 NA NA 6 6 2019-02-02 土 56 Women 5039 7 7 2019-02-07 木 30 Women 7706 8 8 2019-02-10 日 21 Women 2556 9 9 2019-02-07 木 33 Men 3523 10 10 2019-02-06 水 59 Men 2700
ccdddn
などと文字を並べるだけで、列名を指定しなくても型を指定できたりもします。
#列を右から文字、日付、スキップ、整数、文字、整数として読み込む >read_csv("practice.csv",na = c("NA","NULL"),col_types = "cD_ici") 警告: 1 parsing failure. row # A tibble: 1 x 5 col row col expected actual file expected <int> <chr> <chr> <chr> <chr> actual 1 2 Age no trailing characters 才 'practice.csv' file # A tibble: 1 x 5 # A tibble: 10 x 5 ID Day Age Sex Sales <chr> <date> <int> <chr> <int> 1 1 2019-02-04 59 Women 9649 2 2 2019-02-09 NA Women 9072 3 3 2019-02-06 47 Women 7062 4 4 2019-02-10 43 Women 8057 5 5 2019-02-11 24 NA NA 6 6 2019-02-02 56 Women 5039 7 7 2019-02-07 30 Women 7706 8 8 2019-02-10 21 Women 2556 9 9 2019-02-07 33 Men 3523 10 10 2019-02-06 59 Men 2700 警告メッセージ: 1: read_tokens_(data, tokenizer, col_specs, col_names, locale_, で: length of NULL cannot be changed 2: read_tokens_(data, tokenizer, col_specs, col_names, locale_, で: length of NULL cannot be changed 3: rbind(names(probs), probs_f) で: number of columns of result is not a multiple of vector length (arg 2)
ここで上のほうに警告: 1 parsing failure.
が出ました。これは整数で指定したAgeに”才”が入っているため整数に変換でず、欠損値になりましたという意味です。
problems
を実行すると、2行目のAgeが変換できなかったことをご丁寧にレポートしてくれます。
problems(read_csv("practice.csv",na = c("NA","NULL"),col_types = "cD_ici")) # A tibble: 1 x 5 row col expected actual file <int> <chr> <chr> <chr> <chr> 1 2 Age no trailing characters 才 'practice.csv'
優しすぎます!
行や列を飛ばして読み込む
今度は行や列をスキップして読み込んでみましょう。列のスキップは先ほど実行しましたので、指定した列のみを読み込むことにします。
行のスキップ
行のスキップは、skip=行
で行います。
#1行目をスキップ > read_csv("practice.csv",na = c("NA","NULL"),skip=1,col_names = F) # A tibble: 10 x 6 X1 X2 X3 X4 X5 X6 <int> <date> <chr> <chr> <chr> <int> 1 1 2019-02-04 月 59 Women 9649 2 2 2019-02-09 土 30才 Women 9072 3 3 2019-02-06 水 47 Women 7062 4 4 2019-02-10 日 43 Women 8057 5 5 2019-02-11 月 24 NA NA 6 6 2019-02-02 土 56 Women 5039 7 7 2019-02-07 木 30 Women 7706 8 8 2019-02-10 日 21 Women 2556 9 9 2019-02-07 木 33 Men 3523 10 10 2019-02-06 水 59 Men 2700
1行目をスキップすると1行目の値を列名として認識してしまうので、col_names=FALSE
を指定しました。ちなみにここに列目を任意でつけることもできます。
さらに、n_max
を指定すると任意の行数までを読み込んでくれます。
>read_csv("practice.csv",na = c("NA","NULL"),skip=1,col_names = F,n_max=5) # A tibble: 5 x 6 X1 X2 X3 X4 X5 X6 <int> <date> <chr> <chr> <chr> <int> 1 1 2019-02-04 月 59 Women 9649 2 2 2019-02-09 土 30才 Women 9072 3 3 2019-02-06 水 47 Women 7062 4 4 2019-02-10 日 43 Women 8057 5 5 2019-02-11 月 24 NA NA
指定した列のみを読み込む
列のスキップではなく、指定した列のみを読み込む時にはcol_types=cols()
の代わりにcol_types=cols_only()
を指定します。cols_only
でも同様に型の指定ができます。
read_csv("practice.csv",na = c("NA","NULL"),col_types = cols_only(ID="c",Day="D",Sales="i")) # A tibble: 10 x 3 ID Day Sales <chr> <date> <int> 1 1 2019-02-04 9649 2 2 2019-02-09 9072 3 3 2019-02-06 7062 4 4 2019-02-10 8057 5 5 2019-02-11 NA 6 6 2019-02-02 5039 7 7 2019-02-07 7706 8 8 2019-02-10 2556 9 9 2019-02-07 3523 10 10 2019-02-06 2700
上手く読み込めたみたいです!
まとめ
今回は高速かつ優しい心遣いまでしてくれる{readr}
を紹介しました。
他にもいくつかできることがあるので是非使ってみてください!
参考
readr: 高速で柔軟なテーブル読み込み - Heavy Watal
11 Data import | R for Data Science
上記サイトの和書版です。dplyrやpurrr、tidyrなどモダンなパッケージをまとめたtidyverseを中心に、データの解析手法そのものよりも、いかに効率よくデータを解析するかが書かれています。Rに慣れ始めた頃に読むのがおすすめです!
- 作者: Hadley Wickham,Garrett Grolemund,大橋真也,黒川利明
- 出版社/メーカー: オライリージャパン
- 発売日: 2017/10/25
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (2件) を見る