Rのdplyrが便利ですねって話。

Tokyo.Rに行くたびにdplyrの話が話題に上がっていて、数か月前は完全に「なんすか、それ?意味あるんすか?」みたいな感じだったんですが、最近データの前処理で使いまくりです。

もうね、便利すぎてヤヴァイ。

という事で使い方をまとめておこうかと。

Fråm

library自体はCRANからtidyverseをインストールするか、そのままdplyrをインストールすれば大丈夫です。

どちらの場合も library(dplyr)で呼び出せます。

 

twoyp, area, ku, matiの4つの変数のある賃貸物件のサンプルデータがあるとしましょう。

それぞれ家賃二年分・面積・23区・市町というデータです。

この発表で使われたものですね。

頭の10行を取り出してみます。

> head(sample,10)
twoyp area ku mati
2 480000 11.00 世田谷 代沢
3 528000 14.76 世田谷 代田
4 576000 8.01 世田谷 桜丘
5 625000 9.90 世田谷 用賀
6 625000 9.90 世田谷 用賀
7 600000 13.00 世田谷 北沢
8 676000 13.00 世田谷 駒沢
9 676000 13.00 世田谷 駒沢
10 650000 11.00 世田谷 駒沢
11 650000 11.00 世田谷 駒沢

 

filter機能でデータを絞ってみます。

> first <- sample %>% filter(twoyp < 1500000, area > 30)

まずsampleで、sampleデータを読み込んでいます。パイプオペレーターを使って読み込まれたデータを次の関数(filter)に渡します。
filter関数では「twoyp > 1500000」「area > 30」の二つの条件を指定し、パイプオペレーターによって渡されたデータの中から条件を満たすデータのみを残す様にします。

データを出力するとこんな感じです。

> head(first,10)
twoyp area ku mati
1 1100000 32.00 世田谷 八幡山
2 1224000 31.14 世田谷 八幡山
3 1224000 31.14 世田谷 八幡山
4 1224000 31.14 世田谷 八幡山
5 1224000 31.14 世田谷 八幡山
6 1224000 31.14 世田谷 八幡山
7 1296000 31.00 世田谷 代田
8 1296000 31.00 世田谷 代田
9 1296000 31.00 世田谷 代田
10 1296000 31.00 世田谷 代田

 

次はmutateで変数を一つ足してみます。

> second <- sample %>% mutate(ten = ceiling(area/10))

sampleでデータを読み込んで、そのデータにmutateで変数を足します。
足す変数の名前はtenで、部屋の面積を10で割って切り上げた値になっています。ceiling(area/10)

データを見てみるとちゃんと最後の列に面積を10で割って切り上げた値が入っています。

> head(second,10)
twoyp area ku mati ten
1 480000 11.00 世田谷 代沢 2
2 528000 14.76 世田谷 代田 2
3 576000 8.01 世田谷 桜丘 1
4 625000 9.90 世田谷 用賀 1
5 625000 9.90 世田谷 用賀 1
6 600000 13.00 世田谷 北沢 2
7 676000 13.00 世田谷 駒沢 2
8 676000 13.00 世田谷 駒沢 2
9 650000 11.00 世田谷 駒沢 2
10 650000 11.00 世田谷 駒沢 2

 

次はgroup_byとsummarizeを使ってデータをグループ化して、グループの中で集計をします。

> third <- sample %>% mutate(ten = ceiling(area/10)) %>% group_by(ten) %.% summarize(count = n())

sampleでデータを読み込んで、mutateでtenを足します。ここまではさっきと同じですね。
パイプオペレーターでその結果をgroup_byに渡します。
group_byではtenを指定しているので、ここでデータがtenの値によってグループ化されます。ten=1のデータ、ten=2のデータ・・・とデータが小さな集団に分かれているわけです。

グループ化されたデータをsummarize関数に渡します。
countという変数を新たに作成し、n()でデータの数をカウントした値を代入します。ログデータみたいな数量でないデータはよくこれでカウントしてます。

で、これが結局何をしているかというと、データを面積が0~10,11~20,21~30・・・という小グループに分け、その小グループにそれぞれデータが何個あったのかをカウントしています。

 

> head(third,10)
Source: local data frame [10 x 2]

ten count
1 1 223
2 2 13533
3 3 33512
4 4 14633
5 5 12236
6 6 7927
7 7 4138
8 8 2621
9 9 1592
10 10 850

 

区ごとに物件数をカウントしたければこんな感じですね。
kuでグループ化して、データ数をカウントと。

> fourth <- sample %>% mutate(ten = ceiling(area/10)) %>% group_by(ku) %.% summarize(count = n())

> fourth
Source: local data frame [5 x 2]

ku count
1 港 14948
2 渋谷 14693
3 世田谷 37187
4 品川 13752
5 目黒 12669

 

区と町ごとに物件数をカウントしたければ、

