ggplot2 3.2.0からfacet_grid()、facet_wrap()がNULLを受け付けるようになった

ggplot2 3.2.0がリリースされてはや1カ月ちょっと。おそらくみんなが気付いていないマイナーな変更の一つに、

facet_wrap() and facet_grid() now automatically remove NULL from facet specs, and accept empty specs (@yutannihilation, #3070, #2986).

(https://ggplot2.tidyverse.org/news/index.html#minor-improvements-and-bug-fixes)

というものがあります。具体的にはこんな感じで、facet_grid()+しているのに、あたかもfacetがないかのごとく単一のプロットが描かれます。

library(ggplot2)
ggplot(mpg, aes(displ, hwy)) + geom_point() + facet_grid()

Created on 2019-07-12 by the reprex package (v0.3.0)

「...で?」という感じだと思いますが、これは、facetで分割してプロットしたいけど分割に使う変数がいくつあるかわからない、みたいなときに便利です。 たとえば、

do_plot <- function(data, x, y, ...) {
  grouping_vars <- enquos(...)
  # !!enquo(x) のナウい書き方
  mapping <- aes(x = {{ x }}, y = {{ y }})

  # グループ化する変数が1つ以上なら colour にマッピングする
  if (length(grouping_vars) > 0) {
    mapping$colour <- grouping_vars[[1]]
  }

  ggplot(data, mapping) +
    geom_point() +
    facet_wrap(grouping_vars[-1])
}

というdo_plot(データ, xの変数名, yの変数名, グループ化に使う変数名1, ...)のように使用する関数が書けます。 グループ分けに使う変数を足していくと、それに応じて色にマッピングされたりプロットが分割されたりします。

do_plot(mpg, displ, cyl)

do_plot(mpg, displ, cyl, drv)

do_plot(mpg, displ, cyl, drv, manufacturer)

こういう、 aes()facet_*() を縦横無尽に行ったり来たりする関数を書いておくと、「colourとfacetを入れ替えたい!」みたいなときも変数を入れ替えるだけでいけて便利です。

do_plot(mpg, displ, manufacturer, drv, cyl)

あんまり使うことはないと思いますが、機会があれば思い出してやってください。