<< 目次へ
最終更新日 : 2015.4.29
dplyrによるデータフレーム操作
dplyrというデータフレームの操作に特化した便利なパッケージがあります。ただし、古典的な「書き方」を知っている人は無理に覚える必要はないかもしれません。試したことはありませんが、dplyrに含まれる関数を用いた方が高速に処理ができるそうです。
ここでは練習のために、Rに最初から入っているデータ:CO2を例にとって説明していきたいと思います。特に何もせずとも、Rのコンソール画面に CO2 と入力してみてください。そうすると以下のようなデータが表示されるはずです。
> CO2 Plant Type Treatment conc uptake 1 Qn1 Quebec nonchilled 95 16.0 2 Qn1 Quebec nonchilled 175 30.4 3 Qn1 Quebec nonchilled 250 34.8 4 Qn1 Quebec nonchilled 350 37.2 5 Qn1 Quebec nonchilled 500 35.3 6 Qn1 Quebec nonchilled 675 39.2 7 Qn1 Quebec nonchilled 1000 39.7 8 Qn2 Quebec nonchilled 95 13.6 9 Qn2 Quebec nonchilled 175 27.3 10 Qn2 Quebec nonchilled 250 37.1 11 Qn2 Quebec nonchilled 350 41.8 12 Qn2 Quebec nonchilled 500 40.6 13 Qn2 Quebec nonchilled 675 41.4 14 Qn2 Quebec nonchilled 1000 44.3 15 Qn3 Quebec nonchilled 95 16.2 16 Qn3 Quebec nonchilled 175 32.4 (以下省略)
CO2には「Plant」、「Type」、「Treatment」、「conc」、「uptake」といった5つの変数が含まれています。
さて、まずはdplyrパッケージをインストールし、パッケージを読み込む必要があります。
> install.packages("dplyr") > library(dplyr)
■行と列の抽出操作
古典的な書き方では [ ] を使うことで特定の条件にマッチするレコードを抽出することができました。これを filter() という関数を用いることで同じ操作ができます。古典的な書き方ではOR条件を | で示し、AND条件を & で示します。一方でfilter()ではOR条件を | で示し、AND条件を , で示します。
> CO2[CO2$Plant=="Qc1" & CO2$Type=="Quebec", ] # 古典的な書き方 AND条件は & で示す Plant Type Treatment conc uptake 22 Qc1 Quebec chilled 95 14.2 23 Qc1 Quebec chilled 175 24.1 24 Qc1 Quebec chilled 250 30.3 25 Qc1 Quebec chilled 350 34.6 26 Qc1 Quebec chilled 500 32.5 27 Qc1 Quebec chilled 675 35.4 28 Qc1 Quebec chilled 1000 38.7 > filter(CO2, Plant=="Qc1", Type=="Quebec") # filter()を用いる方法 AND条件は , で示す Plant Type Treatment conc uptake 1 Qc1 Quebec chilled 95 14.2 2 Qc1 Quebec chilled 175 24.1 3 Qc1 Quebec chilled 250 30.3 4 Qc1 Quebec chilled 350 34.6 5 Qc1 Quebec chilled 500 32.5 6 Qc1 Quebec chilled 675 35.4 7 Qc1 Quebec chilled 1000 38.7
さて古典的な書き方では、列の操作も行操作と同様に [ ] を使って必要な列を抽出することができました。これを select() という関数を使うことで実現できます。なお、必要な列を抽出するのとは逆に、不要な列を削除する(結果としてどちらも同じだが)場合は - を使うことで実現できます。例えば CO2[, -c(2,5)] もしくは select(CO2, -(2:5)) のように。
> CO2[, c(2,5)] # 古典的方法 列番号を指定Ver. Type uptake 1 Quebec 16.0 2 Quebec 30.4 3 Quebec 34.8 4 Quebec 37.2 5 Quebec 35.3 > CO2[, c("Type", "uptake")] # 古典的方法 変数名を指定Ver. Type uptake 1 Quebec 16.0 2 Quebec 30.4 3 Quebec 34.8 4 Quebec 37.2 5 Quebec 35.3 > select(CO2, 2,5) # select() 列番号を指定Ver. Type uptake 1 Quebec 16.0 2 Quebec 30.4 3 Quebec 34.8 4 Quebec 37.2 5 Quebec 35.3 > select(CO2, Type, uptake) # select() 変数名を指定Ver. Type uptake 1 Quebec 16.0 2 Quebec 30.4 3 Quebec 34.8 4 Quebec 37.2 5 Quebec 35.3
列の操作でselect()を使った方が便利な例として、以下のような使い方があげられます。
> select(CO2, Plant:Treatment) # 連続した変数を抽出する Plant Type Treatment 1 Qn1 Quebec nonchilled 2 Qn1 Quebec nonchilled 3 Qn1 Quebec nonchilled 4 Qn1 Quebec nonchilled 5 Qn1 Quebec nonchilled
元々のデータフレームに新たな変数を追加する場合、以前は cbind() を使うのが常套手段でしたが、 mutate() という関数を使うことで同様のことができます。
> mutate(CO2, new=uptake/100) # CO2に対して、新たな変数newを列結合する Plant Type Treatment conc uptake new 1 Qn1 Quebec nonchilled 95 16.0 0.160 2 Qn1 Quebec nonchilled 175 30.4 0.304 3 Qn1 Quebec nonchilled 250 34.8 0.348 4 Qn1 Quebec nonchilled 350 37.2 0.372 5 Qn1 Quebec nonchilled 500 35.3 0.353
■データフレームのソート(データフレームの並び替え)
従来、データフレームについてソートを行う場合、 order() を用いていました。しかし arrange() を使うことで簡単にソートができるようになっています。
> srt.indx <- order(CO2$uptake) # 従来はorder()を用いてソートしていた > CO2[srt.indx, ] # uptakeについて昇順ソート Plant Type Treatment conc uptake 71 Mc2 Mississippi chilled 95 7.7 29 Qc2 Quebec chilled 95 9.3 64 Mc1 Mississippi chilled 95 10.5 43 Mn1 Mississippi nonchilled 95 10.6 78 Mc3 Mississippi chilled 95 10.6 57 Mn3 Mississippi nonchilled 95 11.3 > arrange(CO2, uptake) # arrange()を使う場合 Plant Type Treatment conc uptake 1 Mc2 Mississippi chilled 95 7.7 2 Qc2 Quebec chilled 95 9.3 3 Mc1 Mississippi chilled 95 10.5 4 Mn1 Mississippi nonchilled 95 10.6 5 Mc3 Mississippi chilled 95 10.6 6 Mn3 Mississippi nonchilled 95 11.3
どちらもデフォルトでは「昇順」ソートですが、「降順」ソートにすることもできます。また、複数の変数をキーとしてソートすることもできます。
## 従来どおりorder()を使う場合 # 2つの変数をキーに指定すると、どちらも降順になってしまうのが面倒 > srt.indx <- order(CO2$Treatment, CO2$uptake, decreasing=TRUE) > CO2[srt.indx, ] Plant Type Treatment conc uptake 35 Qc2 Quebec chilled 1000 42.4 42 Qc3 Quebec chilled 1000 41.4 41 Qc3 Quebec chilled 675 39.6 40 Qc3 Quebec chilled 500 38.9 32 Qc2 Quebec chilled 350 38.8 28 Qc1 Quebec chilled 1000 38.7 33 Qc2 Quebec chilled 500 38.6 ## arrange()を使う場合 # 2つの変数を指定したとき、どちらか任意の方に「だけ」降順指定ができる(便利!) > arrange(CO2, Treatment, desc(uptake)) Plant Type Treatment conc uptake 1 Qn3 Quebec nonchilled 1000 45.5 2 Qn2 Quebec nonchilled 1000 44.3 3 Qn3 Quebec nonchilled 675 43.9 4 Qn3 Quebec nonchilled 500 42.9 5 Qn3 Quebec nonchilled 350 42.1 6 Qn2 Quebec nonchilled 350 41.8 7 Qn2 Quebec nonchilled 675 41.4
■グループ集計
通常、Rでグループ集計を行う際には tapply() を使うのが一般的でした。しかし、dplyrパッケージには group_by という関数と summarize() という関数が含まれており、これらを使うことでグループ集計ができます。
## Typeについて、uptakeの平均を計算する > tapply(CO2$uptake, CO2$Type, mean) Quebec Mississippi 33.54286 20.88333 ## 上記と同じことをgroup_byとsummarizeで実行してみる > gCO2 <- group_by(CO2, Type) # グループ化したい変数を指定し、新たなデータフレームを作成 > gCO2 # 中身を確認。Typeがグループ変数になっていることが確認できる Source: local data frame [84 x 5] Groups: Type Plant Type Treatment conc uptake 1 Qn1 Quebec nonchilled 95 16.0 2 Qn1 Quebec nonchilled 175 30.4 3 Qn1 Quebec nonchilled 250 34.8 4 Qn1 Quebec nonchilled 350 37.2 5 Qn1 Quebec nonchilled 500 35.3 6 Qn1 Quebec nonchilled 675 39.2 7 Qn1 Quebec nonchilled 1000 39.7 8 Qn2 Quebec nonchilled 95 13.6 9 Qn2 Quebec nonchilled 175 27.3 10 Qn2 Quebec nonchilled 250 37.1 .. ... ... ... ... ... > summarize(gCO2, upt.M=mean(uptake)) # tapplyに該当する操作部分 Source: local data frame [2 x 2] Type upt.M 1 Quebec 33.54286 2 Mississippi 20.88333 > summarize(gCO2, upt.M=n()) # ちなみに「カウント」したい場合はこのように書く Source: local data frame [2 x 2] Type upt.M 1 Quebec 42 2 Mississippi 42 ## グループ集計のキーとする変数は複数指定できる > gCO2 <- group_by(CO2, Plant, Type, Treatment) > gCO2 Source: local data frame [84 x 5] Groups: Plant, Type, Treatment Plant Type Treatment conc uptake 1 Qn1 Quebec nonchilled 95 16.0 2 Qn1 Quebec nonchilled 175 30.4 3 Qn1 Quebec nonchilled 250 34.8 4 Qn1 Quebec nonchilled 350 37.2 5 Qn1 Quebec nonchilled 500 35.3 6 Qn1 Quebec nonchilled 675 39.2 7 Qn1 Quebec nonchilled 1000 39.7 8 Qn2 Quebec nonchilled 95 13.6 9 Qn2 Quebec nonchilled 175 27.3 10 Qn2 Quebec nonchilled 250 37.1 .. ... ... ... ... ... > summarize(gCO2, Plant.count=mean(uptake)) Source: local data frame [12 x 4] Groups: Plant, Type Plant Type Treatment Plant.count 1 Qn1 Quebec nonchilled 33.22857 2 Qn2 Quebec nonchilled 35.15714 3 Qn3 Quebec nonchilled 37.61429 4 Qc1 Quebec chilled 29.97143 5 Qc3 Quebec chilled 32.58571 6 Qc2 Quebec chilled 32.70000 7 Mn3 Mississippi nonchilled 24.11429 8 Mn2 Mississippi nonchilled 27.34286 9 Mn1 Mississippi nonchilled 26.40000 10 Mc2 Mississippi chilled 12.14286 11 Mc3 Mississippi chilled 17.30000 12 Mc1 Mississippi chilled 18.00000