> fourth <- sample %>%mutate(ten = ceiling(area/10)) %>% group_by(ku,mati) %>% summarize(count = n())
> fourth
Source: local data frame [173 x 3]
Groups: ku

ku mati count
1 港 愛宕 14
2 港 海岸 472
3 港 元赤坂 56
4 港 元麻布 204
5 港 虎ノ門 200
6 港 港南 343
7 港 高輪 1223
8 港 三田 933
9 港 芝 1180
10 港 芝浦 1415

区・町・部屋面積でグループ化したければ

> fourth <- sample %>% mutate(ten = ceiling(area/10)) %>% group_by(ku,mati,ten) %>% summarize(count = n())
> fourth
Source: local data frame [1,948 x 4]
Groups: ku, mati

ku mati ten count
1 港 愛宕 7 3
2 港 愛宕 9 2
3 港 愛宕 10 5
4 港 愛宕 13 1
5 港 愛宕 17 2
6 港 愛宕 20 1
7 港 海岸 2 42
8 港 海岸 3 131
9 港 海岸 4 52
10 港 海岸 5 61
.. .. … … …
>

n()以外にもmax()とかmin()とかsd()とかもあります。n()意外は変数名をカッコ内で指定しないとだめです。試しに各地区の各サイズの物件グループの面積の平均と標準偏差を出してみます。

> five <- sample %>% mutate(ten = ceiling(area/10)) %>% group_by(ku,mati,ten) %>% summarize(avg.area = mean(area), sd.area = sd(area))

> five
Source: local data frame [1,948 x 5]
Groups: ku, mati

ku mati ten avg.area sd.area
1 港 愛宕 7 67.64333 0.04618802
2 港 愛宕 9 88.69000 0.00000000
3 港 愛宕 10 92.39000 2.71020294
4 港 愛宕 13 124.15000 NaN
5 港 愛宕 17 163.74000 0.00000000
6 港 愛宕 20 194.16000 NaN
7 港 海岸 2 15.89714 3.10037550
8 港 海岸 3 22.93550 1.81477492
9 港 海岸 4 33.42462 3.28411295
10 港 海岸 5 45.11328 3.52784718

 

次にjoinをして、データの結合をやってみます。いわゆるvlookupってやつですね。

dplyrには4つのタイプのjoinが用意されています。

inner_joinは二つのデータをマッチした物のみをアウトプットします。カギになる変数の組み合わせが複数ある場合には全パターンの結果を出してくれます。

left_joinは二つのデータのマッチした物としなかった物の両方をアウトプットしてくれます。

anti_joinは二つのデータのマッチしなかった物のみをアウトプットしてくれます。

semi_joinは二つのデータのマッチした者のみをアウトプットしますが、xとyの二つのデータのうちのxに入っているカラムのみを出してくれます。

fourthは区と町とサイズごとに物件数をカウントしたデータで、fiveは区と町の物件の平均サイズと標準偏差のデータです。

これら二つのデータを結合したいので、結合のカギとしては区と町とサイズを使います。
最近知ったんですけど、mergeでもjoinでも条件に配列使えるんですね。

fourthを読み込んでパイプオペレーターでinner_joinに渡して、fiveと結合させます。
その時のカギとしてby=c(“ku”,”mati”,”ten”)で区・町・サイズの3つを条件にマッチさせています。

> six <- fourth %>% inner_join(five, by=c(“ku”,”mati”,”ten”))
> six
Source: local data frame [1,948 x 6]
Groups: ku, mati

ku mati ten count avg.area sd.area
1 港 愛宕 7 3 67.64333 0.04618802
2 港 愛宕 9 2 88.69000 0.00000000
3 港 愛宕 10 5 92.39000 2.71020294
4 港 愛宕 13 1 124.15000 NaN
5 港 愛宕 17 2 163.74000 0.00000000
6 港 愛宕 20 1 194.16000 NaN
7 港 海岸 2 42 15.89714 3.10037550
8 港 海岸 3 131 22.93550 1.81477492
9 港 海岸 4 52 33.42462 3.28411295
10 港 海岸 5 61 45.11328 3.52784718

 

ふぅ。いったんこんなとこでしょうか?filter, summarize, group_by, joinこの辺がわかれば大体出来る気がします。あとは条件で色々なRの関数を使ってみる事とかですかね?greplとかよく使ってます。

現状今やってる仕事のほとんどがデータ集計なので、dplyrで非常に助かってます。なんつーかいまのポジションって間違いなくRと今までの好奇心で支えられているなと思う次第です。

色々助かってしょうがないです。

 

Yutaniさんが公式の紹介記事を翻訳されているのでこちらを参照するのも良いと思います。

 

カテゴリー: R パーマリンク

Rのdplyrが便利ですねって話。 への1件のフィードバック

  1. ピンバック: Rのdplyrがもっと便利ですねって話。 | 分析のおはなし。

コメントを残す