SlideShare a Scribd company logo
R Language Definition
          version 2.14.2(2012-02-29) DRAFT


Chapter 6: Computing on the language

            Tokyo.Lang.R #2
              2012/06/02
             @teramonagi
6 Computing on the language
•   RはLispよりも親しみやすいインターフェイス
•   しかし、計算エンジンはLisp-like
•   (数式の)“expression”にアクセス可能
•   微分等を解析的に計算可能!(Not 数値的)
•   example
    > curve(sin(x))
    > curve(cos(x))



                                     2
6.1 Direct manipulation of language objects
• Language objectsは3種類
  1. call
  2. expression
  3. function
• まずはcall objectについてのお話
• call object = “unevaluated expressions”
  –   quote関数で生成
  –   その名の通り“まだ評価されていない”
  –   eval関数で評価してやる
  –   [[]]でlist-likeに表現の各要素?にアクセス可能
                                               3
6.1 Direct manipulation of language objects
> e1 <- quote(2 + 2)         > as.list(e1)
> mode(e1)                   [[1]]
[1] "call"                   `+`
> typeof(e1)         call型                   実際これで
[1] "language"               [[2]]           Listになる
> e1[[1]]                    [1] 2
`+`
> e1[[2]]                    [[3]]
[1] 2         Listのように       [1] 2
> e1[[3]]     アクセス可能
[1] 2

                                                       4
6.1 Direct manipulation of language objects
> mode(e1[[1]])              > e1[[2]] <- e1
[1] "name"                   > e1
> mode(e1[[2]])              2*2*2
                   演算子(+,*等)や              callを要素?として
[1] "numeric"                              代入する事も可能
                   変数は”name”
> mode(e1[[3]])
[1] "numeric"
> e1[[1]] <- as.name("*")
> e1
2*2
            演算子の挿げ替え
            (関数も可)
                                                    5
6.1 Direct manipulation of language objects
> x <- quote(c(1,2))        > deparse(quote("-"(2,2)))
> as.list(x)                [1] "2 - 2"
[[1]]                       > deparse(quote(2 - 2))
c                           [1] "2 - 2"
[[2]]
[1] 1
[[3]]
[1] 2                                  同じ表現にdeparse
                                       されるとは限らない
> deparse(x)
[1] "c(1, 2)"
> class(deparse(x))
[1] "character"        deparse(call→文字列化)

                                                         6
6.2 Substitutions
• “expression”をplotラベルとして文字列化した
  い
• そんな時のsubstitute関数。俗に言う“deparse”
  (オブジェクト⇒文字)
• 遅延評価に使われる”promise”オブジェクトの
  expression スロットの値を引っこ抜く
• “promise”オブジェクトは
 – expression:中身の“表現”
 – environment:評価される際の“環境“
 – value:(もし一度評価されているなら)その“値“
の3つのSLOTを持っている(2.1.8より)             7
6.2 Substitutions
plot(0)
for(i in 1:4)
{
  text(1, 0.2 * i,      substitute(x[ix] == y, list(ix = i, y = pnorm(i))))
}
                 1.0




                                        x4  0.9999683
                                        x3  0.9986501
                                        x2  0.9772499
                                        x1  0.8413447
                 0.0
             0
                 -1.0




                        0.6       0.8        1.0         1.2      1.4
                                            Index
                                                                              8
6.2 Substitutions
plot(0)                                                     bquote関数で
for( i in 1:4)                                              略記が可能
{
  text(1, 0.2 * i, bquote(x[.(i)] == .(pnorm(i)) ))
}
              1.0




                                    x4  0.9999683
                                    x3  0.9986501
                                    x2  0.9772499
                                    x1  0.8413447
              0.0
          0
              -1.0




                     0.6      0.8        1.0          1.2    1.4
                                        Index
                                                                        9
6.2 Substitutions
> expr <- quote(x + y)             > nested <-
> not.nested <-                       substitute(substitute(e,
   substitute(expr, list(x = 3))      list(x = 3)), list(e = expr))
> class(not.nested)                > class(nested)
                                                       substituteを
[1] "name"                         [1] "call"
                                                       ネストして適用
> typeof(not.nested)               > typeof(nested)
[1] "symbol"                       [1] "language"
> eval(not.nested)                 > eval(nested)
x+y                                3+y

                       第一引数(quote(x+y))を評価しないので
                       正しくdeparse(文字列化されない)     10
