symbolはベクトルを作れない
既に下記の記事やっていた1のだが、 niszet.hatenablog.com
単純に、c()
でベクトルを作ろうと思う。symbol
はas.symbol()
で作る。
c(as.symbol("~"), as.symbol("a")) [[1]] `~` [[2]] a
構造を見てみると、
str(c(as.symbol("~"), as.symbol("a"))) #> List of 2 #> $ : symbol ~ #> $ : symbol a is.list(c(as.symbol("~"), as.symbol("a"))) #> [1] TRUE
で、listになっている、と。ようやく理解できたかな…。
languageを直接作る方法はなさそう
さて、前回はformulaを分解してみていきました。
formulaはformula()
かas.formula()
によって作ることができます。他にもa~b
のような形で作れますが、後者の書式だとsymbolで書かねばならないので、文字列からas.formula()
で作った方が関数等に使いまわしがしやすいかな。
rlang
パッケージやplyr
パッケージも見てみましたが、as.language()
みたいな関数はなさそうです。が、
quote(a~b) plyr::is.formula(quote(a~b)) #> [1] FALSE is.language(quote(a~b)) #> [1] TRUE
quote
でlanguageとなります。この辺りはまた別にわけよう。
また、as.formula()
の引数にあるように、formula
は環境(environment)を必要とします。前回見たように、language
にenvironment
がついた構造がformula
です(class属性も持っているけど)
で、language
は~
とsymbol
で構成されて、1番目の要素は必ず~
、そのあと左辺と右辺に相当するlanguage
かsymbol
が入り、language
の場合は同じルールでネストすることが可能ということですね。前回見た通り。
ちなみに、
x<-as.formula("a~b") x[[2]]<-as.formula("b~c")
で要素を置き換えることが出来るが、置き換えた部分はlanguageではなくformulaになってしまうのである。単体のlanguageオブジェクトを作って置き換える場合はquote()
で。
あと、一旦formulaの形をとると、なんでも代入できる気がする。文字列"a~b"も関数sumも入った。View()
で確認するとちゃんとそれぞれのオブジェクトのまま(languageとかsymbolにならないで)格納されていることがわかる。これはlanguageでも同じで、これはNSEにつながる話のようだな。
また、as.formula()
にNULLを渡すとlist
かつformula
となるようだ。
x<-as.formula(NULL) x #> list() is.list(x) #> [1] TRUE plyr::is.formula(x) #> [1] TRUE # 当然、通常の作り方の場合はlistではない。 is.list(a~b) #> [1] FALSE plyr::is.formula(x) #> [1] TRUE
未評価のままオブジェクトを保存できる便利な箱の出来上がりですね。
symbolはシンボリックリンクみたいなもん。
symbolは変数の名前であって、中身は入っていないリンクのようなもので、リンク元を環境という形で与えられると値を取り出すことが出来る。
見た方が分かりやすくて、
a<- 1 x<-new.env() x$a <- 1000 eval(as.symbol("a")) #> [1] 1 eval(as.symbol("a"), envir = x) #> [1] 1000
のように、適当な環境に変数a
をその実体としては1であるように作っておくと、その環境のもとでeval()
すればその環境での変数名から値を取り出すことが出来る、そんな感じ。
調べると調べた分だけ不明な点が出てくるので文章をまとめてから日記に出来ていませんが…。このあたり全容を把握出来たらもう一度清書したい…
Enjoy!!
-
教えていただいただけで僕何もしていないのでは。↩