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

Rとヨーダ記法

R dplyr

ヨーダ記法(Yoda conditions)ということばがあります。

Wikipediaの例で言うと、

if ( $value == 52 ) { /* ... */ }

みたいに変数と定数を比較する条件を書きたいところで==(比較)と=(代入)を間違えて、

if ( $value = 52 ) { /* ... */ }

と書いてしまって、でも文法上は問題ないのでエラーにならない、みたいなことは、変数と定数を逆にしとけば安心!というテクニックです。

なぜかというと定数に代入はできないからで、これはOKですが、

if ( 52 == $value ) { /* ... */ }

これはちゃんとエラーにしてくれます。

if ( 52 = $value ) { /* ... */ }

けどまあそれ読みにくくない?という批判がよくされます。そのへんの議論はなんか闇が深そうなので立ち入らないことにします。

Rの場合

Rでも当然同じことが起こります。

ただ、if文を使うこと自体も少ないし、if文で==で定数と比較して判定するよりは、is.XXX()みたいな関数でやることも多いので、 他の言語と比べると問題になるケースはそこまでないのでは?という気もします。

あと細かい話。

subset

こんな感じでsubsetしたいところを、

library(dplyr)
subset(iris, Species == 'virginica') %>% nrow
#> [1] 50

===を間違えてもなぜかsubset()はすんなり通してしまいます。まったくsubsetされてません。(Speciesという変数ができるわけではなく、何が起こってるかは謎です…)

subset(iris, Species = 'virginica') %>% nrow
#> [1] 150

filter

でもこんなこときも、dplyr::filter()を使えば、エラーを出してくれます。

filter(iris, Species = 'virginica')
#> Error: incompatible expression in filter

[

...とか書いてて、[は?と思ったので調べてみると、こっちはちゃんとエラーになりました。

iris[iris$Species = 'virginica', ]
#> Error: unexpected '=' in "iris[iris$Species ="

括弧をつけてるとエラーは出ませんが、まあさすがにこれは意図したものではないと気づくでしょう。

iris[(iris$Species = 'virginica'), ]
#>    Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#> NA           NA          NA           NA          NA    <NA>

まとめ

May the force()4th be with you!