読者です 読者をやめる 読者になる 読者になる

dplyrのmutate_each()/summarise_each()とSE版の関数(select_()、mutate_()...)はdeprecatedになります

という話をTokyo.Rでしたらなんか意外と衝撃を受けている人が多かったので個別に記事に書いておきます。あわせて、移行方法について紹介したCompatibilityというvignetteがあるので、それの該当箇所をポイントします。

0.6.0の変更点全体については以下の記事に書いたので興味がある方はそちらもご参照ください。

mutate_each()summarise_each()

この2つは0.5.0(現行バージョン)の時点で将来的にdeprecatedにすることが予告されています*1

A new family of functions replace summarise_each() and mutate_each() (which will thus be deprecated in a future release).
(http://dplyr.tidyverse.org/news/index.html#new-functions)

移行方法はこのあたりです:http://dplyr.tidyverse.org/articles/compatibility.html#deprecation-of-mutate_each-and-summarise_each

_each()の代わりに_all()_at()を使いましょう、というのが要約です。

_each()には、

  1. mutate_each(starwars, funs(as.character))のように列を指定せずすべての列に対して関数を適用する
  2. mutate_each(starwars, funs(as.character), height, mass)指定した列に対して関数を適用する

という二通りの書き方がありました。

前者のすべての列に適用するパターンは、_all()を使って以下のように書けます。単一の関数を指定するだけならfuns()はなくても大丈夫です。

mutate_all(starwars, funs(as.character))
mutate_all(starwars, as.character)

後者の指定した列に適用するパターンは、_at()を使って以下のように書けます。これは順番が変わるのでちょっと覚えづらいかもしれません。

mutate_at(starwars, vars(height, mass), as.character)

_all()_at()はもっといろいろ使い方がありますが、それについてはdplyr再入門(Colwise編) // Speaker Deckに書いたのでそっちを読んでください。

SE版の関数(select_()mutate_()…)

これは0.6.0(次期バージョン)でdeprecatedになります。

移行方法はこのあたりです:http://dplyr.tidyverse.org/articles/compatibility.html#deprecation-of-underscored-verbs_

ここに書かれているのは、SEを使わなくてもtidyevalを使えばNSEで全部扱えるようになった、という話です。_each()のように簡単には置き換えられないので地道に勉強していきましょう。tidyevalについてはdplyr再入門(Tidyeval編) // Speaker Deckに書いたのでそっちを読んでください。

個人的によくわからなかったのは、

Finally, and perhaps most importantly, strings are not and should not be parsed. As developers, it is tempting to try and solve problems using strings because we have been trained to work with strings rather than quoted expressions. However it’s almost always the wrong way to approach the problem.

というあたりです。このあとで、symbolをつくるのは問題ない。だがcall、てめーはだめだ。みたいなことが書かれているんですが、この「quasiquotation」という概念についてちょっと理解があやしいくてよくわかりませんでした。

感想

_each()は実は知られてないけど割と前からdeprecatedにするぞポーズを見せていたということで、意外と早く消されてしまうかもしれません。この辺のスピード感はよくわかりませんが、例えば、rbind_all()rbind_list()bind_rows)()の前身)は0.5.0でdeprecatedになって0.6.0で完全に消されます。

After a period of deprecation, rbind_list() and rbind_all() have been removed from the package. Please use bind_rows() instead.
(http://dplyr.tidyverse.org/news/index.html#deprecated-and-defunct-functions)

その間だいたい1年くらいです。

SE版の関数については、

This means that the underscored version of each main verb is no longer needed, and so these functions have been deprecated (but remain around for backward compatibility).
(https://github.com/tidyverse/dplyr/releases/tag/v0.6.0-rc)

とあるので、なくなると影響が大きいことは羽鳥も認識しています。まだしばらくは残るでしょう。とはいえ、内部実装がどこまで保たれるかは怪しいところがあります。例えばsfパッケージは互換性が壊れたのでsfパッケージ側で対応が必要でした。

無事でいられるかあやしいので、できるならなるべく早めに移行しましょう(といってもまだリリースされてないけど)。

*1:でもdeprecatedになったという宣言はまだなので実はまだdeprecatedではない…? 「deprecated」と「将来的にdeprecated」というのの違いとは…