パッケージdplyrを使ってデータフレームを爆速で操作

%>%演算子を使う

この%>%演算子を使うためにはパッケージが必要です。パッケージtidyverseやパッケージmagrittrの中に入っているのですが、ここではパッケージmagrittrを使うことにします。このページで操作を紹介するパッケージdplyrと%>%演算子を組み合わせると爆速で色々操作できるようになります。

パッケージmagrittr自体の使い方はこの辺 [1] が参考になりました。

[1]  magrittrの使い方

パッケージdplyr

パッケージdplyrにはたくさんの機能があるようですが、ここではfilter、summarise、group_by、arrange、select、rename、mutateの使い方を紹介します。

まずは、以下の2つのパッケージをインストールしましょう。

R Console
> library(magrittr)
> library(dplyr)

filter

まずは、条件式にマッチした行のみに絞り込むfilter関数です。デフォルトの関数だとsubset関数を使ったり、[]を使ったりするのですが、dplyrのfilter関数はこれらと比べてもとても便利です。

R Console
> iris %>% # irisのデータを呼び出し、%>%を使って次の行のプログラムにデータを送る
+   dplyr::filter(iris$Species=="setosa") %>% # irisデータのSpecied列の値がsetosaと一致した行のみに絞り込む。この結果を%>%を使って次の行のプログラムに送る。
+   head(5) # 最初の5行を表示。
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
4          4.6         3.1          1.5         0.2  setosa
5          5.0         3.6          1.4         0.2  setosa

上の例では、
dplyr::filter(iris$Species==”setosa”)
と記述していますが、
dplyr::filter(.$Species==”setosa”)

dplyr::filter(Species==”setosa”)
と略しても同じ結果が得られます。

また、&(AND;かつ)を使って複数の条件でデータを絞り込むこともできます。もしくは(OR;I)を使うこともできます。

R Console
> iris %>%
+   dplyr::filter(Species=="setosa" & Petal.Width>0.4) # irisデータのSpecied列の値がsetosaと一致した行で、かつ、Petal.Widthの値が0.4より大きい行のみに絞り込む。
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.3          1.7         0.5  setosa
2          5.0         3.5          1.6         0.6  setosa

summarise

基本統計量を集計する際に便利です [3]。

R Console
> iris %>% # irisのデータを呼び出し、%>%を使って次の行のプログラムにデータを送る
+   dplyr::summarise(平均値=mean(Sepal.Length), 標準偏差=sd(Sepal.Length), 標本数=n(), 標準誤差=sd(Sepal.Length)/sqrt(n())) # このようにラベル名=関数で計算できる。
    平均値  標準偏差 標本数   標準誤差
1 5.843333 0.8280661    150 0.06761132

summarise内で使える関数は、mean、median、sd、IQR、min、max、quantile、nなどいろいろあるようです。corの中に2変数を入れるとピアソンの相関係数が計算できたり、method=”spearman”オプションも使えたり、なんかいろいろできるみたいです。

quantileに関しては、1変数だけしか返すことができないようなので、こんな感じで使うものなんでしょうかね?

R Console
> iris %>%
+   dplyr::summarise("1Q"=quantile(Sepal.Length)[2], "3Q"=quantile(Sepal.Length)[4])
   1Q  3Q
1 5.1 6.4

summarise_each関数を使うと、指定した列に対して複数の関数を適用できます。適用する関数はlist内に指定します。

R Console
> iris %>% # irisのデータを呼び出し、%>%を使って次の行のプログラムにデータを送る
+   dplyr::summarise_each(list(平均=mean, 標準偏差=sd), Sepal.Length, Sepal.Width) %>% # list関数内にラベル=関数で指定し、計算結果を次のプログラムに送る。
+   round(digits = 2) # 計算結果を小数点2位で四捨五入する。
  Sepal.Length_平均 Sepal.Width_平均 Sepal.Length_標準偏差 Sepal.Width_標準偏差
1              5.84             3.06                  0.83                 0.44

group_by

summariseでは、対象のデータフレーム全体に対しminやmax等の関数を適用しましたが、group_byを使用することで、指定した列のカテゴリーごとに集計することが可能です。

R Console
> iris %>% # irisのデータを呼び出し、%>%を使って次の行のプログラムにデータを送る
+   dplyr::group_by(Species) %>% # Speciesのカテゴリーに従いグループ分けし、次の行のプログラムにデータを送る
+   dplyr::summarise_each(list(平均値=mean, 標準偏差=sd), Sepal.Length)
# A tibble: 3 x 3
  Species    平均値 標準偏差
1 setosa       5.01    0.352
2 versicolor   5.94    0.516
3 virginica    6.59    0.636

arrange

ソートを行います。デフォルトでは昇順でソートし、desc関数を使うと降順でソートします。複数の条件を指定することもできます。

