S3 メソッドを使ってみる
http://d.hatena.ne.jp/syou6162/20080521/1211321228
をみて、Filter も で使えた方が一貫性があるし、Filter って書くよりも短いよね、と思ったので書いてみた。
演算子の動作を定義するには [ 関数を書き換えればいい。
[ 関数は呼び出す時には
"["(1:10,3)
と書けば呼べるけど、アクセスするときは ` を使って
> `[` .Primitive("[")
と書かないといけない。
関数かどうかの判定に class 関数を使って書くとこんな感じ。
`[` <- function(x,i,...) { if(class(i)=="function") Filter(i,x) else (.Primitive("["))(x,i,...) }
動作確認
> (1:10)[function(x) x > 4] [1] 5 6 7 8 9 10 > x <- 1:10 > x[x > 4] [1] 5 6 7 8 9 10
これでも動くけど、どうせなら最近覚えた S3 とやらを使ってみる。
この S3 は print や plot なんかで、与えられたデータに合わせた関数を呼び出す仕組みのようだ。
仕組みは簡単で UseMethod(generic, object) 関数を使うと「"generic"."objectのクラス名"」の関数を呼び出してくれる。
`[` <- function(x, i, ...) UseMethod("[", i) `[.default` <- .Primitive("[") `[.function` <- function(x,f) Filter(f,x) > (1:10)[function(x) x > 5 && x < 7] [1] 6 > x <- 1:10; x[x > 5 & x < 7] [1] 6
関数は function クラスなので、上の場合 i が関数だと [.function それ以外では [.default を呼び出す。
作ってはみたけど、function て書くのが長いな。単にS3を使ってみたかっただけだし、いっか。