6.2 Substitutions
> default <- 1
> f <- eval(bquote( function(x, y = .(default)) x+y ))
> f(2)
[1] 3



                           かなりヤンチャな書き方もできる。。。
                           が、可読性が。。。



                                                         11
6.2 Substitutions
• 厳密なルール
 – パースツリーのそれぞれのシンボルが第二引数
   (タグ付されたリストか環境)にマッチされる
 – シンボルがローカル変数の場合は、そのローカル
   の値が挿入される(グローバル環境にマッチされ
   る場合除く)
 – シンボルがpromise(関数の引数等)ならその表
   現が代入される(たぶん遅延評価の事)
 – substituteの前にローカル変数が変更された場合、
   Rは新しい値を使う一方、Sの場合はargument
   expressionを使う

                              12
}
                                   y <- log(y)
45, 1.09861228866811, 1.38629436111989, 1.6094379124341,




                                 logplot(1:19)
1.94591014905531, 2.07944154167984, 2.19722457733622,
, 2.39789527279837, 2.484906649788, 2.56494935746154,
            0.0  1.5    3.0
2.70805020110221, 2.77258872223978, 2.83321334405622,
 2.89037175789616, 2.94443897916644)
                                   plot(y, ylab = ylab)




             5
             10
     Index
                                 logplot <- function(y, ylab = deparse(substitute(y))){




             15
                                                                                          6.2 Substitutions




13
6.2 Substitutions
logplot <- function(y, ylab = deparse(substitute(y))){
  ylab
  y <- log(y)
  plot(y, ylab = ylab) “ylab”をあらかじめ
}                        評価しておくと良い
logplot(1:19)
          3.0
   1:19
          1.5
          0.0




                          5              10              15
                                        Index
                                                              14
6.3 More on evaluation
• eval関数
    ‒ “call”オブジェクトを評価するときに使用
    ‒ どの“環境”で評価をするのかを指定可能
    – 例(親環境評価):eval(expr,
> x <- sys.frame(sys.parent())
       3
> y <- 10
> eval(quote(x+y), data.frame(x = 1:10), sys.frame(sys.parent()))
 [1] 11 12 13 14 15 16 17 18 19 20
> eval(quote(x+y), sys.frame(sys.parent()))
                                                先にデータの値を
[1] 13                                          使って評価してくれる
                                                           15
6.4 Evaluation of expression objects
• Expression object(2.1.4に記載あり)
  – 特殊なLanguage Object
  – Language objectとの違い
    • 複数のExpressionを保持(call objectのlistみたいなもん)
    • eval関数に通したときのみ評価される
> ex <- expression(2 + 2, 3 + 4)
                                 call objectの
> ex[[1]]
                                 リストっぽく扱える
2+2
> ex[[2]]
3+4                   最後に評価されたものが値として返ってくる
> eval(ex)            (中で評価は全部されてる)
[1] 7
                                            16
6.4 Evaluation of expression objects
• 前述の例は基本quote({2 + 2; 3 + 4})と同じ
• Language objectとの違い
      • eval関数に通したときのみ評価される

> eval(substitute(mode(x), list(x = quote(2 + 2))))
[1] "numeric"                                       再帰的に
                                                    evalされる

> eval(substitute(mode(x), list(x = expression(2 + 2))))
[1] "expression"
                            “直に”eval関数に渡されない場合は
                            expressionは評価されない

                                                           17
6.4 Evaluation of expression objects
> e <- quote(expression(2 + 2))
>e
                                  expressionを作るcall object
expression(2 + 2)
> mode(e)
[1] "call"
> ee <- expression(2 + 2)                  vs
> ee
expression(2 + 2)
> mode(ee)                            普通のexpression
[1] "expression"

                                                       18
6.5 Manipulation of function calls
• 関数がどのように呼ばれたのかを見たい
  – sys.call関数
  – match.call関数
> f <- function(x, y, ...) sys.call()
> f(y = 1, 2, z = 3, 4)            “2”がxに割り当てられている
                                   のがわかりにくい
f(y = 1, 2, z = 3, 4)
> f <- function(x, y, ...) match.call()
                                    “2”がxに割り当てられている
> f(y = 1, 2, z = 3, 4)             のがわかりやすい
f(x = 2, y = 1, z = 3, 4)
                                  ※返り値は
                                  両方共Call Object      19
6.5 Manipulation of function calls
• match.callは同じ引数で違う関数を呼ばれる時
  によく使われる(例:lm関数の頭)
vh> f <- function (formula, data, subset, weights, na.action, method = "qr",
+       model = TRUE, x = FALSE, y = FALSE, qr = TRUE, singular.ok = TRUE,
+       contrasts = NULL, offset, ...)
+{
+ cl <- match.call()
+ mf <- match.call(expand.dots = FALSE)
+ m <- match(c("formula", "data", "subset", "weights", "na.action",
+          "offset"), names(mf), 0L)
+ mf <- mf[c(1L, m)]
+ print(mf)
+ mf$drop.unused.levels <- TRUE
+ print(mf[[1L]])                                                              関数名だけ
+ mf[[1L]] <- as.name("model.frame")
+ print(mf)
                                                                               変更して評価
+ eval(mf, parent.frame())
+}
                                                                                        20
6.5 Manipulation of function calls
> f(y~x, data.frame(x=1:10, y = 1:10 + rnorm(10)))
f(formula = y ~ x, data = data.frame(x = 1:10, y = 1:10 + rnorm(10)))
f
model.frame(formula = y ~ x, data = data.frame(x = 1:10, y = 1:10 +
   rnorm(10)), drop.unused.levels = TRUE)
      y x                                                               関数名
1 1.409984 1
2 3.925316 2
                                                                        変更前
3 5.449060 3
4 4.462354 4                 関数名変更+項目追加
5 5.494868 5
6 6.283794 6
7 7.479154 7
8 8.675264 8
9 8.283814 9
10 9.259617 10

                                                                         21
6.5 Manipulation of function calls
• match.callのexpand.dotsをFALSEにすると”…”が
  ひと固まりのリストとして扱われる
> f <- function(x, y, ...) match.call(expand.dots = FALSE)
> f(y = 1, 2, z = 3, 4)
f(x = 2, y = 1, ... = list(z = 3, 4))
> f(y = 1, 2, z = 3, 4)$...
$z
                                      リストとして扱われる。特に
[1] 3                                  f(y = 1, 2, z = 3, 4)$... <- NULL
[[2]]                                 等として要らないものを消去
[1] 4                                 する際に使用

                                                                           22
6.5 Manipulation of function calls
• 関数呼び出しを作成する2つの関数
  – call関数
  – do.call関数
• call関数
  – 関数名と引数のリストからcall objectを生成
• do.call関数
  – call関数と似てるけど、こちら値を即評価
  – modeがlistな引数に指定した関数を適用
  (data.frameのmodeもlistなんで適用可能)
                                       23
6.5 Manipulation of function calls
• 関数Callを作成する2つの関数
  – call関数
  – do.call関数
> f <- function(x, y, ...) sys.call()
> f(y = 1, 2, z = 3, 4)            “2”がxに割り当てられている
                                   のがわかりにくい
f(y = 1, 2, z = 3, 4)
> f <- function(x, y, ...) match.call()
                                    “2”がxに割り当てられている
> f(y = 1, 2, z = 3, 4)             のがわかりやすい
f(x = 2, y = 1, z = 3, 4)
                                  ※返り値は
                                  両方共Call Object      24
6.5 Manipulation of function calls
> y <- 10.5
> (e <- call("round", y))                   call関数でcall objectを
                                            生成&評価
round(10.5)
> eval(e)
[1] 10
>
> x <- list(x = 1:5, y = 101:105, z = 1001:1005)
                                                   do.call関数で
> do.call("rbind", x)
                                                   引数のリストを
 [,1] [,2] [,3] [,4] [,5]                          全て”rbind”関数
x 1 2 3 4 5                                        で結合し行列化
y 101 102 103 104 105
z 1001 1002 1003 1004 1005

                                                            25
6.6 Manipulation of functions
• 関数・クロージャーを操作する関数が存在
 1. body:関数の中身(expression)を返却
 2. formals:関数の引数を返却
 3. environment:関数の環境を返却


• 関数⇔リストの相互変換
 – as.list: 関数 ⇒ リスト
 – as.function:リスト ⇒ 関数


                                   26
6.6 Manipulation of functions
> f.original <- function(x){x + a}   > formals(f)
> f <- f.original        例として        $x
> f(3)                   使う関数        > environment(f)
 以下にエラー f(3) : オブ                    <environment: R_GlobalEnv>
   ジェクト ‘a’ がありません                   > body(f) <- quote(5^x)
> body(f)                            > #body(f) <- expression(5^x)
{                                    >f
   x+a                               function (x)
}                                    5^x               関数の中身
                                                      を変更できる


                                                                 27
6.6 Manipulation of functions
               変更された関数                                    3(x) + 10(a) = 13
> f(3)         5^3 = 125として評価 f(3)
                             >                            と評価される
[1] 125                               [1] 13
>                                     >
> f <- f.original                     > f <- f.original
> formals(f) <- alist(x = , a = 10)   > as.list(f)
>f                                    $x
function (x, a = 10)                  [[2]]
{                                     {
   x+a                                   x+a
      alist(の結果)をformalsに
}     入れることで外から束縛                     }

※alistはうまいこと”型”を割り振った”list”を作ってくれる関数 28
6.6 Manipulation of functions
> as.function(as.list(f))
function (x)                            関数をリスト化した後、
{                                       再関数化で元通り
   x+a
}
>
> f <- as.function(alist(x = ,y = 2,x + y))
> f(3)
[1] 5
                alistで作成したlistを関数化

                                                      29

More Related Content

PDF
Cvpr2011 reading-tsubosaka
PPTX
PDF
Introduction Xtend
PPT
12-11-30 Kashiwa.R #5 初めてのR Rを始める前に知っておきたい10のこと
PPTX
Javaプログラミング入門【第2回】
PPTX
Active Directoryデータの Security Descriptor
PDF
Javaセキュアコーディングセミナー東京第4回講義
PDF
JastAdd & JastAddJ クリックチュートリアル
Cvpr2011 reading-tsubosaka
Introduction Xtend
12-11-30 Kashiwa.R #5 初めてのR Rを始める前に知っておきたい10のこと
Javaプログラミング入門【第2回】
Active Directoryデータの Security Descriptor
Javaセキュアコーディングセミナー東京第4回講義
JastAdd & JastAddJ クリックチュートリアル

What's hot (20)

PPTX
Javaプログラミング入門【第7回】
PPTX
Javaプログラミング入門【第3回】
PDF
プログラミング言語Scala
PPTX
Javaデザインパターン入門【第3回】
PDF
Scala with DDD
KEY
Actor&stm
PDF
“Design and Implementation of Generics for the .NET Common Language Runtime”他...
PPTX
C#を始めたばかりの人へのLINQ to Objects
PDF
東京都市大学 データ解析入門 3 行列分解 2
PDF
東京都市大学 データ解析入門 7 回帰分析とモデル選択 2
PDF
東京都市大学 データ解析入門 6 回帰分析とモデル選択 1
PDF
東京都市大学 データ解析入門 8 クラスタリングと分類分析 1
PDF
Monadicプログラミング マニアックス
PDF
サーバーサイドでの非同期処理で色々やったよ
DOCX
深層学習 Day1レポート
PDF
東京都市大学 データ解析入門 4 スパース性と圧縮センシング1
PDF
東京都市大学 データ解析入門 2 行列分解 1
PDF
東京都市大学 データ解析入門 9 クラスタリングと分類分析 2
PDF
BOF1-Scala02.pdf
PPTX
Javaプログラミング入門【第5回】
Javaプログラミング入門【第7回】
Javaプログラミング入門【第3回】
プログラミング言語Scala
Javaデザインパターン入門【第3回】
Scala with DDD
Actor&stm
“Design and Implementation of Generics for the .NET Common Language Runtime”他...
C#を始めたばかりの人へのLINQ to Objects
東京都市大学 データ解析入門 3 行列分解 2
東京都市大学 データ解析入門 7 回帰分析とモデル選択 2
東京都市大学 データ解析入門 6 回帰分析とモデル選択 1
東京都市大学 データ解析入門 8 クラスタリングと分類分析 1
Monadicプログラミング マニアックス
サーバーサイドでの非同期処理で色々やったよ
深層学習 Day1レポート
東京都市大学 データ解析入門 4 スパース性と圧縮センシング1
東京都市大学 データ解析入門 2 行列分解 1
東京都市大学 データ解析入門 9 クラスタリングと分類分析 2
BOF1-Scala02.pdf
Javaプログラミング入門【第5回】
Ad

Similar to Chapter 6: Computing on the language (R Language Definition) (20)

PDF
R language definition3.1_3.2
PDF
初心者講習会資料(Osaka.R#5)
PDF
初心者講習会資料(Osaka.R#7)
PDF
初心者講習会資料(Osaka.r#6)
PDF
R新機能抄出
PDF
第1回R勉強会@東京
DOCX
Ⅰ. Rの基礎 2017
PPTX
統計環境R_データ入出力編2016
PPT
K010 appstat201201
PDF
Rで学ぶデータマイニングI 第8章〜第13章
ODP
第2回R勉強会1
PDF
Tokyor23 doradora09
PPTX
Rプログラミング02 データ入出力編
PDF
テーマ別勉強会(R言語)#1.pdf
PDF
Rあんなときこんなとき(tokyo r#12)
PDF
HiRoshimaR3_IntroR
PPT
Code iq×japanr 公開用
PDF
Nagoya.R #11 入門者講習
PDF
第1回Rを使って統計分析を勉強する会
R language definition3.1_3.2
初心者講習会資料(Osaka.R#5)
初心者講習会資料(Osaka.R#7)
初心者講習会資料(Osaka.r#6)
R新機能抄出
第1回R勉強会@東京
Ⅰ. Rの基礎 2017
統計環境R_データ入出力編2016
K010 appstat201201
Rで学ぶデータマイニングI 第8章〜第13章
第2回R勉強会1
Tokyor23 doradora09
Rプログラミング02 データ入出力編
テーマ別勉強会(R言語)#1.pdf
Rあんなときこんなとき(tokyo r#12)
HiRoshimaR3_IntroR
Code iq×japanr 公開用
Nagoya.R #11 入門者講習
第1回Rを使って統計分析を勉強する会
Ad

More from Nagi Teramo (20)

PDF
第86回R勉強会@東京 LT資料
PDF
Rでを作る
PPTX
Reproducebility 100倍 Dockerマン
PDF
healthplanetパッケージで 体組成データを手に入れて 健康な体も手に入れる
PDF
闇と向き合う
PDF
機械の体を手に入れるのよ、 鉄郎!!!
PDF
続わかりやすいパターン認識11章(11.1 - 11.4)
PDF
5分でわかるかもしれないglmnet
PDF
Ultra Lightning Talk × 3
PDF
F#談話室(17)
PDF
RFinanceJはじめました
PDF
東京R非公式おじさんが教える本当に気持ちいいパッケージ作成法
PDF
お前の逐モン、GETだぜ!
PDF
Trading volume mapping R in recent environment
PDF
~knitr+pandocではじめる~『R MarkdownでReproducible Research』
PDF
とある金融屋の統計技師が時系列解析してみた
PDF
可視化周辺の進化がヤヴァイ~rChartsを中心として~
PDF
「plyrパッケージで君も前処理スタ☆」改め「plyrパッケージ徹底入門」
PDF
Tokyo.R 白熱教室「これからのRcppの話をしよう」
PDF
レプリカ交換モンテカルロ法で乱数の生成
第86回R勉強会@東京 LT資料
Rでを作る
Reproducebility 100倍 Dockerマン
healthplanetパッケージで 体組成データを手に入れて 健康な体も手に入れる
闇と向き合う
機械の体を手に入れるのよ、 鉄郎!!!
続わかりやすいパターン認識11章(11.1 - 11.4)
5分でわかるかもしれないglmnet
Ultra Lightning Talk × 3
F#談話室(17)
RFinanceJはじめました
東京R非公式おじさんが教える本当に気持ちいいパッケージ作成法
お前の逐モン、GETだぜ!
Trading volume mapping R in recent environment
~knitr+pandocではじめる~『R MarkdownでReproducible Research』
とある金融屋の統計技師が時系列解析してみた
可視化周辺の進化がヤヴァイ~rChartsを中心として~
「plyrパッケージで君も前処理スタ☆」改め「plyrパッケージ徹底入門」
Tokyo.R 白熱教室「これからのRcppの話をしよう」
レプリカ交換モンテカルロ法で乱数の生成

Chapter 6: Computing on the language (R Language Definition)

  • 1. R Language Definition version 2.14.2(2012-02-29) DRAFT Chapter 6: Computing on the language Tokyo.Lang.R #2 2012/06/02 @teramonagi
  • 2. 6 Computing on the language • RはLispよりも親しみやすいインターフェイス • しかし、計算エンジンはLisp-like • (数式の)“expression”にアクセス可能 • 微分等を解析的に計算可能!(Not 数値的) • example > curve(sin(x)) > curve(cos(x)) 2
  • 3. 6.1 Direct manipulation of language objects • Language objectsは3種類 1. call 2. expression 3. function • まずはcall objectについてのお話 • call object = “unevaluated expressions” – quote関数で生成 – その名の通り“まだ評価されていない” – eval関数で評価してやる – [[]]でlist-likeに表現の各要素?にアクセス可能 3
  • 4. 6.1 Direct manipulation of language objects > e1 <- quote(2 + 2) > as.list(e1) > mode(e1) [[1]] [1] "call" `+` > typeof(e1) call型 実際これで [1] "language" [[2]] Listになる > e1[[1]] [1] 2 `+` > e1[[2]] [[3]] [1] 2 Listのように [1] 2 > e1[[3]] アクセス可能 [1] 2 4
  • 5. 6.1 Direct manipulation of language objects > mode(e1[[1]]) > e1[[2]] <- e1 [1] "name" > e1 > mode(e1[[2]]) 2*2*2 演算子(+,*等)や callを要素?として [1] "numeric" 代入する事も可能 変数は”name” > mode(e1[[3]]) [1] "numeric" > e1[[1]] <- as.name("*") > e1 2*2 演算子の挿げ替え (関数も可) 5
  • 6. 6.1 Direct manipulation of language objects > x <- quote(c(1,2)) > deparse(quote("-"(2,2))) > as.list(x) [1] "2 - 2" [[1]] > deparse(quote(2 - 2)) c [1] "2 - 2" [[2]] [1] 1 [[3]] [1] 2 同じ表現にdeparse されるとは限らない > deparse(x) [1] "c(1, 2)" > class(deparse(x)) [1] "character" deparse(call→文字列化) 6
  • 7. 6.2 Substitutions • “expression”をplotラベルとして文字列化した い • そんな時のsubstitute関数。俗に言う“deparse” (オブジェクト⇒文字) • 遅延評価に使われる”promise”オブジェクトの expression スロットの値を引っこ抜く • “promise”オブジェクトは – expression:中身の“表現” – environment:評価される際の“環境“ – value:(もし一度評価されているなら)その“値“ の3つのSLOTを持っている(2.1.8より) 7
  • 8. 6.2 Substitutions plot(0) for(i in 1:4) { text(1, 0.2 * i, substitute(x[ix] == y, list(ix = i, y = pnorm(i)))) } 1.0 x4  0.9999683 x3  0.9986501 x2  0.9772499 x1  0.8413447 0.0 0 -1.0 0.6 0.8 1.0 1.2 1.4 Index 8
  • 9. 6.2 Substitutions plot(0) bquote関数で for( i in 1:4) 略記が可能 { text(1, 0.2 * i, bquote(x[.(i)] == .(pnorm(i)) )) } 1.0 x4  0.9999683 x3  0.9986501 x2  0.9772499 x1  0.8413447 0.0 0 -1.0 0.6 0.8 1.0 1.2 1.4 Index 9
  • 10. 6.2 Substitutions > expr <- quote(x + y) > nested <- > not.nested <- substitute(substitute(e, substitute(expr, list(x = 3)) list(x = 3)), list(e = expr)) > class(not.nested) > class(nested) substituteを [1] "name" [1] "call" ネストして適用 > typeof(not.nested) > typeof(nested) [1] "symbol" [1] "language" > eval(not.nested) > eval(nested) x+y 3+y 第一引数(quote(x+y))を評価しないので 正しくdeparse(文字列化されない) 10
  • 11. 6.2 Substitutions > default <- 1 > f <- eval(bquote( function(x, y = .(default)) x+y )) > f(2) [1] 3 かなりヤンチャな書き方もできる。。。 が、可読性が。。。 11
  • 12. 6.2 Substitutions • 厳密なルール – パースツリーのそれぞれのシンボルが第二引数 (タグ付されたリストか環境)にマッチされる – シンボルがローカル変数の場合は、そのローカル の値が挿入される(グローバル環境にマッチされ る場合除く) – シンボルがpromise(関数の引数等)ならその表 現が代入される(たぶん遅延評価の事) – substituteの前にローカル変数が変更された場合、 Rは新しい値を使う一方、Sの場合はargument expressionを使う 12
  • 13. } y <- log(y) 45, 1.09861228866811, 1.38629436111989, 1.6094379124341, logplot(1:19) 1.94591014905531, 2.07944154167984, 2.19722457733622, , 2.39789527279837, 2.484906649788, 2.56494935746154, 0.0 1.5 3.0 2.70805020110221, 2.77258872223978, 2.83321334405622, 2.89037175789616, 2.94443897916644) plot(y, ylab = ylab) 5 10 Index logplot <- function(y, ylab = deparse(substitute(y))){ 15 6.2 Substitutions 13
  • 14. 6.2 Substitutions logplot <- function(y, ylab = deparse(substitute(y))){ ylab y <- log(y) plot(y, ylab = ylab) “ylab”をあらかじめ } 評価しておくと良い logplot(1:19) 3.0 1:19 1.5 0.0 5 10 15 Index 14
  • 15. 6.3 More on evaluation • eval関数 ‒ “call”オブジェクトを評価するときに使用 ‒ どの“環境”で評価をするのかを指定可能 – 例(親環境評価):eval(expr, > x <- sys.frame(sys.parent()) 3 > y <- 10 > eval(quote(x+y), data.frame(x = 1:10), sys.frame(sys.parent())) [1] 11 12 13 14 15 16 17 18 19 20 > eval(quote(x+y), sys.frame(sys.parent())) 先にデータの値を [1] 13 使って評価してくれる 15
  • 16. 6.4 Evaluation of expression objects • Expression object(2.1.4に記載あり) – 特殊なLanguage Object – Language objectとの違い • 複数のExpressionを保持(call objectのlistみたいなもん) • eval関数に通したときのみ評価される > ex <- expression(2 + 2, 3 + 4) call objectの > ex[[1]] リストっぽく扱える 2+2 > ex[[2]] 3+4 最後に評価されたものが値として返ってくる > eval(ex) (中で評価は全部されてる) [1] 7 16
  • 17. 6.4 Evaluation of expression objects • 前述の例は基本quote({2 + 2; 3 + 4})と同じ • Language objectとの違い • eval関数に通したときのみ評価される > eval(substitute(mode(x), list(x = quote(2 + 2)))) [1] "numeric" 再帰的に evalされる > eval(substitute(mode(x), list(x = expression(2 + 2)))) [1] "expression" “直に”eval関数に渡されない場合は expressionは評価されない 17
  • 18. 6.4 Evaluation of expression objects > e <- quote(expression(2 + 2)) >e expressionを作るcall object expression(2 + 2) > mode(e) [1] "call" > ee <- expression(2 + 2) vs > ee expression(2 + 2) > mode(ee) 普通のexpression [1] "expression" 18
  • 19. 6.5 Manipulation of function calls • 関数がどのように呼ばれたのかを見たい – sys.call関数 – match.call関数 > f <- function(x, y, ...) sys.call() > f(y = 1, 2, z = 3, 4) “2”がxに割り当てられている のがわかりにくい f(y = 1, 2, z = 3, 4) > f <- function(x, y, ...) match.call() “2”がxに割り当てられている > f(y = 1, 2, z = 3, 4) のがわかりやすい f(x = 2, y = 1, z = 3, 4) ※返り値は 両方共Call Object 19
  • 20. 6.5 Manipulation of function calls • match.callは同じ引数で違う関数を呼ばれる時 によく使われる(例:lm関数の頭) vh> f <- function (formula, data, subset, weights, na.action, method = "qr", + model = TRUE, x = FALSE, y = FALSE, qr = TRUE, singular.ok = TRUE, + contrasts = NULL, offset, ...) +{ + cl <- match.call() + mf <- match.call(expand.dots = FALSE) + m <- match(c("formula", "data", "subset", "weights", "na.action", + "offset"), names(mf), 0L) + mf <- mf[c(1L, m)] + print(mf) + mf$drop.unused.levels <- TRUE + print(mf[[1L]]) 関数名だけ + mf[[1L]] <- as.name("model.frame") + print(mf) 変更して評価 + eval(mf, parent.frame()) +} 20
  • 21. 6.5 Manipulation of function calls > f(y~x, data.frame(x=1:10, y = 1:10 + rnorm(10))) f(formula = y ~ x, data = data.frame(x = 1:10, y = 1:10 + rnorm(10))) f model.frame(formula = y ~ x, data = data.frame(x = 1:10, y = 1:10 + rnorm(10)), drop.unused.levels = TRUE) y x 関数名 1 1.409984 1 2 3.925316 2 変更前 3 5.449060 3 4 4.462354 4 関数名変更+項目追加 5 5.494868 5 6 6.283794 6 7 7.479154 7 8 8.675264 8 9 8.283814 9 10 9.259617 10 21
  • 22. 6.5 Manipulation of function calls • match.callのexpand.dotsをFALSEにすると”…”が ひと固まりのリストとして扱われる > f <- function(x, y, ...) match.call(expand.dots = FALSE) > f(y = 1, 2, z = 3, 4) f(x = 2, y = 1, ... = list(z = 3, 4)) > f(y = 1, 2, z = 3, 4)$... $z リストとして扱われる。特に [1] 3 f(y = 1, 2, z = 3, 4)$... <- NULL [[2]] 等として要らないものを消去 [1] 4 する際に使用 22
  • 23. 6.5 Manipulation of function calls • 関数呼び出しを作成する2つの関数 – call関数 – do.call関数 • call関数 – 関数名と引数のリストからcall objectを生成 • do.call関数 – call関数と似てるけど、こちら値を即評価 – modeがlistな引数に指定した関数を適用 (data.frameのmodeもlistなんで適用可能) 23
  • 24. 6.5 Manipulation of function calls • 関数Callを作成する2つの関数 – call関数 – do.call関数 > f <- function(x, y, ...) sys.call() > f(y = 1, 2, z = 3, 4) “2”がxに割り当てられている のがわかりにくい f(y = 1, 2, z = 3, 4) > f <- function(x, y, ...) match.call() “2”がxに割り当てられている > f(y = 1, 2, z = 3, 4) のがわかりやすい f(x = 2, y = 1, z = 3, 4) ※返り値は 両方共Call Object 24
  • 25. 6.5 Manipulation of function calls > y <- 10.5 > (e <- call("round", y)) call関数でcall objectを 生成&評価 round(10.5) > eval(e) [1] 10 > > x <- list(x = 1:5, y = 101:105, z = 1001:1005) do.call関数で > do.call("rbind", x) 引数のリストを [,1] [,2] [,3] [,4] [,5] 全て”rbind”関数 x 1 2 3 4 5 で結合し行列化 y 101 102 103 104 105 z 1001 1002 1003 1004 1005 25
  • 26. 6.6 Manipulation of functions • 関数・クロージャーを操作する関数が存在 1. body:関数の中身(expression)を返却 2. formals:関数の引数を返却 3. environment:関数の環境を返却 • 関数⇔リストの相互変換 – as.list: 関数 ⇒ リスト – as.function:リスト ⇒ 関数 26
  • 27. 6.6 Manipulation of functions > f.original <- function(x){x + a} > formals(f) > f <- f.original 例として $x > f(3) 使う関数 > environment(f) 以下にエラー f(3) : オブ <environment: R_GlobalEnv> ジェクト ‘a’ がありません > body(f) <- quote(5^x) > body(f) > #body(f) <- expression(5^x) { >f x+a function (x) } 5^x 関数の中身 を変更できる 27
  • 28. 6.6 Manipulation of functions 変更された関数 3(x) + 10(a) = 13 > f(3) 5^3 = 125として評価 f(3) > と評価される [1] 125 [1] 13 > > > f <- f.original > f <- f.original > formals(f) <- alist(x = , a = 10) > as.list(f) >f $x function (x, a = 10) [[2]] { { x+a x+a alist(の結果)をformalsに } 入れることで外から束縛 } ※alistはうまいこと”型”を割り振った”list”を作ってくれる関数 28
  • 29. 6.6 Manipulation of functions > as.function(as.list(f)) function (x) 関数をリスト化した後、 { 再関数化で元通り x+a } > > f <- as.function(alist(x = ,y = 2,x + y)) > f(3) [1] 5 alistで作成したlistを関数化 29