言語オブジェクト
Rの言語オブジェクトについてまとめてみました.
『Rプログラミングマニュアル』(間瀬茂, 2007年, 数理工学社) を参考にしました.
言語としてのRの基礎や,豊富な役立つtipsが載っており,とても参考になる本です.
言語オブジェクト
型
Rの言語オブジェクトには3つの型がある.呼び出し call,表現式 expression,名前 name である.呼び出しオブジェクトは関数名と引数を与えてつくる.
作成したオブジェクトは,eval()関数で評価実行できる.
> c1 <- call("round", 2.4) > c1 round(2.4) > eval(c1) [1] 2
quote()関数によって表現式オブジェクトを呼び出しに変換できる.引数は,eval()関数を用いたとき,またはオブジェクトをデータとして扱ったときに,はじめて評価される.substitute関数と異なり,quote関数は含まれる引数を評価しないで構文木を返す.
> q1 <- quote(sum(2, 4)) > q1 sum(2, 4) > is.call(q1) [1] TRUE > eval(q1) [1] 6
as.call()関数はリストを呼び出しに変換する.as.list()関数はその逆.
> f <- sum > A <- c(1, 3) > (g <- as.call(list(f, quote(A)))) .Primitive("sum")(A) > eval(g) [1] 4 > as.list(g) [[1]] function (..., na.rm = FALSE) .Primitive("sum") [[2]] A
リストにcallモードを与えても同じことができる.
> g <- list(f, quote(A)) > eval(g) [[1]] function (..., na.rm = FALSE) .Primitive("sum") [[2]] A > mode(g) <- "call" > eval(g) [1] 4
呼び出しはリスト風の構造をしている.
> q2 <- quote(sum(1, 2)) > q2[[1]] sum > q2[[2]] [1] 1 > q2[[3]] [1] 2 > q2[[1]] <- c > eval(q2) [1] 1 2
呼び出しの各成分は名前オブジェクトで置き換えられる.
> q3 <- quote(plot(x, y)) > q3[[1]] plot > q3[[1]] <- as.name("+") > q3 x + y
代入
substitute(expr, env)関数は,環境envに拘束された変数を代入した表現式exprに対する構文木を返す.plot()の軸ラベルなどを生成する際に,評価された実引数の値ではなく,実引数を生成する式が表示されるのは,このはたらきによる.結果は通常,逆構文解析関数であるdeparse()で文字列に変換され,使われる.
> f1 <- function(x){ + cat(x, fill = TRUE) + cat(deparse(substitute(x)), fill = TRUE) + } > f1(rnorm(2)) 1.829917 -0.07375462 rnorm(2)
substitute()関数は,スロットに記録された予約オブジェクトの中身を取り出している (c.f. 遅延評価).
envirに環境やリストを指定すると,その中で変数が検索され,あれば代入される.
> # envirにリストを指定 > (A <- substitute(expression(a + b), list(a = 1, b = 2))) expression(1 + 2) > eval(eval(A)) [1] 3 > # シンボルを変更 > (B <- substitute(expression(a + b), list(a = 1, b = quote(c)))) expression(1 + c) > eval(eval(B)) 以下にエラー 1 + c : 二項演算子の引数が数値ではありません > # cは関数c()とされる > (C <- substitute(expression(a + b), list(a = 1, b = c))) expression(1 + .Primitive("c")) > eval(eval(C)) 以下にエラー 1 + .Primitive("c") : 二項演算子の引数が数値ではありません > # シンボルに値を代入 > d <- 3 > (D <- substitute(expression(a + b), list(a = d, b = 2))) expression(3 + 2) > eval(eval(D)) [1] 5
代入は形式的で,意味を持つかどうかはチェックされない.
遅延評価により,代入式が評価された時点で値が代入されるので,以下のような事態が起こる.
> f1 <- function(y, main = deparse(substitute(y))){ + y <- log(y) + plot(y, main = main) # ここでmainが評価される + } > f2 <- function(y, main = deparse(substitute(y))){ + main # ここでmainが評価されてしまう + y <- log(y) + plot(y, main = main) + } > f1(1:3) > f2(1:3)
呼び出しの即実行
do.call(what, args)関数は,関数名whatと引数リストargsをもとに関数呼び出しを構成し,実行する.lapply()関数との違いは,lapplyはリストの各成分ごとに関数whatを適用して,リストとして結果を返す点.> (x <- data.frame(A = 1:3, B = -1, C = 0)) A B C 1 1 -1 0 2 2 -1 0 3 3 -1 0 > lapply(x, "sum") $A [1] 6 $B [1] -3 $C [1] 0 > do.call(sum, x) [1] 3
言語オブジェクトを操作する関数表現式オブジェクトの作成
expression()関数は表現式オブジェクトを作成する.表現式は,呼び出しオブジェクトを並べたリスト風の構造で,リスト風の操作ができる.
> (ex1 <- expression(sum(1:3), "B", 0))
expression(sum(1:3), "B", 0)
> length(ex1)
[1] 3
> ex1[[2]]
[1] "B"
表現式を指定環境で評価
evalq()関数はeval(quote(expr))と同値で,式中の引数を,現在のスコープではなく,オプションで指定された環境で評価する.> a <- -1 > b <- 1 > eval(a + b, list(a = 0)) [1] 0 > evalq(a + b, list(a = 0)) [1] 1
テキストから表現式 とその逆
parse()関数は文字列textの入力を構文解析し,表現式のリストにする.eval関数と組み合わせて使うと便利.deparse()関数は表現式を逆構文解析し,文字列に変換する.fig用のラベル文字列を式から構成するときなどに用いる.
> a <- -1 > b <- 1 > txt1 <- parse(text = "a + b") > eval(txt1) [1] 0 > deparse(txt1) [1] "structure(expression(a + b), srcfile = <environment>, wholeSrcref = structure(c(1L, " [2] "0L, 2L, 0L, 0L, 0L, 1L, 2L), srcfile = <environment>, class = \"srcref\"))"
Rの言語オブジェクトについてまとめてみました.
『Rプログラミングマニュアル』(間瀬茂, 2007年, 数理工学社) を参考にしました.
言語としてのRの基礎や,豊富な役立つtipsが載っており,とても参考になる本です.
言語オブジェクト
型
Rの言語オブジェクトには3つの型がある.呼び出し call,表現式 expression,名前 name である.呼び出しオブジェクトは関数名と引数を与えてつくる.
作成したオブジェクトは,eval()関数で評価実行できる.
> c1 <- call("round", 2.4) > c1 round(2.4) > eval(c1) [1] 2
quote()関数によって表現式オブジェクトを呼び出しに変換できる.引数は,eval()関数を用いたとき,またはオブジェクトをデータとして扱ったときに,はじめて評価される.substitute関数と異なり,quote関数は含まれる引数を評価しないで構文木を返す.
> q1 <- quote(sum(2, 4)) > q1 sum(2, 4) > is.call(q1) [1] TRUE > eval(q1) [1] 6
as.call()関数はリストを呼び出しに変換する.as.list()関数はその逆.
> f <- sum > A <- c(1, 3) > (g <- as.call(list(f, quote(A)))) .Primitive("sum")(A) > eval(g) [1] 4 > as.list(g) [[1]] function (..., na.rm = FALSE) .Primitive("sum") [[2]] A
リストにcallモードを与えても同じことができる.
> g <- list(f, quote(A)) > eval(g) [[1]] function (..., na.rm = FALSE) .Primitive("sum") [[2]] A > mode(g) <- "call" > eval(g) [1] 4
呼び出しはリスト風の構造をしている.
> q2 <- quote(sum(1, 2)) > q2[[1]] sum > q2[[2]] [1] 1 > q2[[3]] [1] 2 > q2[[1]] <- c > eval(q2) [1] 1 2
呼び出しの各成分は名前オブジェクトで置き換えられる.
> q3 <- quote(plot(x, y)) > q3[[1]] plot > q3[[1]] <- as.name("+") > q3 x + y
代入
substitute(expr, env)関数は,環境envに拘束された変数を代入した表現式exprに対する構文木を返す.plot()の軸ラベルなどを生成する際に,評価された実引数の値ではなく,実引数を生成する式が表示されるのは,このはたらきによる.結果は通常,逆構文解析関数であるdeparse()で文字列に変換され,使われる.
> f1 <- function(x){ + cat(x, fill = TRUE) + cat(deparse(substitute(x)), fill = TRUE) + } > f1(rnorm(2)) 1.829917 -0.07375462 rnorm(2)
substitute()関数は,スロットに記録された予約オブジェクトの中身を取り出している (c.f. 遅延評価).
envirに環境やリストを指定すると,その中で変数が検索され,あれば代入される.
> # envirにリストを指定 > (A <- substitute(expression(a + b), list(a = 1, b = 2))) expression(1 + 2) > eval(eval(A)) [1] 3 > # シンボルを変更 > (B <- substitute(expression(a + b), list(a = 1, b = quote(c)))) expression(1 + c) > eval(eval(B)) 以下にエラー 1 + c : 二項演算子の引数が数値ではありません > # cは関数c()とされる > (C <- substitute(expression(a + b), list(a = 1, b = c))) expression(1 + .Primitive("c")) > eval(eval(C)) 以下にエラー 1 + .Primitive("c") : 二項演算子の引数が数値ではありません > # シンボルに値を代入 > d <- 3 > (D <- substitute(expression(a + b), list(a = d, b = 2))) expression(3 + 2) > eval(eval(D)) [1] 5
代入は形式的で,意味を持つかどうかはチェックされない.
遅延評価により,代入式が評価された時点で値が代入されるので,以下のような事態が起こる.
> f1 <- function(y, main = deparse(substitute(y))){ + y <- log(y) + plot(y, main = main) # ここでmainが評価される + } > f2 <- function(y, main = deparse(substitute(y))){ + main # ここでmainが評価されてしまう + y <- log(y) + plot(y, main = main) + } > f1(1:3) > f2(1:3)
呼び出しの即実行
do.call(what, args)関数は,関数名whatと引数リストargsをもとに関数呼び出しを構成し,実行する.lapply()関数との違いは,lapplyはリストの各成分ごとに関数whatを適用して,リストとして結果を返す点.> (x <- data.frame(A = 1:3, B = -1, C = 0)) A B C 1 1 -1 0 2 2 -1 0 3 3 -1 0 > lapply(x, "sum") $A [1] 6 $B [1] -3 $C [1] 0 > do.call(sum, x) [1] 3
言語オブジェクトを操作する関数表現式オブジェクトの作成
expression()関数は表現式オブジェクトを作成する.表現式は,呼び出しオブジェクトを並べたリスト風の構造で,リスト風の操作ができる.
> (ex1 <- expression(sum(1:3), "B", 0))
expression(sum(1:3), "B", 0)
> length(ex1)
[1] 3
> ex1[[2]]
[1] "B"
表現式を指定環境で評価
evalq()関数はeval(quote(expr))と同値で,式中の引数を,現在のスコープではなく,オプションで指定された環境で評価する.> a <- -1 > b <- 1 > eval(a + b, list(a = 0)) [1] 0 > evalq(a + b, list(a = 0)) [1] 1
テキストから表現式 とその逆
parse()関数は文字列textの入力を構文解析し,表現式のリストにする.eval関数と組み合わせて使うと便利.deparse()関数は表現式を逆構文解析し,文字列に変換する.fig用のラベル文字列を式から構成するときなどに用いる.
> a <- -1 > b <- 1 > txt1 <- parse(text = "a + b") > eval(txt1) [1] 0 > deparse(txt1) [1] "structure(expression(a + b), srcfile = <environment>, wholeSrcref = structure(c(1L, " [2] "0L, 2L, 0L, 0L, 0L, 1L, 2L), srcfile = <environment>, class = \"srcref\"))"