初心者向けセッション(3)

前田和寛(@kazutan)
2015/6/13

パッケージを使ったデータ操作

SappoRo.R #4

icon

自己紹介

そろそろ限界きてる

オモシロクナール

内容

パッケージを利用してデータをいじろう

dplyrパッケージ

プライヤのようにデータを操作

tidyrパッケージ

縦型データと横型データを変換

dplyrパッケージ

dplryパッケージとは

特徴

  • Hadley Wickhamが作成した、データ操作に特化したパッケージ
  • データ操作をシンプルに、そして高速に処理
  • Rのパッケージ群のなかでもトップレベルの人気
  • このパッケージを前提にして書かれたコードも多数

参考資料(Web)

dplyrの基本関数

filter()

条件指定した行を抽出

select()

指定した列を抽出

mutate()

新しく列を追加、列の更新

arrange()

並び替え

summarise()

集約(集計)する

前準備

パッケージインストールと読み込み

install.packages("dplyr")
library("dplyr")

みんなのアイドルirisたんを使って説明します

df <- iris

行の抽出 dplyr::filter(データフレーム, フィルター条件, ...)

df.virginica <- dplyr::filter(df, Species=='virginica')
  Sepal.Length Sepal.Width Petal.Length Petal.Width   Species
1          6.3         3.3          6.0         2.5 virginica
2          5.8         2.7          5.1         1.9 virginica
3          7.1         3.0          5.9         2.1 virginica
  • dplyr::は「dplyrパッケージ内の」という意味です
  • 同じ名前の関数が他にもあるんで、これを付けたほうが確実です

列の抽出 dplyr::select(データフレーム, 列の指定, ...)

df.popo <- dplyr::select(df, c(Sepal.Width,Species))
  Sepal.Width Species
1         3.5  setosa
2         3.0  setosa
3         3.2  setosa
  • 列の指定方法はsubset()の時と同様

列の追加・更新 dplyr::mutate(データフレーム, ...)

新しい列を追加

df.pp <- dplyr::mutate(df.popo, pp=Sepal.Width*2)
  Sepal.Width Species  pp
1         3.5  setosa 7.0
2         3.0  setosa 6.0
3         3.2  setosa 6.4

列名がすでにある場合は更新

df.pp2 <- dplyr::mutate(df.pp, pp=Sepal.Width*3)
  Sepal.Width Species   pp
1         3.5  setosa 10.5
2         3.0  setosa  9.0
3         3.2  setosa  9.6

並べ替え dplyr::arrange(データフレーム, キー列, ...)

基本は昇順

df.pp3 <- dplyr::arrange(df.pp2, Sepal.Width)
  Sepal.Width    Species  pp
1         2.0 versicolor 6.0
2         2.2 versicolor 6.6
3         2.2 versicolor 6.6

desc()と組み合わせると降順

df.pp3 <- dplyr::arrange(df.pp2, desc(Sepal.Width))
  Sepal.Width Species   pp
1         4.4  setosa 13.2
2         4.2  setosa 12.6
3         4.1  setosa 12.3

集約 dplyr::summarise(データフレーム, ...)

列の集計を実施。色々応用可能。

df.pp4 <- dplyr::summarize(df.pp3, pp.sum=sum(pp))
  pp.sum
1 1375.8

グループ化して集計も…!?

df.pp5 <- dplyr::group_by(iris, Species)
df.pp6 <- dplyr::summarize(df.pp5, Sepal.Length.Mean = mean(Sepal.Length))
df.pp6
Source: local data frame [3 x 2]

     Species Sepal.Length.Mean
1     setosa             5.006
2 versicolor             5.936
3  virginica             6.588

%>%のときめき

このコードが…

z <- dplyr::select(iris,c(Sepal.Width, Species))
zz <- dplyr::group_by(z, Species)
zzz <- dplyr::summarize(zz, Sepal.Width.Mean = mean(Sepal.Width))
zzz

こうなる!!

iris %>%
  dplyr::select(.,c(Sepal.Width,Species)) %>% 
  dplyr::group_by(.,Species) %>% 
  dplyr::summarize(.,Sepal.Width.Mean = mean(Sepal.Width))

tidyrパッケージ

tidyrパッケージとは

  • データの縦型と横型を変換
  • 他にもいろいろ
  • 今日は基本のみ

複数列で持っている値を行持ちに展開

  • いわゆる「縦型」データに変換するにはtidyr::gather関数
iris2 <- dplyr::mutate(iris,id=rownames(iris))
z <- tidyr::gather(iris2, hoge, value, c(Sepal.Length, Sepal.Width, Petal.Length, Petal.Width))
head(z,3)
  Species id         hoge value
1  setosa  1 Sepal.Length   5.1
2  setosa  2 Sepal.Length   4.9
3  setosa  3 Sepal.Length   4.7
  • tidyr::gather(データ, まとめた変数名, 値, まとめる対象)

複数行持ちの値を列持ちに変換

  • いわゆる「横型」データに変換するにはtidyr::spread関数
  • ただし、IDとなるような変数が必要(エラーが出る)
head(tidyr::spread(z,hoge,value),3)
  Species id Sepal.Length Sepal.Width Petal.Length Petal.Width
1  setosa  1          5.1         3.5          1.4         0.2
2  setosa 10          4.9         3.1          1.5         0.1
3  setosa 11          5.4         3.7          1.5         0.2

その他にも…

他にも豊富な機能がはいってます

dplyrでは…

  • 変数名の変更
  • 複数列でまとめて実行
  • データベースを扱える

tidyrでは…

  • 一列のデータを複数列に分割(separate)
  • 複数列のデータを1列に結合(unite)

…詳しくは紹介した資料を見てください。

Enjoy!