<-現在の環境で割り当てを行います。
関数内にいるとき、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"