実際には、@Backlin が示すのとは逆です。親環境は、他の環境を囲む環境です。したがって、定義した場合、 を囲む環境test
は のローカル環境でfn
あり、 を囲む環境test1
はグローバル環境です。次のようになります。
環境は、関数に渡されたときや代入で使用されたときにコピーされないという意味で、R の他のオブジェクトとは異なる動作をします。環境オブジェクト自体は、次へのポインタで内部的に構成されています。
- フレーム (値を含むペアリスト)
- 囲んでいる環境 (上で説明したように)
- ハッシュ テーブル (環境がハッシュされていない場合はリストまたは NULL)
環境にポインターが含まれているという事実は、すべての違いを生みます。環境を扱うのはそれほど簡単ではなく、実際には非常にトリッキーです。以下のコードを見てください。
> test <- new.env()
> test$a <- 1
> test2 <- test
> test2$a <- 2
> test$a
[1] 2
したがって、からコピーしたのはポインターだけtest
ですtest2
。の値を変更すると、 の値test2
も変更さtest
れます。(実際には、その値を一度だけ変更しますがtest
、test2
両方を同じフレームに向けます)。
環境を保存しようとすると、R はフレーム、ハッシュ テーブル、および囲んでいる環境の値を取得して保存するしかありません。エンクロージング環境はそれ自体が環境であるため、R はグローバル環境に到達するまで、すべてのエンクロージング環境も保存します。グローバル環境は内部コードで特別な方法で扱われるため、(幸いなことに) ファイルには保存されません。
囲んでいる環境と親フレームの違いに注意してください: 関数の定義が少し異なるとします:
a <- matrix(runif(1000000, 0, 1), ncol=1000)
save(a, file="bigfile.RData")
fn <- function() {
load("bigfile.RData")
test <- new.env()
save(test, file="far-too-big.RData")
test1 <- new.env(parent=globalenv())
save(test1, file="right-size.RData")
}
fn2 <- function(){
z <- matrix(runif(1000000,0,1),ncol=1000)
fn()
}
fn2()
現在、次の状況があります。

ファイル "far-too-big.RData" には行列 a と行列 z の両方が含まれていると思われるかもしれませんが、そうではありません。行列 a のみが含まれます。これは、 を囲む環境fn
がグローバル環境であるためです。の親フレームはfn
の環境ですfn2
が、 によって作成された環境オブジェクトfn
にはグローバル環境へのポインタが含まれています。
一方、次のようにすると:
fn <- function() {
load("bigfile.RData")
test <- new.env()
test$b <- a
test2 <- new.env(parent=test)
save(test2, file="far-too-big.RData")
}
test2
は 2 つの環境 (test
と の環境fun
) に含まれるようになり、両方の環境もファイルに保存されます。したがって、次のような状況になります。

これに関係なく、私は個人的に環境を環境として保存することを避けています。私の意見では、環境をリストとして保存することは、99.9% のケースでより良い選択です:
fn2 <- function(){
load("bigfile.RData")
test <- new.env()
test$x <- "something"
test$fn <- ls
testlist <- as.list(test)
save(testlist, file="right-size.RData")
}
fn2()
環境にする必要がある場合は、ロード時に元に戻すことができます。
load("right-size.RData")
test <- as.environment(testlist)