dplyr とは何か
dplyr は R で最も人気のあるデータ操作パッケージであり、少数の 動詞(verbs) から成る「データの文法」です。各動詞はデータフレームを受け取り、ちょうど 1 つの仕事(行を絞る、列を追加する、グループの要約を計算する)を行い、新しいデータフレームを返す関数です。すべての動詞が同じ形 — データフレームが入り、データフレームが出る — をしているので、パイプで組み合わせると、レシピのように上から下へ読めるパイプラインになります。dplyr はこの設計を共有するパッケージ群(tidyr、ggplot2、readr)である tidyverse の中核です。
dplyr にできることは、base R にもできます。純粋な base R による小さな分析を見てみましょう — 組み込みの mtcars データを 4 気筒の車に絞り、新しい列を計算し、ギア数ごとに平均を取ります。これは実行できます。
これは動きますし、良い R です。しかし、物語が括弧による添字付け、$ への代入、そして式(formula)にまたがって塗り広げられていることに注目してください。同じ分析の dplyr 版はこうなります。
library(dplyr)
mtcars |>
filter(cyl == 4) |>
mutate(kml = mpg * 0.425) |>
group_by(gear) |>
summarize(avg_kml = round(mean(kml), 1))
4 つの動詞が、口に出して説明するのと同じ順序で並んでいます。この読みやすさこそが売り文句のすべてであり、20 段階のパイプラインでは決定的です。
このページの dplyr のスニペットが静的なのは、このエディタが base R しか実行しないためです。実行するには、次に示す手順で自分のマシンに dplyr をインストールしてください。
インストールと読み込み
1 回インストールし、その後は使用するすべてのスクリプトで読み込みます。
install.packages("dplyr") # once, per machine
library(dplyr) # every script
代わりに install.packages("tidyverse") をインストールすると、dplyr と兄弟パッケージがまとめて入ります。dplyr を読み込むと stats::filter と stats::lag をマスクするという警告が出ますが、これは正常であり、エラーではありません。
6 つの中核となる動詞
すべての動詞は第 1 引数にデータフレームを取り、列名は引用符も df$ の接頭辞もない 裸の 形で受け取ります。
filter() は条件に一致する行を残します。
mtcars |> filter(mpg > 25)
mtcars |> filter(cyl == 4, hp < 70) # comma = AND
select() は名前、範囲、ヘルパーで列を残します。
mtcars |> select(mpg, cyl, hp)
mtcars |> select(mpg:hp) # a range of adjacent columns
mtcars |> select(starts_with("d")) # disp, drat
mutate() は列を追加または変換します。
mtcars |> mutate(kml = mpg * 0.425, heavy = wt > 3.5)
arrange() は行を並べ替えます — 降順にするには列を desc() で包みます。
mtcars |> arrange(desc(mpg))
summarize() は行を 1 つの要約行にまとめ、group_by() はそれをグループごとのまとめに変えます。
mtcars |>
group_by(cyl) |>
summarize(n = n(), avg_mpg = mean(mpg))
group_by() は単独では目に見える変化を起こしません — 次の summarize()(または mutate())がグループ単位で動くように、データフレームに印を付けるだけです。各動詞にはこの章に詳細なドキュメントがあります: 行の絞り込み、列の追加、並べ替え、グループ集計。
パイプで動詞をつなぐ
パイプ |> は手前の値を受け取り、後ろの関数の第 1 引数として渡します — x |> f(y) は f(x, y) を意味します。すべての dplyr の動詞はデータフレームを受け取って返すので、動詞はいくらでも連鎖できます。
mtcars |>
filter(hp > 100) |>
mutate(kml = mpg * 0.425) |>
group_by(cyl) |>
summarize(cars = n(), avg_kml = round(mean(kml), 1)) |>
arrange(desc(avg_kml))
声に出して読んでみましょう。mtcars を取り、100 馬力を超える車を残し、リッターあたりキロメートルの列を追加し、気筒数でグループ化し、各グループを数えて平均し、平均で並べ替える。中間変数も入れ子もありません。古いコードでは |> の代わりに magrittr パッケージの %>% を使います — dplyr の作業では交換可能で、|>(R 4.1 以降に組み込み)は パイプのドキュメント で扱っています。
count() と n(): 数えるためのヘルパー
数える作業はあまりに一般的なので、dplyr にはショートカットがあります。n() は現在のグループの行数を返し(summarize() または mutate() の内部でのみ有効)、count() は group_by() + summarize(n = n()) という一連の手順を 1 回の呼び出しにまとめます。
mtcars |> count(cyl) # rows per cyl value
mtcars |> count(cyl, gear, sort = TRUE) # two groupers, biggest first
group_by(x) |> summarize(n = n()) と書いている自分に気づいたら、count(x) に置き換えましょう。
tibble についての補足
dplyr の動詞はしばしば tibble を返します — データフレームに対する tidyverse の変種です。これはデータフレーム そのもの であり(データフレームを受け取るものはすべて tibble も受け取ります)、表示がより親切です。最初の 10 行だけ、収まる列だけを表示し、各名前の下に型が示されます。知っておく価値のある違いが 2 つあります。tibble は行名を一切使いません(mtcars |> as_tibble() で車名が失われるのはこのためです — tidyverse は識別子が本物の列にあることを期待します)。また、角括弧 1 つの添字付けは常に tibble を返し、ときどきベクトルに落ちるということがありません。どちらも日常的に驚くべきものではありません。str() が tbl_df と言っても慌てないでください。
この記事のまとめ
- dplyr は文法です。6 つの動詞がそれぞれデータフレームに 1 つの仕事をし、パイプでつながれます。
filter()は行を選び、select()は列を選び、mutate()は列を追加し、arrange()は並べ替え、group_by() + summarize()は集計します。x |> f(y)はf(x, y)です — パイプラインは物事が起こる順に上から下へ読めます。count()とn()は数える用途のほとんどをカバーします。- base R でもすべてできます。dplyr はパイプラインが大きくなったときの読みやすさで勝ります。
次は 絞り込みと部分抽出の詳細 — base R の括弧の定型句と、dplyr の filter() がどこに収まるかを見ていきます。
よくある質問
R の dplyr とは何ですか?
dplyr はデータフレームを操作するための最も広く使われている R パッケージです。filter()、select()、mutate()、arrange()、summarize()、group_by() という少数の動詞を提供し、それぞれがデータフレームに対して 1 つのことを行い、パイプでつないで読みやすいパイプラインになります。tidyverse の一部です。
dplyr はどうやってインストールしますか?
install.packages("dplyr") を 1 回実行し、その後は使用するすべてのスクリプトの先頭で library(dplyr) を書きます。代わりに tidyverse をインストールすると、dplyr と兄弟パッケージ(tidyr、ggplot2、readr)が一度に手に入ります。
dplyr は必要ですか、それとも base R で十分ですか?
base R は dplyr にできることをすべてできます — 部分抽出、aggregate()、order() など — そして依存関係ゼロでどこでも動くので、知っておく価値があります。dplyr がインストールに値するのはパイプラインが長くなったときです。5 つの動詞を連ねたものは文のように読めますが、base の等価物は入れ子の括弧パズルのように読めます。
dplyr の summarize と summarise の違いは何ですか?
ありません。米国式と英国式の綴り違いの同じ関数で、dplyr は両方をエクスポートしています。チームで使っている方を使い、一貫させましょう。