R Console
> iris %>% # irisのデータを呼び出し、%>%を使って次の行のプログラムにデータを送る
+   dplyr::arrange(Sepal.Length) %>% # Sepal.Length列を昇順でソートし、次の行のプログラムにデータを送る
+   head(5) # 先頭の5行を表示
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          4.3         3.0          1.1         0.1  setosa
2          4.4         2.9          1.4         0.2  setosa
3          4.4         3.0          1.3         0.2  setosa
4          4.4         3.2          1.3         0.2  setosa
5          4.5         2.3          1.3         0.3  setosa
> iris %>% # irisのデータを呼び出し、%>%を使って次の行のプログラムにデータを送る + dplyr::arrange(desc(Sepal.Length)) %>% # Sepal.Length列を降順でソートし、次の行のプログラムにデータを送る + head(5) # 先頭の5行を表示 Sepal.Length Sepal.Width Petal.Length Petal.Width Species 1 7.9 3.8 6.4 2.0 virginica 2 7.7 3.8 6.7 2.2 virginica 3 7.7 2.6 6.9 2.3 virginica 4 7.7 2.8 6.7 2.0 virginica 5 7.7 3.0 6.1 2.3 virginica
> iris %>% # irisのデータを呼び出し、%>%を使って次の行のプログラムにデータを送る + dplyr::arrange(Sepal.Length, Petal.Length) %>% # Sepal.Length列とPetal.Length列を昇順でソートし、次の行のプログラムにデータを送る + head(5) # 先頭の5行を表示 Sepal.Length Sepal.Width Petal.Length Petal.Width Species 1 4.3 3.0 1.1 0.1 setosa 2 4.4 3.0 1.3 0.2 setosa 3 4.4 3.2 1.3 0.2 setosa 4 4.4 2.9 1.4 0.2 setosa 5 4.5 2.3 1.3 0.3 setosa

 

select

列を選択する関数です。

R Console
> iris %>% # irisのデータを呼び出し、%>%を使って次の行のプログラムにデータを送る
+   dplyr::select(Sepal.Length, Species) %>% # Sepal.Length列とSpecies列を選択し、次の行のプログラムにデータを送る
+   head(5) # 先頭の5行を表示
  Sepal.Length Species
1          5.1  setosa
2          4.9  setosa
3          4.7  setosa
4          4.6  setosa
5          5.0  setosa

rename

列名を変更する関数です。

R Console
> iris %>% # irisのデータを呼び出し、%>%を使って次の行のプログラムにデータを送る
+   dplyr::rename(がく長=Sepal.Length, がく幅=Sepal.Width, 花弁長=Petal.Length, 花弁幅=Petal.Width, 種=Species) %>% # 変更後の列名=変更前の列名の形で列名を変更し、次の行のプログラムにデータを送る
+   head(5) # 先頭の5行を表示
  がく長 がく幅 花弁長 花弁幅     種
1    5.1    3.5    1.4    0.2 setosa
2    4.9    3.0    1.4    0.2 setosa
3    4.7    3.2    1.3    0.2 setosa
4    4.6    3.1    1.5    0.2 setosa
5    5.0    3.6    1.4    0.2 setosa

mutate

新しく列を追加する関数です。これが一番便利かもしれません。

下の例のように既存の変数を元に計算し、新たな変数を新たな列に収めるようなことができます。下の例では、LengthとWidthを掛けた数字をArea(面積)として計算し、新たな列に収めています。

R Console
> iris %>% # irisのデータを呼び出し、%>%を使って次の行のプログラムにデータを送る
+   dplyr::mutate(Sepal.Area=(Sepal.Length*Sepal.Width)) %>% # Sepal.Areaという名前の列を作り、Sepal.Length×Sepal.Widthで計算した値を入れ、次の行のプログラムにデータを送る
+   dplyr::mutate(Petal.Area=(Petal.Length*Petal.Width)) %>% # Petal.Areaという名前の列を作り、Petal.Length×Petal.Widthで計算した値を入れ、次の行のプログラムにデータを送る
+   head(5) # 先頭の5行を表示
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species Sepal.Area Petal.Area
1          5.1         3.5          1.4         0.2  setosa      17.85       0.28
2          4.9         3.0          1.4         0.2  setosa      14.70       0.28
3          4.7         3.2          1.3         0.2  setosa      15.04       0.26
4          4.6         3.1          1.5         0.2  setosa      14.26       0.30
5          5.0         3.6          1.4         0.2  setosa      18.00       0.28

mutate関数とifelse関数を組み合わせて使うと、条件に合わせてラベルをつけるようなことが簡単にできます。以下に、irisデータのSepal.Lengthが平均より大きい条件と、Sepal.Lengthが平均より小さい条件とでラベルを割り振る例を示します。

