2014-12-04
R にラムダ式を導入するパッケージ lambdaR を作った
※この記事は R Advent Calendar 2014 - Qiita の 4 日目の記事です。
いくつかのプログラミング言語には、無名関数を生成する方法として、ラムダ式が用意されています。
例えば、
# Python increment = lambda x: x + 1
// Scala def increment = (x: Int) => x + 1
などです。
ラムダ式は、無名関数をダイレクトに表現することができるため、プログラムの記述が容易になり、可読性も上がります。
ところが、R にはラムダ式はありません。
このように便利なラムダ式を R に導入できないでしょうか?
というわけで、作りました。
lambdaR は、R にラムダ式を導入するためのパッケージです。
次のようにしてインストールできます。
install.packages("devtools") # devtools をインストールしていない場合のみ devtools::install_github("hoxo-m/lambdaR")
このパッケージで定義される lambda() は、ラムダ式を関数に変換する関数です。
increment <- lambda(x: x + 1) add <- lambda(x,y: x + y)
ラムダ式は、上記のように、 や
のように、Python ライクに記述します。
この lambda() 関数を使うことにより、ラムダ式を入力として持つ高階関数(関数を入力として持つ関数)を作ることができるようになります。
lambdaR パッケージでは、適用例として、このようなラムダ式を入力として持つ高階関数が 6 つ定義されています。
- Filter_()
- Map_()
- Reduce_()
- Find_()
- Position_()
- Negate_()
これらの関数の詳細については、下記サイトを参考にして下さい。
これらの関数だけでなく、関数を入力とする関数ならば、ラムダ式を入力としたものとして再定義することができます。
例えば、Filter_() は、入力されたベクトルのうち、ラムダ式で指定された関数が TRUE を返す値のみを返します。
# 偶数のみを返す Filter_(1:10, x: x %% 2 == 0)
2 4 6 8 10
また、Map_() は、入力されたベクトルのそれぞれの値に対して、関数を適用したベクトルを生成します。
# 二乗した値を返す Map_(1:5, x: x ** 2)
1 4 9 16 25
このような関数と dplyr のパイプ演算子 %>% を組み合わせると、次のように書くことができます。
library(lambdaR) library(dplyr) 1:10 %>% Filter_(x: x %% 2 == 0) %>% Map_(x: x ** 2)
4 16 36 64 100
普通に書いた場合との記述量、可読性を比べてみてください。
# dplyr 不使用 Map(function(x) x ** 2, Filter(function(x) x %% 2 == 0, 1:10) # dplyr 使用 1:10 %>% Filter(function(x) x %% 2 == 0, .) %>% Map(function(x) x ** 2, .)
ラムダ式を使うと、このような記述がすっきりすることがわかると思います。
プレースホルダ
lambdaR では、Scala で使えるプレースホルダを使うこともできます。
1:10 %>% Filter_(._ %% 2 == 0) %>% Map_(._ ** 2)
プレースホルダにより、より簡潔にラムダ式を記述することができます。
まとめ
lambdaR パッケージにより、R におけるラムダ式への道が開けました。
より詳しい使い方については、下記ページを参照して下さい。
以上です。