【初心者向け】dplyrの使い方(tidyverse)

R言語のデファクトスタンダードともいえるtidyverseに含まれるdplyrライブラリの使い方についてです。dplyrは表データの集計や前処理になくてはならいパッケージで、Rstudioと組み合わせることでデータ分析を円滑に快適にすることができます。

dplyr(tidyverse)のインストール

Rにインストールしていない方は以下のパッケージをインストールしておいてください。

install.packages("tidyverse")

利用の前段

dplyr%>%(パイプ演算子)を利用してAPIを記載していくのが一般的な使い方です。イメージとしてオブジェクトを関数(API)に受け渡しをして処理を実行します。SQLのwith句の流れと似た流れかもしれません。もう少し突っ込んだ話をするとオブジェクトのAPIの第一引数にうけたわして処理をしていきます。

試しにlibraryを読み込んで今回のテストデータをhead関数でサンプルデータを抽出してみましょう。

d <- read.csv('https://raw.githubusercontent.com/maruko-rosso/datasciencehenomiti/master/data/ShopSales.csv',header = T)
library(tidyverse)
d %>% head()

## date          shop staff  item  price quantity
## 1 2018-02-01      New York  Kory itemA 290000        1
## 2 2018-02-01      New York  Kory itemB 160000        1
## 3 2018-02-01      New York  Kory itemC  14000        1
## 4 2018-02-01 San Francisco  Rose itemD 570000        3
## 5 2018-02-01      New York  Kory itemE  11100        1
## 6 2018-02-01      New York  Kory itemE  11100        1

集計 summarise

データの集計はsummariseを使います。以下はn()を組み合わせて表の件数を取得しています。

d %>% summarise(n())
## n()
## 1 2276

以下のようなやり方でbaseパッケージの集計する関数を組み合わせて集約した値を取得することができます。

d %>% summarise(sum(price), mean(price))
## sum(price) mean(price)
## 1  418912470    184056.4

集約 groupby

次は表データの集約です。以下はshop列の要素別に件数とstaffのユニーク集計を行っています。

d %>% group_by(shop) %>% summarise(n(), n_distinct(staff))

## `summarise()` ungrouping output (override with `.groups` argument)
## # A tibble: 3 x 3
## shop          `n()` `n_distinct(staff)`
##                         
## 1 Chicago         149                   3
## 2 New York       1257                   5
## 3 San Francisco   870                   4

以下のように計算結果をオブジェクトとして作成することもできます。ちなみにパイプ演算子で集計を続けるときにgroupbyの設定を外すときはungroup関数を挟むことで実現できますので頭の隅においておいてください。

d_2 <- d %>% group_by(shop) %>% summarise(n())
d_2

## # A tibble: 3 x 2
## shop          n()
##          
## 1 Chicago         149
## 2 New York       1257
## 3 San Francisco   870

列の選択 select

d %>% select(staff) %>% head()

## staff
## 1  Kory
## 2  Kory
## 3  Kory
## 4  Rose
## 5  Kory
## 6  Kory

以下のように指定した列以外を取得することも可能です。

d %>% select(-staff) %>% head()

## date          shop  item  price quantity
## 1 2018/2/1      New York itemA 290000        1
## 2 2018/2/1      New York itemB 160000        1
## 3 2018/2/1      New York itemC  14000        1
## 4 2018/2/1 San Francisco itemD 570000        3
## 5 2018/2/1      New York itemE  11100        1
## 6 2018/2/1      New York itemE  11100        1

列の追加 mutate

以下のようにして列の追加と計算結果を挿入することができます。

d %>% mutate(price_sum = sum(price)) %>% head()

## date          shop staff  item  price quantity price_sum
## 1 2018/2/1      New York  Kory itemA 290000        1 418912470
## 2 2018/2/1      New York  Kory itemB 160000        1 418912470
## 3 2018/2/1      New York  Kory itemC  14000        1 418912470
## 4 2018/2/1 San Francisco  Rose itemD 570000        3 418912470
## 5 2018/2/1      New York  Kory itemE  11100        1 418912470
## 6 2018/2/1      New York  Kory itemE  11100        1 418912470

