145

私は R の初心者であり、R でのローカル変数とグローバル変数の使用法にかなり混乱しています。

インターネットで、現在の環境で変数を使用する=か割り当てるかという投稿を読みました。関数内でグローバル変数にアクセスできます。<-<<-

ただし、C++ では、かっこ内で変数を宣言するたびにローカル変数が発生することを覚えている{}ので、これは R でも同じでしょうか? それとも、ローカル変数の概念があるのは Rの関数だけですか。

ちょっとした実験をしてみましたが、括弧だけでは不十分だと思われます。何か間違っているのでしょうか?

{
   x=matrix(1:10,2,5)
}
print(x[2,2])
[1] 4
4

3 に答える 3

168

関数内で宣言された変数は、その関数に対してローカルです。例えば:

foo <- function() {
    bar <- 1
}
foo()
bar

次のエラーが発生しますError: object 'bar' not found

barグローバル変数を作成する場合は、次のようにする必要があります。

foo <- function() {
    bar <<- 1
}
foo()
bar

この場合bar、関数の外部からアクセスできます。

ただし、C、C++、または他の多くの言語とは異なり、ブラケットは変数のスコープを決定しません。たとえば、次のコード スニペットでは次のようになります。

if (x > 10) {
    y <- 0
}
else {
    y <- 1
}

yif-elseステートメントの後も引き続きアクセスできます。

よくおっしゃる通り、ネストされた環境を作成することもできます。これらの使用方法を理解するには、次の 2 つのリンクを参照してください。

  1. http://stat.ethz.ch/R-manual/R-devel/library/base/html/environment.html
  2. http://stat.ethz.ch/R-manual/R-devel/library/base/html/get.html

ここに小さな例があります:

test.env <- new.env()

assign('var', 100, envir=test.env)
# or simply
test.env$var <- 100

get('var') # var cannot be found since it is not defined in this environment
get('var', envir=test.env) # now it can be found
于 2012-06-05T20:20:40.810 に答える
148

<-現在の環境で割り当てを行います。

関数内にいるとき、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"
于 2012-06-05T20:56:00.007 に答える