web-dev-qa-db-ja.com

R:参照によるデータフレームの受け渡し

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

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

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

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

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

22
Sim

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

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

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

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

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

29
42-