24

Rには値渡しのセマンティクスがあり、偶発的な副作用を最小限に抑えます(良いことです)。ただし、コードが再利用可能性/読みやすさ/保守性のために多くの関数/メソッドに編成されている場合、およびそのコードが一連の変換/操作を通じて、たとえばビッグデータフレームを介して大きなデータ構造を操作する必要がある場合、値渡しのセマンティクスが導きます周りのデータの多くのコピーと多くのヒープスラッシング(悪いこと)に。たとえば、関数パラメータとして渡されるヒープで50Mbを使用するデータフレームは、少なくとも関数呼び出しの深さと同じ回数だけコピーされ、呼び出しスタックの最下部のヒープサイズはN*になります。 50Mb。関数が呼び出しチェーンの奥深くから変換/変更されたデータフレームを返す場合、コピーは別のNだけ上に移動します。

SOの質問データフレームの受け渡しを回避するための最良の方法は何ですか?このトピックに触れますが、参照渡しの質問を直接行わないように表現されており、勝者の答えは基本的に「はい、値渡しはRの仕組みです」と述べています。それは実際には100%正確ではありません。R環境では、参照渡しのセマンティクスが可能になり、 protoなどのOOフレームワークはこの機能を広範囲に使用します。たとえば、protoオブジェクトが関数の引数として渡され、その「マジックラッパー」が値で渡される場合、R開発者にはセマンティクスが参照渡しされます。

ビッグデータフレームを参照で渡すことは一般的な問題のようで、他の人がどのようにそれにアプローチしているか、そしてこれを可能にするライブラリがあるかどうか疑問に思っています。私の検索では、私はそれを発見していません。

何も利用できない場合、私のアプローチは、データフレームをラップするプロトオブジェクトを作成することです。このオブジェクトを便利にするために追加する必要のあるシンタックスシュガーについてのポインターをいただければ幸いです。たとえば、$演算子と[[演算子、および注意が必要な落とし穴をオーバーロードします。私はRの専門家ではありません。

私のニーズはデータフレームだけですが、Rとうまく統合するタイプにとらわれない参照渡しソリューションのボーナスポイント。

4

1 に答える 1

31

質問の前提は(部分的に)正しくありません。Rはパスバイプロミスとして機能し、プロミスが渡されたときにデータフレームにさらに割り当てや変更が加えられた場合にのみ、アウトラインの方法でコピーが繰り返されます。したがって、コピーの数はN * sizeではなく、Nはスタックの深さであり、Nは割り当てが行われるレベルの数です。あなたは正しいです、しかし、その環境は役に立つかもしれません。リンクをたどると、「proto」パッケージがすでに見つかりました。「R5」と呼ばれることもある「参照クラス」の比較的最近の導入もあります。ここで、R / S3はRでコピーされたS3の元のクラスシステムであり、R4はほとんどサポートしているように見えるより最近のクラスシステムです。 BioConductorパッケージの開発。

コピーコストを回避するためにS4オブジェクト内に環境を埋め込む(参照クラスのメリットを説明するスレッド内の)SteveLianoglouによる例へのリンクを次に示します。

https://stat.ethz.ch/pipermail/r-help/2011-September/289987.html

Matthew Dowleの「data.table」パッケージは、「[」を使用したアクセスセマンティクスが通常のR data.framesのアクセスセマンティクスとは異なり、実際には参照渡しとして機能する新しいクラスのデータオブジェクトを作成します。アクセスと処理の速度が優れています。また、後年、このようなオブジェクトは「data.frame」クラスを継承するため、データフレームのセマンティクスにフォールバックすることもできます。

Hesterbergのデータフレームパッケージを調査することもできます。

于 2012-06-26T12:53:06.543 に答える