この記事はR Advent Calendar 2022 3日目の記事です。昨日はhoxo-mさんの記事でした。温故知新でしたね。
さて、来年1月後半にリリース予定を控えたdplyr 1.1.0について、リリース前の新機能紹介が出ました。
今回はその中でも、summarise()
やmutate()
に追加されるという.by
引数について簡単に紹介します。
.by
引数とは?
これは、group_by()
の代わりに使えるものですが、コードを見てもらった方が早いと思うので↑の記事から引用します。
region
ごとにcost
の平均を求めたい場合、これまでdplyrでは、
expenses |> group_by(region) |> summarise(cost = mean(cost))
と書いていました(これまで、と書きましたがもちろんこれからもこれでもOKです)。
これが、group_by()
を使わずとも以下のように2行で書けるようになる、というのが今回の変更です。
expenses |> summarise(cost = mean(cost), .by = region)
要は、
- グループ化
- 何らかの処理
- グループ化解除
というのを一気にできるようになった、ということです。
.by
引数が使えるのは、summarise()
に限りません。mutate()
、filter()
、slice()
など、group_by()
に対応しているすべてのverbにこの引数が追加されています。例えば、「レコード数が30以上の manufacturer
のデータだけに絞り込み」という処理は、これまでだと
ggplot2::mpg |> group_by(manufacturer) |> # グループ化 filter(n() >= 30) |> # メインの処理 ungroup() # グループ化解除
だったのが、.by
を使うと以下のように2行で書けます。
ggplot2::mpg |> filter(n() >= 30, .by = manufacturer)
これまでの歴史
この「一時的にグループ化して処理を行う」というのは、dplyrの長年の課題というかペインポイントでした。 過去、これを改善するためにいくつかの試みがなされました。
例えば、dplyr 1.0.0で導入されたsummarise()
の.drop
引数もこのあたりに関連するものでした。
summarise()
がグループ化を完全に解除せずに1つだけ解除する、という挙動は初見殺しでしたが、
少なくともこれによってungroup()
が省略可能になりました。
# 1.0.0より前 data |> group_by(g1, g2, g3) |> summarise(total = sum(value)) |> ungroup() # 1.0.0以降 data |> group_by(g1, g2, g3) |> summarise(total = sum(value), .groups = "drop")
同じく1.0.0で追加されたもう一つとして、with_groups()
という関数もあります。これは、withrパッケージのようなインターフェースで、一時的にグループ化を設定して任意の処理を行います。
# 1.0.0以降 data |> with_groups(c(g1, g2, g3), \(x) summarise(x, total = sum(value)) )
ということで追加されたものの、なんかとっつきにくくてあまり使われていない印象があります。
このへんに比べると.by
は圧倒的にわかりやすいし、上述のようにsummarise()
の初見殺しを避けられるという安全性もあるので、.by
が人気になっていくのかな?という予感がします。
「それもうbase Rでよくね?」
という声もあります。この画像が言っていることは要は、「.by
引数でコードが短くなった!とか喜んでるけど、そもそもbase Rならaggregate()
で一発やねんで?」ということです。たしかに...
#RStats dplyr 1.1.0: Temporary grouping with .by pic.twitter.com/LjR37zoFNw
— Tokhir Dadaev (@zx8754) 2022年11月29日
個人的には、tidyverse派もようやくbase R派の考えてることがちょっとわかるようになったんだし、それはそれでいいのでは?と思うんですが、どうなんでしょうね。まあ今後もここの鍔迫り合いが何度かあるような気がするので、英語圏Rツイッター界隈をウォッチしていきたいと思います。
リリースが楽しみですね!
最後に
明日、R advent calendar 4日目はatusyさんの記事です。楽しみに待ちましょう。ちなみにアドカレまだまだ空きがあるので、書きたいことがある人、アドカレドリブンで学びたい人は決断的にエントリーだ!