#contents
//間瀬茂 2003/7/13
//COLOR(red){SIZE(30){二項演算子定義の例}}
*二項演算子の定義 [#operator]
[[R:http://www.r-project.org/index.html]]には幾つかの二項演算子が(内部関数として)定義((既定で定義されている COLOR(red){%%},COLOR(red){%*%},COLOR(red){%/%},COLOR(red){%o%} を定義し直すこともできるがすすめられない。))されているが、自前で簡単に定義できる。こうした自前の定義をいつも使うには、スタートアップファイル COLOR(red){.Profile} を用意((このファイルは[[R:http://www.r-project.org/index.html]]の起動時に、必ずまず[[R:http://www.r-project.org/index.html]]の起動ディレクトリで捜され、そこになければユーザーのホームディレクトリで捜される。なければそれまで。))しておき、その中に書いておく。
構文は次のようになる:
"%name%" <- function (x, y) { x, y を使った演算} # 二重引用符が必要
C言語風演算子のエミュレート例 (但し、永続付値演算子を使っているので変数 x に関してスコープ問題が起きる可能性あり?):
> "%+=%" <- function(x, y) x <<- x + y
> x <- 3; x %+=% 4; x
[1] 7
> "%-=%" <- function(x, y) x <<- x - y
> x <- 3; x %-=% 2; x
[1] 1
> "%*=%" <- function(x, y) x <<- x*y
> x <- 3; x %*=% 4; x
[1] 12
> "%/=%" <- function(x, y) x <<- x/y
> x <- 3; x %/=% 2; x
[1] 1.5
%*=% のような定義は,正確にC言語と同じような演算になっていないので注意が必要。
> x <- 5
> y <- 3
> "%*=%" <- function(x, y) x <<- x * y
> x %*=% y+1
[1] 16
# しかも,
> x
[1] 15 # となっているから,始末が悪い
C言語では x *=y+1 は x = x*(y+1) になる。つまり,x は 16 でもなく,当然 15 ではなく 20 になるべきなのだから。
右辺を括弧でくくってやれば,当然だが期待される答えになる。しかし,そこまでしてこんな演算子を使いたくない。
> x %*=% (y+1)
> x
[1] 20
r-help 記事に次のような定義の仕方が紹介されていた。
> "%+=%" <- function(a, b) eval.parent(substitute(a <- a + b))
> "%-=%" <- function(a, b) eval.parent(substitute(a <- a - b))
> "%*=%" <- function(a, b) eval.parent(substitute(a <- a * b))
> "%/=%" <- function(a, b) eval.parent(substitute(a <- a / b))
この定義もだめだな。
こんなのも可能:
> "%foo%" <- function (x, ...) { # 引数 ... でベクトルを渡す
Data <- numeric(0)
for (i in 1:length(...)) Data[i] <- ...[i]
quantile(Data, prob=x)
}
> 0.2 %foo% runif(100)
20%
0.1561065
但し、二項演算子はやはり COLOR(magenta){左右、そして返り値が同質のオブジェクト} の場合に使うのが自然でしょう。
*参考記事 [#article]
-[[R言語プログラミング: 基本演算子・初等関数:http://d.hatena.ne.jp/hamadakoichi/20100209/p1]]
-[[R言語プログラミング: データ型・操作:http://d.hatena.ne.jp/hamadakoichi/20100118/1263832446]]