問い合わせ先(環境)を変更する方法について

とりあえず試行錯誤メモって感じで。やりたい事は関数h内のxの値をf内から変更するって話。

x <- 1:3
g <- function()
{
  f <- function(){x <<- 10}
  h(f)
}
h <- function(f)
{
  x <- 1
  print(x)
  f()
  print(x)
}

これを実行すると

> g()
[1] 1
[1] 1
> x
[1] 10

となるんで、h内のxは変更されておらず、やりたい事はできていない。
どうも<<-は実行した場所の一個上の環境というよりも、定義した場所から見た上の(この場合更に上の)環境に代入しているように見える。

〜参考を読んで理解した〜
ああ、そうかfが問い合わせる先は、関数を定義したgなのか。
ってのを確かめてみる。

x <- 1:3
g <- function()
{
  print("gの環境")
  print(environment())
  print("gの困った時の問い合わせ先")
  print(parent.env(environment()))
  f <- function(){
    print("fの環境")
    print(environment())
    print("fの困った時の問い合わせ先")
    print(parent.env(environment()))
    x <<- 10
  }
  h(f)
}
h <- function(f)
{
  x <- 1
  print("hの環境")
  print(environment())
  print("hの困った時の問い合わせ先")
  print(parent.env(environment()))
  f()
}

これを実行すると、たしかにfの困った時の問い合わせ先がgの環境になっており、hの環境はfとgの関係には出て来ない。

> g()
[1] "gの環境"
<environment: 0x000000000daf8f40>
[1] "gの困った時の問い合わせ先"
<environment: R_GlobalEnv>
[1] "hの環境"
<environment: 0x000000000cfe6788>
[1] "hの困った時の問い合わせ先"
<environment: R_GlobalEnv>
[1] "fの環境"
<environment: 0x000000000a509ee0>
[1] "fの困った時の問い合わせ先"
<environment: 0x000000000daf8f40>
> x
[1] 10

なんで、fの問い合わせ先がhの環境になるように

environment(f) <- environment()

という処理を追加すると

x <- 1:3
g <- function()
{
  f <- function(){
    x <<- 10
  }
  h(f)
}
h <- function(f)
{
  x <- 1
  #関数fの問い合わせ先を変更
  environment(f) <- environment()
  print(x)
  f()
  print(x)
}

実行すると

> g()
[1] 1
[1] 10
> x
[1] 1 2 3

となり、無事やりたいことができるぞと。

参考(というか、これ読めって話。特に上記の問題だと3)