group_by関数と組み合わせることで、SQLのwindow関数のような使い方もできます。

d %>% group_by(staff) %>% mutate(price_sum = sum(price)) %>% head()

## # A tibble: 6 x 7
## # Groups:   staff [2]
## date     shop          staff item   price quantity price_sum
##                          
## 1 2018/2/1 New York      Kory  itemA 290000        1  28116970
## 2 2018/2/1 New York      Kory  itemB 160000        1  28116970
## 3 2018/2/1 New York      Kory  itemC  14000        1  28116970
## 4 2018/2/1 San Francisco Rose  itemD 570000        3  12366200
## 5 2018/2/1 New York      Kory  itemE  11100        1  28116970
## 6 2018/2/1 New York      Kory  itemE  11100        1  28116970

絞込み filter

表データをSQLのwhere句のように絞りこむには以下のようにします。注意点としてRの比較演算子は「==」で等号「!=」で不等号(≠)になります。

d %>% filter(staff == "Kory") %>% head()

## date     shop staff  item  price quantity
## 1 2018/2/1 New York  Kory itemA 290000        1
## 2 2018/2/1 New York  Kory itemB 160000        1
## 3 2018/2/1 New York  Kory itemC  14000        1
## 4 2018/2/1 New York  Kory itemE  11100        1
## 5 2018/2/1 New York  Kory itemE  11100        1
## 6 2018/2/1 New York  Kory itemE  11100        1


d %>% filter(price < 2000) %>% head()

## date          shop   staff  item price quantity
## 1  2018/2/2 San Francisco Richard itemI  1910        1
## 2  2018/2/5 San Francisco  Rachel itemI  1910        1
## 3 2018/2/12 San Francisco  Rachel itemI  1910        1
## 4 2018/2/14      New York  Rachel itemI  1910        2
## 5 2018/2/14      New York  Rachel itemI  1910        1
## 6 2018/2/14      New York  Rachel itemI  1910        1

表の並び替え arrange

以下のようにすることで表の昇順、降順の並び替えができます。複数の列名を記載することも可能です。

d %>% arrange(price) %>% head()

## date          shop   staff  item price quantity
## 1  2018/2/2 San Francisco Richard itemI  1910        1
## 2  2018/2/5 San Francisco  Rachel itemI  1910        1
## 3 2018/2/12 San Francisco  Rachel itemI  1910        1
## 4 2018/2/14      New York  Rachel itemI  1910        2
## 5 2018/2/14      New York  Rachel itemI  1910        1
## 6 2018/2/14      New York  Rachel itemI  1910        1

d %>% arrange(desc(quantity)) %>% head()

## date          shop   staff  item  price quantity
## 1 2018/2/14      New York  Rachel itemB 160000       40
## 2 2018/2/18      New York  Rachel itemB 160000       28
## 3  2018/2/2 San Francisco Richard itemB 160000       13
## 4 2018/2/15 San Francisco  Rachel itemG  65000       13
## 5 2018/2/22      New York    Rose itemB 160000       11
## 6 2018/2/22      New York    Rose itemB 160000       11

表の結合 left_join

表の結合をすることができます。今回は左寄せを行うleft_joinを実施しましたが、inner_joincross_joinといったこともできます。

d_2 <- d %>% group_by(shop) %>% summarise(n())

d %>% 
  left_join(d_2,by = c("shop" = "shop")) %>% 
  head()


## date          shop staff  item  price quantity  n()
## 1 2018/2/1      New York  Kory itemA 290000        1 1257
## 2 2018/2/1      New York  Kory itemB 160000        1 1257
## 3 2018/2/1      New York  Kory itemC  14000        1 1257
## 4 2018/2/1 San Francisco  Rose itemD 570000        3  870
## 5 2018/2/1      New York  Kory itemE  11100        1 1257
## 6 2018/2/1      New York  Kory itemE  11100        1 1257