Rにおけるマクロの使用
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
検索
|
最終更新
|
ヘルプ
]
開始行:
COLOR(red){SIZE(30){R でマクロを実現する関数}}
// 間瀬 2003/7/11
次の関数 COLOR(red){defmacro} はパラメータ付きのマクロを定義する。C 言語に慣れ
た人には便利かも知れない。この関数の本来の目的は、~
複数の関数で(幾つかのパラメータ値を除いて)同一の部分をマクロにしておき、コードを簡潔かつ統一的にすることである。
注:マクロは実行時に定義内容がコード中にまず展開され、その後実行される。
#contents
*関数のコード
defmacro <- function(..., expr) {
# ... には任意個のパラメータ引数 (零個不可)、expr には R の表現式
# by T. Lumley, in "Macros in R" in Rnwes, Vol. 1/3, Sep. (2001) より
# 使用例
# mcr <- defmacro(x, y, expr=x*exp(y)) # パラメータ x, y を持つマクロ定義
# foo <- function (x) x*mcr(2, 3) # foo は x*2*exp(3) になる
#
expr <- substitute(expr)
a <- substitute(list(...))[-1]
nn <- names(a)
if (is.null(nn)) nn <- rep("", length(a))
for (i in seq(length = length(a))) {
if (nn[i] == "") {
nn[[i]] <- paste(a[[i]])
msg <- paste(a[[i]], "not supplied")
a[[i]] <- substitute(stop(foo), list(foo = msg))
}
}
names(a) <- nn
a <- as.list(a)
ff <- eval(substitute(
function () {
tmp <- substitute(body)
eval(tmp, parent.frame())
}, list(body = expr)))
formals(ff) <- a
mm <- match.call()
mm$expr <- NULL
mm[[1]] <- as.name("macro")
attr(ff, "source") <- c(deparse(mm), deparse(expr))
ff
}
*使用例
> mcr <- defmacro(a, expr=readline("Input a number -> ")) # a はダミーパラメータ
> mcr(0) # パラメータ 0 は無意味
Input a number -> 3
[1] "3"
> foo <- function (x) x + as.numeric(mcr(0)) # mcr(0) の返す値は文字列なので数値化
> foo(4)
Input a number -> 5
[1] 9 # 4 + 5
> mcr <- defmacro(x, y, expr=exp(x)*sin(y)) # パラメータが二個のマクロ
> mcr # マクロの定義内容
macro(x, y)
exp(x) * sin(y)
<environment: 0x9065944>
> mcr(2, 3) # マクロを単独で実行(まるで関数そのものに見える)
[1] 1.042744
> foo <- function (x) x*mcr(2, 3)
> foo(1)
[1] 1.042744 # 1*exp(2)*sin(3)
> mcr <- defmacro(i, j, k, expr=i*(j+k))
> mcr(2,3,4)
[1] 14
これだけなら関数で足りること。マクロでなくちゃというもう少し気の効いた例はないものか?
*コメント 1
次の例は,関数を使わない方が好ましい例かもしれません。
こんなことをしなくてもと思う場合には,
jugemujugemugokounosurikire <- jugemujugemugookounosurikire*(kaijarisuigyo+3)
みたいな例((左辺の変数は右辺の長い変数と同じつもりをタイプミスした例))をわざわざ挙げたり。
C 言語みたいに +<-,-<-, *<-, /<- みたいなの((C 言語などでは, x *= y+1 は,x = x*(y+1) と同じことを表す代入演算子))があれば((割り込みコメント。[[二項演算子定義の例]] を参照して下さい。))いいのだけど。
> mul <- defmacro(x, y, expr=x <- x*(y))
> x <- 2
> y <- 4
> mul(x, y+1)
> x
[1] 10
終了行:
COLOR(red){SIZE(30){R でマクロを実現する関数}}
// 間瀬 2003/7/11
次の関数 COLOR(red){defmacro} はパラメータ付きのマクロを定義する。C 言語に慣れ
た人には便利かも知れない。この関数の本来の目的は、~
複数の関数で(幾つかのパラメータ値を除いて)同一の部分をマクロにしておき、コードを簡潔かつ統一的にすることである。
注:マクロは実行時に定義内容がコード中にまず展開され、その後実行される。
#contents
*関数のコード
defmacro <- function(..., expr) {
# ... には任意個のパラメータ引数 (零個不可)、expr には R の表現式
# by T. Lumley, in "Macros in R" in Rnwes, Vol. 1/3, Sep. (2001) より
# 使用例
# mcr <- defmacro(x, y, expr=x*exp(y)) # パラメータ x, y を持つマクロ定義
# foo <- function (x) x*mcr(2, 3) # foo は x*2*exp(3) になる
#
expr <- substitute(expr)
a <- substitute(list(...))[-1]
nn <- names(a)
if (is.null(nn)) nn <- rep("", length(a))
for (i in seq(length = length(a))) {
if (nn[i] == "") {
nn[[i]] <- paste(a[[i]])
msg <- paste(a[[i]], "not supplied")
a[[i]] <- substitute(stop(foo), list(foo = msg))
}
}
names(a) <- nn
a <- as.list(a)
ff <- eval(substitute(
function () {
tmp <- substitute(body)
eval(tmp, parent.frame())
}, list(body = expr)))
formals(ff) <- a
mm <- match.call()
mm$expr <- NULL
mm[[1]] <- as.name("macro")
attr(ff, "source") <- c(deparse(mm), deparse(expr))
ff
}
*使用例
> mcr <- defmacro(a, expr=readline("Input a number -> ")) # a はダミーパラメータ
> mcr(0) # パラメータ 0 は無意味
Input a number -> 3
[1] "3"
> foo <- function (x) x + as.numeric(mcr(0)) # mcr(0) の返す値は文字列なので数値化
> foo(4)
Input a number -> 5
[1] 9 # 4 + 5
> mcr <- defmacro(x, y, expr=exp(x)*sin(y)) # パラメータが二個のマクロ
> mcr # マクロの定義内容
macro(x, y)
exp(x) * sin(y)
<environment: 0x9065944>
> mcr(2, 3) # マクロを単独で実行(まるで関数そのものに見える)
[1] 1.042744
> foo <- function (x) x*mcr(2, 3)
> foo(1)
[1] 1.042744 # 1*exp(2)*sin(3)
> mcr <- defmacro(i, j, k, expr=i*(j+k))
> mcr(2,3,4)
[1] 14
これだけなら関数で足りること。マクロでなくちゃというもう少し気の効いた例はないものか?
*コメント 1
次の例は,関数を使わない方が好ましい例かもしれません。
こんなことをしなくてもと思う場合には,
jugemujugemugokounosurikire <- jugemujugemugookounosurikire*(kaijarisuigyo+3)
みたいな例((左辺の変数は右辺の長い変数と同じつもりをタイプミスした例))をわざわざ挙げたり。
C 言語みたいに +<-,-<-, *<-, /<- みたいなの((C 言語などでは, x *= y+1 は,x = x*(y+1) と同じことを表す代入演算子))があれば((割り込みコメント。[[二項演算子定義の例]] を参照して下さい。))いいのだけど。
> mul <- defmacro(x, y, expr=x <- x*(y))
> x <- 2
> y <- 4
> mul(x, y+1)
> x
[1] 10
ページ名: