2012-06-26 6 views
18

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

SOの質問What is the best way to avoid passing a data frame around?はこのトピックに触れていますが、直接パスバイ基準の質問と勝利の答えは基本的に "はい、値渡しはRの仕組み"と言います。それは実際に100%正確ではありません。 R環境では、参照渡しのセマンティクスが有効になり、protoなどのOOフレームワークでは、この機能が広く使用されます。例えば、protoオブジェクトが関数引数として渡され、その "マジックラッパー"が値渡されてR開発者に渡されるとき、セマンティクスは参照渡しです。

大きなデータフレームを参照渡しするのはよくある問題ですが、他の人がどのようにそれに近づいてきたのか、これを可能にするライブラリがあるかどうかは疑問です。私の検索では、私はそれを発見していない。

何も利用できない場合、私のアプローチは、データフレームをラップするprotoオブジェクトを作成することです。たとえば、$や[[演算子、さらには私が注意しなければならないような厄介な点をあふれさせるなど]このオブジェクトに役に立つ文法的な砂糖についての情報を参考にしていただければ幸いです。私はRの専門家ではない。

私の必要性はデータフレームだけではあるが、Rにうまく統合されたタイプにとらわれないパスバイリファレンスソリューションのボーナスポイント。

+4

あなたの質問の前提が正しいとは思わない。 Rは変更をコピーするだけなので、オブジェクトを変更しない限り、新しいコピーを作成することなく引数を呼び出しスタックに渡すことができます。私はあなたにこれについての参考資料を1分で見つけようとします。 – Andrie

+0

たとえば、この質問とその回答を参照してください@ matthewdowle:http://stackoverflow.com/q/10225098/602276 – Andrie

+2

Andrieは正しいです。大きな 'data.frame'の検索で、[' data.table'](http://datatable.r-forge.r-project.org/LondonR_2012.pdf)が見つかりませんでした。あなたは何を探しましたか? –

答えて

26

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

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

マシューDowleさん:ここ

は、コピーコストを回避するためにS4オブジェクト内の環境を埋め込む(参照クラスのメリットを議論スレッドで)スティーブ・Lianoglouによって例へのリンクです'data.table'パッケージは、 "["を使用するアクセスセマンティクスが通常のR data.framesとは異なる、新しいデータオブジェクトクラスを作成し、実際には参照渡しとして機能します。それはアクセスと処理の優れた速度を持っています。また、後の年にこのようなオブジェクトは 'data.frame'クラスを継承しているので、データフレームセマンティクスにも戻すことができます。

Hesterberg's dataframe packageを調べることもできます。

+1

+1この回答を展開して改善していただきありがとうございます。 – Andrie

+1

そして、データフレームパッケージへのリンク+1は、R 2.15-1 – Andrie

+1

@DWinに組み込まれています(または少なくとも哲学的に)。 Pass-by-promiseは最適化として理にかなっていますが、複数のステップが同じデータフレーム上で「未処理」から処理可能にするために役立つわけではありません。通常、変更は処理パイプラインの別々のステップで実行されますが、場合によっては、異なるインバリアントを持つ抽象境界が交差するため、同じコールチェーンで実行されます。あなたが推奨するパッケージを調べます。 – Sim

関連する問題