2

私の質問

オブジェクトxがそれを変更する関数に渡された場合、 fR は元のオブジェクトを変更するのではなく、変更された の環境x内のローカル コピーを作成します (コピー オン チェンジの原則により)。fただし、xが非常に大きく、 に渡されると不要になる状況があるfため、 が呼び出されると元のコピーを保存することは避けたいと考えていxますf。これを達成する賢い方法はありますか?

fおそらくあまり賢くないユーザーによって提供される未知の関数です。

私の現在の解決策

これまでのところ、 calledへの新しいローカル参照を作成し、ワークスペース内の元の参照を削除してから、新しい参照を渡すx関数をラップするのが最善です。問題は、それが私が望むものを達成できるかどうか確信が持てず、それが でしか機能しないことです。forgetxyglobalenv()

forget <- function(x){
    y <- x
    # x and y now refers to the same object, which has not yet been copied
    print(tracemem(y))
    rm(list=deparse(substitute(x)), envir=globalenv())
    # The outside reference is now removed so modifying `y`
    # should no longer result in a copy (other than the
    # intermediate copy produced in the assigment)
    y
}

f <- function(x){
    print(tracemem(x))
    x[2] <- 9000.1
    x
}

上記の関数を呼び出す例を次に示します。

> a <- 1:3
> tracemem(a)
[1] "<0x2ac1028>"
> b <- f(forget(a))
[1] "<0x2ac1028>"
[1] "<0x2ac1028>"
tracemem[0x2ac1028 -> 0x2ac1e78]: f 
tracemem[0x2ac1e78 -> 0x308f7a0]: f 
> tracemem(b)
[1] "<0x308f7a0>"
> b
[1]    1.0 9000.1    3.0
> a
Error: object 'a' not found

結論

私は自分がやりたいことをやっていますか?それを行うためのより良い方法はありますか?

4

2 に答える 2

5

(1)環境そのための環境を使用できます。

e <- new.env()
e$x <- 1:3
f <- function(e) with(e, x <- x + 1)
f(e)
e$x

(2)参照クラス、または参照クラスは自動的に環境を使用するため、次のものを使用します。

E <- setRefClass("E", fields = "x",
    methods = list(
        f = function() x <<- x + 1
    )
)
e <- E$new(x = 1:3)
e$f()
e$x

(3)プロトオブジェクトも環境を使用します:

library(proto)
p <- proto(x = 1:3, f = function(.) with(., x <- x + 1))
p$f()
p$x

追加:プロトソリューション

f更新:質問との一貫性を保つために、関数名をに変更しました。

于 2013-02-01T16:01:04.587 に答える
1

最も簡単な方法は、元の (グローバル名前空間) と作業コピー (関数名前空間) の両方を読み込むのではなく、作業コピーのみをメモリに読み込むことだと思います。「ff」パッケージを使用して「x」および「y」データセットを「ffdf」データフレームとして定義することにより、問題全体を回避できます。私が理解しているように、「ffdf」データフレームはディスク上に存在し、データフレームの一部が必要になったときにのみメモリにロードされ、それらの部分が不要になったときにパージされます。これは、理論的には、データがメモリに読み込まれて関数の名前空間にコピーされ、コピーが完了した後に消去されることを意味します。

「ff」パッケージを使用する必要はめったにないことを認めます。使用する場合、通常はまったく問題はありません。ただし、特定のメモリ使用量をチェックしているわけではありません。通常、私の目標は、データ全体で大規模な計算を実行することです。それは機能し、私は質問をしません。

于 2013-02-01T15:15:20.083 に答える