<-
現在の環境で割り当てを行います。
関数内にいるとき、Rは新しい環境を作成します。デフォルトでは、作成された環境のすべてが含まれているため、これらの変数も使用できますが、作成した新しいものはグローバル環境に書き込まれません。
ほとんどの場合<<-
、関数内にいる場合でも、すでにグローバル環境にある変数に割り当てるか、グローバル環境に変数を作成します。ただし、それはそれほど単純ではありません。これは、親環境で対象の名前の変数をチェックします。親環境で見つからない場合は、(関数が作成された時点で)親環境の親に移動し、そこで検索します。それは地球環境まで上向きに続き、地球環境で見つからない場合は、地球環境で変数を割り当てます。
これは何が起こっているかを示しているかもしれません。
bar <- "global"
foo <- function(){
bar <- "in foo"
baz <- function(){
bar <- "in baz - before <<-"
bar <<- "in baz - after <<-"
print(bar)
}
print(bar)
baz()
print(bar)
}
> bar
[1] "global"
> foo()
[1] "in foo"
[1] "in baz - before <<-"
[1] "in baz - after <<-"
> bar
[1] "global"
初めてバーを印刷するときはまだ呼び出しfoo
ていないので、まだグローバルである必要があります。これは理にかなっています。2回目に印刷するときは、foo
呼び出す前に内部にあるbaz
ため、「infoo」の値は意味があります。以下は、<<-
実際に何が行われているのかを確認する場所です。次に出力される値は、printステートメントが。の後にある場合でも、「in baz--before<<-」<<-
です。これは<<-
、現在の環境を調べないためです(グローバル環境にいる場合を除き、その場合<<-
はのように動作します<-
)。したがって、barの値の内部はbaz
、「in baz--before<<-」のままになります。baz
内部のバーのコピーを呼び出すと、 foo
「in baz」に変更されますが、ご覧のとおり、グローバルbar
は変更されていません。bar
内部で定義されているのfoo
は、作成時に親環境にあるbaz
ため、これは、が表示される最初のコピーでbar
あり<<-
、したがって、割り当てられるコピーです。つまり<<-
、地球環境に直接割り当てるだけではありません。
<<-
トリッキーで、回避できる場合は使用をお勧めしません。本当にグローバル環境に割り当てたい場合は、割り当て機能を使用して、グローバルに割り当てたいことを明示的に伝えることができます。
ここで<<-
、をassignステートメントに変更すると、次のような効果が見られます。
bar <- "global"
foo <- function(){
bar <- "in foo"
baz <- function(){
assign("bar", "in baz", envir = .GlobalEnv)
}
print(bar)
baz()
print(bar)
}
bar
#[1] "global"
foo()
#[1] "in foo"
#[1] "in foo"
bar
#[1] "in baz"
したがって、どちらfoo
の場合も、値の内側にバーを出力すると、。を呼び出した後でも「infoo」になりbaz
ます。これは、どこを見ればよいかを正確に伝えたため、fooassign
の内部のコピーを考慮しなかったためです。bar
ただし、今回は明示的に割り当てたため、地球環境のbarの値が変更されました。
ここで、ローカル変数の作成についても質問しました。関数を作成しなくても、かなり簡単に作成できます...関数を使用するだけですlocal
。
bar <- "global"
# local will create a new environment for us to play in
local({
bar <- "local"
print(bar)
})
#[1] "local"
bar
#[1] "global"