dplyr入門

以下のvignetteの内容に沿っているが一部順序は前後している。

http://cran.rstudio.com/web/packages/dplyr/vignettes/introduction.html

dplyrパッケージとは

Hadley Wickhamが作成したデータ操作に特化したRのパッケージ。

彼がこれまでに作成した有名なRパッケージにはggplot2やplyr、reshape2などがある。

Rという統計に特化したDSLの中にさらに自分の価値観を反映したDSLを作り上げている様はまさにHadley Universe。

使うメリット

データ操作に特化したパッケージとしては同作者のplyrがあった。

しかしplyrは便利だが全てRで書かれておりとにかく遅い。

dplyrはC++で書かれており、無駄な関数呼び出しがないので速い。

どのくらい速いかはこちらを見てほしい。

http://d.hatena.ne.jp/dichika/20140103/p1

使い方

基本関数は5つ。

これにgroup_byを組み合わせることで集計していく。

使用するデータ

hflightsパッケージののhflightsデータを用いる。

hflightsデータはデータ数が大きいのでtbl_df形式に変換しておく。

# install.packages(c("dplyr","hflights")
library(dplyr)
library(hflights)
dim(hflights)
## [1] 227496     21
hflights_df <- tbl_df(hflights)
hflights_df
## Source: local data frame [227,496 x 21]
## 
##      Year Month DayofMonth DayOfWeek DepTime ArrTime UniqueCarrier
## 5424 2011     1          1         6    1400    1500            AA
## 5425 2011     1          2         7    1401    1501            AA
## 5426 2011     1          3         1    1352    1502            AA
## 5427 2011     1          4         2    1403    1513            AA
## 5428 2011     1          5         3    1405    1507            AA
## 5429 2011     1          6         4    1359    1503            AA
## 5430 2011     1          7         5    1359    1509            AA
## 5431 2011     1          8         6    1355    1454            AA
## 5432 2011     1          9         7    1443    1554            AA
## 5433 2011     1         10         1    1443    1553            AA
## ..    ...   ...        ...       ...     ...     ...           ...
## Variables not shown: FlightNum (int), TailNum (chr), ActualElapsedTime
##   (int), AirTime (int), ArrDelay (int), DepDelay (int), Origin (chr), Dest
##   (chr), Distance (int), TaxiIn (int), TaxiOut (int), Cancelled (int),
##   CancellationCode (chr), Diverted (int)

filterで抽出

filterは条件に沿った行を抽出する。 使い方としては、最初の引数にデータフレームを指定して2つ目以降の引数に条件を指定する。 この書き方は他の関数においても同じ。 AND条件の時はカンマで区切るだけで良い(&を使っても良い)。 OR条件の時は|演算子でつなぐ。

filter(hflights_df, Month==1, DayofMonth==1)
filter(hflights_df, Month==1|DayofMonth==1)

selectとmutateで列を操作

selectは列を抽出する。

複数列を指定する時は、カンマで区切る。

隣接した列なら:で指定できる。

指定した列以外を抽出したい時はカッコで囲んで-をつける。

select(hflights_df, Year, Month, DayOfWeek)
select(hflights_df, Year:DayOfWeek)
select(hflights_df, -(Year:DayOfWeek))

mutateは列を追加する。

似たような働きをする関数にplyrパッケージのtransformがあるが、mutateは新しく追加した列を同一操作内で指定できる。

こちらの方が便利なのでmutate使いましょう。

mutate(hflights_df, gain=ArrDelay - DepDelay, gain_per_hour=gain/(AirTime/60))

arrangeで並び替え

arrangeは指定した列において並び替える desc関数と組み合わせることで逆順に並べられる。

arrange(hflights_df, ArrDelay, Month)
arrange(hflights_df, desc(ArrDelay))

summariseで集約

summariseは関数を指定することで、その関数で集約した結果を得ることができる

summarise(hflights_df, delay=mean(DepDelay, na.rm=TRUE))
## Source: local data frame [1 x 1]
## 
##   delay
## 1 9.445

group_byでグループ化

group_byで指定した列でもって、グループ化することができる。 この結果にこれまで挙げてきた関数を適用することで、グループ単位の結果が得られる。

planes <- group_by(hflights_df, TailNum)
delay <- summarise(planes,
                   count=n(),
                   dist=mean(Distance, na.rm=TRUE),
                   delay=mean(ArrDelay, na.rm=TRUE))
delay <- filter(delay, count>20, dist<2000)

library(ggplot2)
ggplot(delay, aes(dist, delay)) + 
  geom_point(aes(size=count), alpha=1/2) + 
  geom_smooth() + 
  scale_size_area()
## geom_smooth: method="auto" and size of largest group is >=1000, so using gam with formula: y ~ s(x, bs = "cs"). Use 'method = x' to change the smoothing method.
## Warning: Removed 1 rows containing missing values (stat_smooth).
## Warning: Removed 1 rows containing missing values (geom_point).

plot of chunk unnamed-chunk-8

chainの喜び

chain(%.%)関数を使うことで各操作をつないで一度に表現することができる。

これが実に楽しい。

一時的にデータフレームを作ったりしなくて良いので便利。

書き方はこれまで第一引数として指定していたデータフレームを省略して%.%でつないでいくだけ。

上記のコードをchainで書き直すと以下のようになる。

hflights %.% 
  group_by(TailNum) %.% 
  summarise(count=n(), dist=mean(Distance, na.rm=TRUE), delay=mean(ArrDelay, na.rm=TRUE)) %.%
  filter(count>20, dist<2000) %.%
  ggplot(aes(dist, delay)) + geom_point(aes(size=count), alpha=1/2) + geom_smooth() + scale_size_area()

最後に、使えるデータ形式の話

データフレームの他に使えるデータ形式として以下がある。

これらのデータもこれまで紹介してきた文法でもって統一的に操作することができる。 具体例については別途紹介していく。

なおdplyrとデータベースについては以下に書いたので参照されたい。 http://rpubs.com/dichika/dplyr_db