読者です 読者をやめる 読者になる 読者になる

行列屋さんの作業ログ

行列まわりで色々やってたエンジニアの作業メモ&国内外旅行記ブログ

dplyrでデータの集計を行う

大量(1億件くらい)のデータを集計する必要が生じた。
ということで今回は、Rであるラベル(複数)のデータがいくつ存在しているのか高速に集計するお話。
アンケートを取って、下のような結果が得られたとする。

adress <- sample(c('千葉','滋賀','佐賀'),size = 1000,replace = TRUE)
sex <- sample(c('男','女'),size = 1000,replace = TRUE)
work <- sample(c('学生','社会人'),size = 1000,replace = TRUE)

data <- data.frame(adress=adress,sex=sex,work=work)

> head(data)
  adress sex   work

1   千葉  女 社会人

2   佐賀  女   学生

3   千葉  女 社会人

4   滋賀  男   学生

5   佐賀  女 社会人

6   佐賀  女 社会人

各県の居住者が何人居るのかは、table関数を使えば判る。

> table(data$adress)
佐賀 千葉 滋賀
 337  357  306

じゃあ、居住地が◯で、性別が☓で、職業が△な人が何人居るのかカウントするにはどうすれば良いのだろう。
それも出来れば高速で。1億件近いデータを処理せねばならんのだ。

こうして悩んでいた所、先輩からdplyrパッケージというのを教わる。
このパッケージの使い方は、このサイトに非常によく纏まっていた。

plyr — データ分割-関数適用-再結合を効率的に — Watallica metallicus

前半はplyrという別のパッケージの話。こっちは処理速度遅め。
(内部でapply系関数を回してるという噂)

CRANからいつものようにインストール。
libraryで読み込んだら、group_by関数とsummarise関数を使う。

> g <- group_by(data,adress,sex,work)> summarise(g,n())
Source: local data frame [12 x 4]

Groups: adress, sex



   adress sex   work n()

1    佐賀  女   学生  84

2    佐賀  女 社会人  79

3    佐賀  男   学生  77

4    佐賀  男 社会人  92

5    千葉  女   学生  91

6    千葉  女 社会人  84

7    千葉  男   学生  86

8    千葉  男 社会人  82

9    滋賀  女   学生  89

10   滋賀  女 社会人  75

11   滋賀  男   学生  81

12   滋賀  男 社会人  80

group_byではdataにつづいて、集計対象の変数名(列名)を記述する。
そしてグルーピングの結果をsummarise関数に渡し、グループ毎にカウントをん()でやってあげる。

このパッケージの良い所は、物凄い高速に処理を行えるところ。
実際に1億件のデータを計算機上で処理させてみたけれど、数秒で終わってしまった。
このパッケージつかえば、既存のスクリプトもかなり高速化出来そうである、