evalをlapplyしたい(以前もハマった気がする)
通常、R言語の呼び出しオブジェクトの評価と言えばevalを使って
> eval(call("<-", substitute(a), 1:10))
なんて書くと変数aが現在の環境*1にアサインされるわけです。
これをリストでもやりたいぞとそういうことです。
まず以下のような"呼び出しオブジェクト"を要素に持つリストを作ります。
> x <- list(call("<-", substitute(a), 1:10), call("<-", substitute(aa), 1:10), call("<-", substitute(aaa), 1:10)) > x [[1]] a <- 1:10 [[2]] aa <- 1:10 [[3]] aaa <- 1:10
んで、これを評価(eval)してやると、今の環境(コンソール)に1-10までの連続した数値を要素として持つ変数a,aa,aaaが出来ることを期待するわけです。
> lapply(x, eval) [[1]] [1] 1 2 3 4 5 6 7 8 9 10 [[2]] [1] 1 2 3 4 5 6 7 8 9 10 [[3]] [1] 1 2 3 4 5 6 7 8 9 10
でも、これだとだめ。ls()関数でオブジェクト一覧を拾ってきてもだめ。そもそも存在しないわけです。
で、「ハハーン、lapply内の環境に変数がアサインされてるんだなこれ」
って思って、現在の環境を渡すつもりで
> environment() <environment: R_GlobalEnv> > lapply(x, function(y)eval(y, envir=environment())) [[1]] [1] 1 2 3 4 5 6 7 8 9 10 [[2]] [1] 1 2 3 4 5 6 7 8 9 10 [[3]] [1] 1 2 3 4 5 6 7 8 9 10
と書いてもやっぱりだめ。
答えは以下の通りで、あらかじめちゃんとenvironment関数を評価しておいて、適当な変数としてとっておけと、
関数内部で取得する"現在の環境"はコンソールの環境とはならないだろと。そういうことです。
> env.current <- environment() > lapply(x, function(y)eval(y, envir=env.current)) [[1]] [1] 1 2 3 4 5 6 7 8 9 10 [[2]] [1] 1 2 3 4 5 6 7 8 9 10 [[3]] [1] 1 2 3 4 5 6 7 8 9 10
これで現在の環境に変数a,aa,aaaがアサインされるので、以降、使える。
前にも嵌った気がするが思い出せん。
*1:environment()で取得