メモ:dplyrがStandard evaluationをdeprecatedにしようとしている理由
追記(2017/3/25):
「NSE/SEの組み合わせではなく、tidyevalで統一的に扱おうとしている」、という感じ? 正しい文章が思い浮かばない。
— Hiroaki Yutani (@yutannihilation) 2017年3月24日
追記(2017/4/7):
やはり「NSEをdeprecatedに」というのは間違いなのでタイトル修正しました。すみません。
だいぶ昔にこんな文章を書きました。
が、今、dplyrのNSEの文章を見ると
Non-standard evaluation is now handled with the tidy evaluation framework. Please see vignette(“programming”). (https://github.com/hadley/dplyr/blob/356146c1b5da3adc985454e0348b9d24dd74b8af/vignettes/nse.Rmd)
と書かれています。いったい何が…。
dplyrの欠点
その理由は、Programming with dplyr(まだ執筆中)というvignetteに書かれています。ここで持ち出されている「tidyeval」という概念はまだいろいろ揺れ動いていますが、問題意識自体はなるほどなあと思ったので先んじて紹介します。
引数は参照透過ではない
Most dplyr arguments are not referentially transparent.
参照透過でない、というのはつまり、このvignetteに例が上がっていますが、
filter(df, my_var == 1)
というのを
var <- my_var filter(df, var == 1)
とは書けないということです。これはdplyr初心者がよく陥る間違いであるようです。
解釈が一意に定まらない
dplyr code is ambiguous.
これは、
filter(df, x == y)
というコードがあったとして、グローバル環境にx
、y
変数があるかないかによって、以下のいずれかを表す可能性があります。
df[df$x == df$y, ] df[df$x == y, ] df[x == df$y, ] df[x == y, ]
これは、文脈抜きにはどれが正しいか判別できないし、エラーになるべきはずがx
やy
といった列名と同じ変数がたまたまグローバル環境にあることによってエラーにならない、といったことも起こってしまいます。
rlangの対応
これに対して、lazyevalパッケージの後継であるrlangパッケージは、以下のような対応を検討しています。
注:rlangのインターフェースはまだまだ発展途上なので、これは今後大幅に変化すると思います。ここに書いたことはすぐに古くなるのであまり信用しないでください
!!
、:=
これは某株式会社の公式アカウントが解説してくださるとの風の噂なので、ここではあまり触れません。mutate()
であれば以下のようにできます。
var <- "my_var" mutate(iris, !!var := 1)
filter()
はどうやるかよくわかりませんでした。たぶんこんな感じじゃないかと思ったんですがうまく動かなかったのでやはり某公式アカウントに見せ場を譲ります。
var <- "Species" filter(iris, !! ~var == "virginica")
追記(2017/3/25):rlang::sym
?
var <- rlang::sym("Species") filter(iris, (!! var) == "virginica")
.data
これは単純で、x
というシンボルがdplyrの関数中に出てきたときにそれがdf
の列x
なのかグローバル変数x
なのか分かりませんでしたが、.data$x
とすることで前者を明示できる、ということです。つまり、
filter(df, x == y)
は、
filter(df, .data$x == .data$y)
とすることで、データフレームdf
が列x
やy
を持たない場合は、グローバル環境に同名の変数があるかないかに関わらずエラーになります。パッケージ中でdplyrを使う場合はこういう感じに.data
を明示すべきでしょう。
まとめ
dplyrはけっこう変更が入ります。備えよう。
というとやばい変更ばっかり入る感じがしますが、Windowsユーザは喜んだ方がいいです。非ASCII文字の扱いが劇的に改善しています。
話している内容はあんまり理解できないんですが、西欧言語圏の人がここまで非ASCII文字の扱いに対して深く議論をして改善していくのには、最大限の敬意を表したい気持ちでいます。ほんとに、足を向けて眠れません。ありがたや。