function の置き換え

毎回 function と書くのは面倒くさいので、楽に書けるように置き換えてみた。

f <- function(...,b){
  ab <- substitute(c(...))
  if (length(ab) < 3 && !hasArg(b)) stop("2引数以上または'b'引数を指定して下さい")
  if (hasArg(b)) {
    a <- ab
    b <- substitute(b)
  }else{
    len <- length(ab)
    a <- ab[-len]
    b <- ab[[len]]
  }
  da <- sub("c","",deparse(a))
  db <- paste(deparse(b), collapse=";")
  eval.parent(parse(text=paste("function", da, db, sep="")))
}

deparse して形を整えて eval する、っていうことをやってる。
結構むだなことをしている感じ。

使い方

# 一番最後の引数が expr になる。
> square <- f(x, x^2)
> square(11)
[1] 121
# 名前つき引数で明示的にも指定できる
# square <- f(x, b=x^2)

# 引数なしの関数を作るときは、名前つき引数で指定
> f1 <- f(b=10)
> f1()
[1] 10

# 変数束縛もしてる
> f2 <- f(x, f(y, x+y))
> f3 <- f2(10)
> f3(5)
[1] 15
> f3(3)
[1] 13

# 複数行も"{}"で囲めばできる
> f4 <- f(x,y,{
+ l <- x:y
+ l + x
+ })
> f4(1,3)
[1] 2 3 4

# sapply とかで使うと、こんな感じ
> sapply(1:10, f(x,x+10))
[1] 11 12 13 14 15 16 17 18 19 20

感想
ちょっとした無名関数をつくるときに便利になった。
エラー処理をやってないから、関係ないエラーが出やすくなった。