Rの変数の取扱い


変数と環境

普段グラフを書くためにRを使っているが、そのためのプログラムは比較的単純なので、バグに苦しむことは少ないが、少し複雑なプログラムを書いていたら、バグに大変苦しめられた。その要因はいくつかあるのだが、一つは変数の有効範囲の問題だった。

例えば、あるプログラムの中で、関数を定義した場合に、変数のスコープがどうなるかを実験してみよう。以下のようなプログラムを動かすとどうなるだろうか。

a<-1
b<-function(){print(a);a<-2}
b()
print(a)

functionの中では、当初はaが定義されていないが、外のaの値を取ってくるので、エラーは起こらず、1が表示される。しかし、次の代入は関数内のスコープをもつ変数に代入されるので、関数の外では1のままとなるのである。読み込めるのに書き込めないというややこしい状況になる。

functionの中と外でスコープを一致させるためには、以下のようにすると良い。代入と取り出しを書くのが長くなるが、環境を指定することができるようになる。すると、関数の外でもaの値が更新されて2となる。ちなみに、evalで環境を指定するという方法もある。

e<-new.env()
assign("a",1,envir=e)
b<-function(){print(get("a",envir=e));assign("a",2,envir=e)}
b()
print(get("a",envir=e))