前回のおさらい
dplyrとは?
- Rで大規模データをさくさく処理するためのパッケージ
- 内部結合とかSQLみたいな処理もできる
- Rでデータ処理する人は必ず使ってる(くらいメジャーで有用)
導入は簡単!
インストールして
> install.packages("dplyr")
パッケージを読み込むだけ
> library(dplyr)
今回は使い方を説明
前回はRのサンプルデータを使ったせいで妙なエラーに悩まされました。なので、オリジナルのサンプルデータを作成していろいろ使い方を紹介していきます。
実はRで遭遇するエラーの多くがデータの構造や型に起因するものです。データがしっかりしていれば、大抵うまくいきます。そのため、データのところは丁寧めに説明しています。
「ちゃんとした」サンプルデータをつくろう
と、言うわけでサンプルデータの作成からはじめていきます。
そのサンプルデータですが、データフレームの構造にする必要があります。なぜなら、dplyrはデータフレームでないと使えないためです。
ちなみに、dplyrは普通のデータフレーム(data.frame)でも利用できますが、dplyr用に最適化されたデーターフレーム(tbl_df)もあります。
違いは、普通のdata.frameでデータ名を実行するとコンソールに全データが表示されますが、tbl_dfだと勝手に要約して表示されます。
(え、それだけ!?)
たぶん他にも違いはあると思うので気になる方はぐぐってください!
では、データをつくります。
> #サンプルデータ作成
>
> #まずはベクトルデータをつくる(先頭のv.はベクトルだと分かりやすいように付けているだけです)
> v.date <- c("2017-08-01","2017-08-02","2017-08-03","2017-08-04","2017-08-05")
> v.sales <- c(100,200,300,40,500)
>
> #データフレームを作成
> df.data <- tbl_df(date = v.date, sales = v.sales)
Error in tbl_df(date = v.date, sales = v.sales) :
unused arguments (date = v.date, sales = v.sales)
あ、やっぱりエラー出た。tbl_dfではデータをつくれないか。まずは、data.frame()でデータをつくる必要があるようですね。
気を取り直して、
> #データフレームを作成
> df.data <- data.frame(date = v.date, sales = v.sales)
> class(df.data) #データ構造の確認
[1] "data.frame"
無事にエラーなくデータフレームできました。classという関数でデータ構造を確認すると、ちゃんとdata.frameになってますね。
では、データを表示してみましょう。
> #データ表示
> df.data
date sales
1 2017-08-01 100
2 2017-08-02 200
3 2017-08-03 300
4 2017-08-04 40
5 2017-08-05 500
今回はデータ少ないので特に問題ないですが、もし、100万行くらいのデータの場合はコンソールがデータでいっぱいになります。
では、data.frameをtbl_dfに変換します。
> #tbl_dfに変換
> df.data <- tbl_df(df.data)
> class(df.data) #データ構造の確認
[1] "tbl_df" "tbl" "data.frame"
tbl_dfが表示されています。うまく変換できているようです。
では、データを表示してみましょう。
> #データ表示
> df.data
# A tibble: 5 x 2
date sales
<fctr> <dbl>
1 2017-08-01 100
2 2017-08-02 200
3 2017-08-03 300
4 2017-08-04 40
5 2017-08-05 500
data.frameの時と少し違いますね。
# A tibble: 5 x 2
は、データが5行で2列のデータであることを示します。
カラム名の下にある<fctr>と<dbl>ですが、それぞれデータの性質を意味しており、簡単に言うと、
<fctr>は文字!
<dbl>は数値!
です(正確にはちょっと違いますが)。
第三者> あれれー? dateって日付なのに文字になってるー!
はい。
このままだと、dateを日付として扱うことができません。
そこで、日付に変換します。
> #dateを日付データに変換
> df.data$date <- as.Date(df.data$date)
>
> #データ表示
> df.data
# A tibble: 5 x 2
date sales
<date> <dbl>
1 2017-08-01 100
2 2017-08-02 200
3 2017-08-03 300
4 2017-08-04 40
5 2017-08-05 500
dateの下が<date>となり日付として認識されました。(日付と認識されることで、日付の計算や不等号を用いての条件検索ができるようになります。)
やっぱり、tbl_df便利ですね!
データ名で実行しただけで、データ型も表示してくれます。
これでサンプルデータ作成は終わりです。
dplyrを使ってみよう
一気にいきましょう。簡単です!
- 行指定の条件抽出:filter
- 列指定の条件抽出:select
- 並び変える:arrange
- 新しい列の作成:mutate
- 複数の処理をつなげる:%>%
- まとめて:group_by、計算する:summarise
- 結合処理もできる:inner_joinなど
1.行指定の条件抽出:filter
2017年8月3日以降のデータを抽出するには、
> #filter
> filter(df.data, date > "2017-08-03")
# A tibble: 2 x 2
date sales
<date> <dbl>
1 2017-08-04 40
2 2017-08-05 500
これでOK!
もし、dateをdate型に変換せずに<fctr>のままだと、
> #filter
> filter(df.data, date > "2017-08-03")
# A tibble: 0 x 2
# ... with 2 variables: date <fctr>, sales <dbl>
Warning message:
In Ops.factor(date, "2017-08-03") : ‘>’ not meaningful for factors
このようにエラーとなります。
2.列指定の条件抽出:select
salesの列だけ抽出するのは、
> #select
> select(df.data, sales)
# A tibble: 5 x 1
sales
<dbl>
1 100
2 200
3 300
4 40
5 500
これでOK!ベリーイージー!
3.並び変える:arrange
salesの昇順で並べるには、
> arrange(df.data, sales)
# A tibble: 5 x 2
date sales
<date> <dbl>
1 2017-08-04 40
2 2017-08-01 100
3 2017-08-02 200
4 2017-08-03 300
5 2017-08-05 500
はい、OK!
ちなみに降順は、
> #arrange
> arrange(df.data, desc(sales))
# A tibble: 5 x 2
date sales
<date> <dbl>
1 2017-08-05 500
2 2017-08-03 300
3 2017-08-02 200
4 2017-08-01 100
5 2017-08-04 40
desc(カラム名)でOK!
そう言えば昔、記事書いていました。
R 順番を変える(arrange)
4.新しい列の作成:mutate
日付の年だけ取り出した新しい列をつくるには、
> #mutate
> mutate(df.data, year = substring(date,1,4))
# A tibble: 5 x 3
date sales year
<date> <dbl> <chr>
1 2017-08-01 100 2017
2 2017-08-02 200 2017
3 2017-08-03 300 2017
4 2017-08-04 40 2017
5 2017-08-05 500 2017
これでOK!!
今回はsubstringという関数も使っています。
substringの使い方は、
substring(カラム名、切り出す最初の文字の順番、切り出す最後の文字の順番)
です。
こちらも昔、記事書いていたのでご参考まで
【R】 日付データから年や月だけを抜き出す方法
5.複数の処理をつなげる:%>%
複数の処理をつなげて一緒にするには、
> df.data %>%
+ filter(date > "2017-08-03") %>%
+ select(sales) %>%
+ arrange(desc(sales))
# A tibble: 2 x 1
sales
<dbl>
1 500
2 40
これでOK!
6.まとめて:group_by、計算する:summarise
年でまとめてsalesの合計を計算するには、
> #group_by summarise
> df.data %>%
+ mutate(year = substring(date,1,4)) %>%
+ group_by(year) %>%
+ summarise(total = sum(sales))
# A tibble: 1 x 2
year total
<chr> <dbl>
1 2017 1140
これでオッケーです!
7.結合処理もできる:inner_joinなど
実は、SQLでお馴染みの内部結合とかもできます!
結合処理にはもう一つデータが必要なのでパパっと作成しましょう。
> #まずはベクトルを作成
> v.date <- c("2017-08-01","2017-08-02","2017-08-03","2017-08-04","2017-08-05")
> v.user <- c(1000,20,300,4,50)
>
> #データフレームを作成
> df.data_2 <- data.frame(date = v.date, user = v.user)
> class(df.data_2) #データ構造の確認
[1] "data.frame"
> #tbl_dfに変換
> df.data_2 <- tbl_df(df.data_2)
> class(df.data_2) #データ構造の確認
[1] "tbl_df" "tbl" "data.frame"
はい。2つ目のデータ完成しました。
では、最初のデータを新たに作ったデータを確認しましょう。
> #data
> df.data
# A tibble: 5 x 2
date sales
<date> <dbl>
1 2017-08-01 100
2 2017-08-02 200
3 2017-08-03 300
4 2017-08-04 40
5 2017-08-05 500
> df.data_2
# A tibble: 5 x 2
date user
<fctr> <dbl>
1 2017-08-01 1000
2 2017-08-02 20
3 2017-08-03 300
4 2017-08-04 4
5 2017-08-05 50
おっと、df.data_2のdateが<fctr>になってる。
df.data_2のdateを日付に変換するのを忘れてましたね。
変換しましょう。
> #日付に変換
> df.data_2$date <- as.Date(df.data_2$date)
>
> #data
> df.data
# A tibble: 5 x 2
date sales
<date> <dbl>
1 2017-08-01 100
2 2017-08-02 200
3 2017-08-03 300
4 2017-08-04 40
5 2017-08-05 500
> df.data_2
# A tibble: 5 x 2
date user
<date> <dbl>
1 2017-08-01 1000
2 2017-08-02 20
3 2017-08-03 300
4 2017-08-04 4
5 2017-08-05 50
これで準備OK。
やっぱり、tbl_dfだとすぐにデータ型を確認できるのでいいですね。
さて、2つのデータが揃ったので内部結合してみましょう。両データに共通するカラムはdateなので、dateをキーにして2つのデータを結合すると、
> #inner_join
> inner_join(df.data, df.data_2, by = "date")
# A tibble: 5 x 3
date sales user
<date> <dbl> <dbl>
1 2017-08-01 100 1000
2 2017-08-02 200 20
3 2017-08-03 300 300
4 2017-08-04 40 4
5 2017-08-05 500 50
こうなります。
他にも外部結合とかアンチ結合とかもできるので下記の記事をご参照ください。
---他の結合---
R 内部結合(inner join)
R 内部結合(複数key)
R 外部結合(left join, right join)
R 完全外部結合(full join)
R アンチ結合(anti join)
以上でdplyrの使い方は終わりです。
本当はまだまだ奥が深く1%も説明できてないですが、以上のことだけでも実用には十分だと思います。
次回は、tidyrという大規模データのクロス集計等を高速におこなうパッケージについて説明できればと思っています。
それでは、
 |
| 一度は富士山に登ってみたい |