R Console
> mean(iris$Sepal.Length) # Sepal.Lengthの平均値を計算
[1] 5.843333
> iris %>% # irisのデータを呼び出し、%>%を使って次の行のプログラムにデータを送る
+   dplyr::mutate(SL長さ=ifelse(Sepal.Length>mean(Sepal.Length),"SL長","SL短")) %>% # Sepal.Lengthの値がSepal.Lengthの平均値より長いという条件に合えば、"SL長"とラベルを付け、そうでなければ"SL短"というラベルを付ける。%>%を使って次の行のプログラムにデータを送る
+   dplyr::filter(Sepal.Length>5.7 & Sepal.Length<6.0) # 平均値周辺のラベル付け結果を確認するために、Sepal.Lengthが5.7より長く、かつ、6.0より短い条件に合致する行を絞り込んで表示する。
   Sepal.Length Sepal.Width Petal.Length Petal.Width    Species SL長さ
1           5.8         4.0          1.2         0.2     setosa   SL短
2           5.9         3.0          4.2         1.5 versicolor   SL長
3           5.8         2.7          4.1         1.0 versicolor   SL短
4           5.9         3.2          4.8         1.8 versicolor   SL長
5           5.8         2.7          3.9         1.2 versicolor   SL短
6           5.8         2.6          4.0         1.2 versicolor   SL短
7           5.8         2.7          5.1         1.9  virginica   SL短
8           5.8         2.8          5.1         2.4  virginica   SL短
9           5.8         2.7          5.1         1.9  virginica   SL短
10          5.9         3.0          5.1         1.8  virginica   SL長

また、cut関数と組み合わせて、例えば四分位で4分割し、それぞれにラベルを付ける時などに便利です。cut関数の設定方法については、こちら [4] にわかりやすいです。

R Console
> quantile(iris$Sepal.Width) # 四分位数を計算
  0%  25%  50%  75% 100% 
 2.0  2.8  3.0  3.3  4.4 
> iris %>% # irisのデータを呼び出し、%>%を使って次の行のプログラムにデータを送る
+   dplyr::mutate(SW=cut(Sepal.Width, breaks = c(quantile(Sepal.Width)), labels=c("細","中細","中太","太"),right=FALSE, include.lowest=TRUE)) %>% # 最大値、最小値と四分位数により4分割された範囲に、それぞれラベルを付け、%>%を使って次の行のプログラムにデータを送る
+   head(10) # 先頭の10行を表示
   Sepal.Length Sepal.Width Petal.Length Petal.Width Species   SW
1           5.1         3.5          1.4         0.2  setosa   太
2           4.9         3.0          1.4         0.2  setosa 中太
3           4.7         3.2          1.3         0.2  setosa 中太
4           4.6         3.1          1.5         0.2  setosa 中太
5           5.0         3.6          1.4         0.2  setosa   太
6           5.4         3.9          1.7         0.4  setosa   太
7           4.6         3.4          1.4         0.3  setosa   太
8           5.0         3.4          1.5         0.2  setosa   太
9           4.4         2.9          1.4         0.2  setosa 中細
10          4.9         3.1          1.5         0.1  setosa 中太

case_when関数を使えば、複数の条件それぞれに対応したラベルを付けることが可能です。~(ちるだ)の左に条件式、右に置換する値を書きます [5]。条件に含まれない場合はNAが返されるので、注意が必要です。

R Console
> iris %>% # irisのデータを呼び出し、%>%を使って次の行のプログラムにデータを送る
+   dplyr::mutate(SL=case_when( # SWという名前の列を作り、条件に従い、ラベルを付ける
+     Sepal.Length < quantile(Sepal.Length)[2] ~ "short", # 第一四分位数より小さい値をshortとする
+     Sepal.Length > quantile(Sepal.Length)[4] ~ "long", # 第三四分位数より大きい値をlongとする
+     Sepal.Length >= quantile(Sepal.Length)[2] & Sepal.Length <= quantile(Sepal.Length)[4] ~ "medium" # 上の2条件の間の範囲をmediumとする
+     )) %>% # %>%を使って次の行のプログラムにデータを送る
+   head(5) # 先頭の5行を表示
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species     SL
1          5.1         3.5          1.4         0.2  setosa medium
2          4.9         3.0          1.4         0.2  setosa  short
3          4.7         3.2          1.3         0.2  setosa  short
4          4.6         3.1          1.5         0.2  setosa  short
5          5.0         3.6          1.4         0.2  setosa  short

 

[1] Qiita – dplyrを使いこなす!基礎編

[2] 独学で始める統計×データサイエンス – 【2-2】Rのmutate関数を使って列の追加や修正を行う

[3] MilanoRAggregation with dplyr/ summarise and summarise_each

[4] 秩序と情報とブロッコリー – R言語のcut関数の使い方

[5] Quitadplyr::case_whenの使い方

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください