32. ローカル変数と永続代入<<-


ローカル変数と永続代入 <<- について

関数中で値が代入される変数をローカル変数といい,ここでの値は普通の変数(グローバル変数)に影響を与えない.例えば,関数内 <- による代入がなされた変数はその関数の中でのみ有効である.つまり,関数内で <- による代入を行なっても,関数の外部にある同じ名前の変数の値は決して変わることがない.よって関数の内部では外部に及ぼす影響を考えずに変数名を決めてもよいことになる.

 
 x <- 10                     # グローバル変数 x
 myfunc <- function(y) {     # y は引数(形式パラメータという)
   x <- y + 999              # x は関数 myfunc() 中のローカル変数
   return(x)                 # 引数でもローカル変数でもない変数は自由変数と呼ばれる
 }                           # 
 x

[1] 10                       # グローバル変数 x の値は 10

 myfunc(1)

[1] 1000                     # グローバル変数 x には影響を与えない

 x                           # 影響がないかどうかを確認する

[1] 10 

関数定義の中からグローバル変数に値を代入する場合は永続代入演算子 <<- を用いる.

 
 x <- 10                    # グローバル変数 x
 myfunc <- function () {
   x <- 777                 # 関数 myfunc() 中のローカル変数 x
   x <<- 99                 # グローバル変数 x に 99 を代入する
   print(x)                 # ローカル変数 x の値を表示
 }
 myfunc()

[1] 777                     # 関数 myfunc() の返り値 (変数 x ) の値

 x                          # 関数 myfunc() 内でグローバル変数 x の値を変えたので,

[1] 99                      # グローバル変数 x の値は 99

永続代入演算子 <<- でグローバル変数に代入をする場合,特に関数中でグローバル変数に代入をする場合は注意が必要である.上の例では,同じ名前だが実体が異なる二つの変数が登場する.関数中では単なる変数 x はローカル変数を指し,これは関数実行後は残らない.一方,グローバル変数 x は関数実行後も残る.すなわち,慣れないうちはグローバル変数とローカル変数を同じ名前にしない方が良いということである.

 
 x <- 10
 myfunc <- function () {
   x <- c(1, 2)
   x[2] <<- 0                       # この文に注目!!
   print(x)
 }
 myfunc()

[1] 1 2 3

 x

[1] 10  0                           # いつの間にかベクトルに...

グローバル変数にアクセスする場合は assign(変数, 値, env=.GlobalEnv) を用いた方が良い.以下にその例を挙げる.

 
 x <- 10
 myfunc <- function () {
   x <- 1:3
   assign(x[2], 2, env=.GlobalEnv)  # x[2] <<- 0 を修正!!
   print(x)
 }
 myfunc()                           # ちゃんとエラーが出る

以下にエラー assign(x[2], 2, env = .GlobalEnv) : 一番目の引数が不正です

関数内で代入が行われない『自由変数』は ローカル変数とは違ったふるまいをする.この仕様は「スコープ」と呼ばれる.

 
 myfunc <- function() print(z)   # z は自由変数
 myfunc()                        # z には何も無いのでエラーが出る

以下にエラーprint(z) : オブジェクト "z" は存在しません

 z <- 999                        # グローバル変数 z に 999 を代入して
 myfunc()                        # myfunc() を実行したらエラーが出るかと思いきや…

[1] 999                          # ローカル内だけでなくグローバル環境にまで z を探しに行き,999 が表示される

R の「スコープ」という概念に興味のある方は,英語版マニュアルの日本語訳「 R 入門 」や「 RjpWiki 」などで学習することをお勧めする.