<-
現在の環境で割り当てを行います。
関数の内部にいるとき、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
ため、 "in foo"という値は意味があります。以下は、<<-
実際に何が行われているのかを示しています。次に出力される値は、 "in baz-before <<-"ですが、printステートメントが<<-
。これは、<<-
が現在の環境を調べないためです(グローバル環境にいる場合<<-
は、のように動作します<-
)。したがってbaz
、barの値の内部は「in baz-before <<-」のままです。baz
内部のバーのコピーを呼び出すと、foo
「in baz」に変更されますが、ご覧のとおり、グローバルbar
は変更されていません。bar
内部で定義されているのfoo
は、作成時に親環境にあるbaz
ので、これは、表示される最初のコピー、bar
つまり<<-
割り当てられるコピーです。つまり<<-
、単にグローバル環境に直接割り当てるだけではありません。
<<-
トリッキーなので、回避できる場合は使用しないことをお勧めします。本当にグローバル環境に割り当てたい場合は、関数assignを使用して、グローバルに割り当てることを明示的に伝えることができます。
ここで<<-
、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
の場合も、を呼び出しbaz
た後でも、値の内部にあるbar は「in foo」です。これは、foo assign
の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"
globalenv(); globalenv() %>% parent.env; globalenv() %>% parent.env %>% parent.env
、…