Rの%>%を理解したい
Rを楽しむための道のりの一つには
「中置関数と仲良くする」というステップがあると思います。
多くの方が恩恵を受けているであろうtidyverseの中にある、
中置関数の一つパイプ(%>%)に関し、
以前こんな記事
を書いてみたのですが、
その頃よりちょっぴり書きたいネタが増えてしまいました。
そこで今回は%>%を実際に作る過程を通じて
中置関数を楽しんでもらいたいなと思います。
実際のコード
最も単純にパイプを表現すると以下の式になると思います。
普通に読むと'%>%'は引数にaとfをとって、
f(a)を返す関数だよ、と言っています。
'%>%' <- function (a,f) f(a)
ここでのミソは2つあります。
1つは左辺、LHS(上の'%>%'側)の制約で、
記号を%で挟むのが作法であるようです。
そしてそれをクウォート('')してあげます。
もう1つは項のとり方で、
適用する際はfunction関数の第一引数を左にとり、
第二引数を右に取ります。
何を言っているんだ、という場合は次の例でスッキリするかもしれません。
iris %>% head
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 5.1 3.5 1.4 0.2 setosa
## 2 4.9 3.0 1.4 0.2 setosa
## 3 4.7 3.2 1.3 0.2 setosa
## 4 4.6 3.1 1.5 0.2 setosa
## 5 5.0 3.6 1.4 0.2 setosa
## 6 5.4 3.9 1.7 0.4 setosa
上を見ると、確かに
先ほど定義した中置関数(%>%)の左側にirisデータを置いて
右側にhead関数を置くと、
head(iris)の意味になることになります。
pipeの何が嬉しいのか
R界隈で今更(というと使っていない方に失礼ですが)pipeの
ありがたさを伝える意味はなさそうです。
が、一応説明すると、以上の%>%を使うと
関数の組み合わせの見通しが良くなります。
まずデータaに対して関数fと関数gを
適用するためにはg(f(a))とせねばなりません。
しかし a %>% f %>% g とかくと
「あぁaをfに入れてgに入れたのか」と分かります。
その他の中置関数の使い方
その便利さは語っても語りきれませんが、
列にアクセスするdf$colも中置換数であることを
思い出すと極めて稀に美味しいことがおきます。
例えば$も中置関数なので、
以下のように通常の呼び出し方ができます。
"$"(iris,Species)
これと先ほどの話を組み合わせてみます。
先ほど作ったのは項を一つしかとらない関数に限定
されているので、もっと柔軟な関数として
magrittrパッケージの%>%を借ります。
library(magrittr)
# さっき作ったのは上書きする
"%>%" <- magrittr::"%>%"
iris %>% "$"(Species)
するとirisのSpecies列へアクセスできます。
これが一体なんの役に立つかというと、
パイプを切らせたくない時、です。
データをガチャガチャしたあとで選択、
とかだと、わけても可読性が上がるわけでもないのに加えて
一時変数が増えるデメリットがあります。
iris %>% 長い操作 %>% "$"(Species)
あるいは apply系なんかにも中置関数使えますね!
mapply("*",c(1,2,3),c(1,2,3))
# 当然、以下だとエラーになる。
# mapply(*,c(1,2,3),c(1,2,3))
# エラー: 予想外の '*' です in "mapply(*"