164

複雑なRプロジェクトに着手すると、スクリプトがすぐに長くなり、混乱します。

私のコードが常に楽しく使えるようにするために採用できるいくつかのプラクティスは何ですか?私は次のようなことを考えています

  • ソースファイルへの関数の配置
  • 別のソースファイルに何かを分割するとき
  • マスターファイルには何を含める必要がありますか
  • 関数を組織単位として使用する(Rによってグローバル状態へのアクセスが困難になることを考えると、これが価値があるかどうか)
  • インデント/改行の練習。
    • 扱う({?
    • )}のようなものを1行または2行に入れますか?

基本的に、大きなRスクリプトを整理するための経験則は何ですか?

4

10 に答える 10

74

標準的な答えは、パッケージを使用することです。R拡張機能の作成マニュアルおよびWeb上のさまざまなチュートリアルを参照してください。

それはあなたに与えます

  • トピックごとにコードを整理するための準自動化された方法
  • ヘルプファイルを作成して、インターフェイスについて考えさせることを強くお勧めします
  • 経由で多くの健全性チェックR CMD check
  • 回帰テストを追加するチャンス
  • 名前空間の手段と同様に。

コードを実行source()するだけで、非常に短いスニペットで機能します。他のすべてはパッケージに含まれている必要があります。内部リポジトリの内部パッケージを作成できるため、公開する予定がない場合でも同様です。

「編集方法」の部分については、R Internalsのマニュアルのセクション6に優れたRコーディング標準があります。それ以外の場合は、 EmacsのESSモードでデフォルトを使用する傾向があります。

更新2008-Aug-13: DavidSmithがGoogleRスタイルガイドについてブログに書きました。

于 2009-08-12T14:09:44.257 に答える
53

私は自分のファイルにさまざまな機能を入れるのが好きです。

しかし、私はRのパッケージシステムが好きではありません。使いにくいです。

私は、ファイルの関数を環境内(他のすべての言語で「名前空間」と呼ばれるもの)に配置して添付するという、軽量の代替手段を好みます。たとえば、次のような関数の「util」グループを作成しました。

util = new.env()

util$bgrep = function [...]

util$timeit = function [...]

while("util" %in% search())
  detach("util")
attach(util)

これはすべてファイルutil.Rにあります。ソースを作成すると、環境「util」が取得されるため、呼び出すことができますutil$bgrep()。しかし、さらに、attach()呼び出しはそれをとても正しくしbgrep()、そのようなものは直接機能します。これらすべての関数を独自の環境に配置しなかった場合、それらはインタプリタの最上位の名前空間(ls()表示されている名前空間)を汚染します。

すべてのファイルがモジュールであるPythonのシステムをシミュレートしようとしていました。それがあれば良いのですが、これは問題ないようです。

于 2009-08-23T22:42:54.657 に答える
34

これは、特にプログラマーの場合は少し明白に聞こえるかもしれませんが、コードの論理的および物理的な単位について私が考える方法は次のとおりです。

これがあなたの場合かどうかはわかりませんが、私がRで働いているとき、大規模で複雑なプログラムを念頭に置いて始めることはめったにありません。私は通常、1つのスクリプトから始めて、コードを論理的に分離可能な単位に分割します。多くの場合、関数を使用します。データ操作と視覚化のコードは、独自の関数などに配置されます。このような関数は、ファイルの1つのセクションにグループ化されます(上部のデータ操作、次に視覚化など)。最終的には、スクリプトの保守を容易にし、不良率を下げる方法を検討する必要があります。

関数をどの程度細かく/粗くするかはさまざまであり、さまざまな経験則があります。たとえば、15行のコード、または「関数は、その名前で識別される1つのタスクを実行する責任がある」などです。マイレージは異なります。 。Rは参照による呼び出しをサポートしていないため、データフレームや同様の構造体を渡す必要がある場合は、通常、関数を細かく調整しすぎます。しかし、これは、私が最初にRを使い始めたときの、いくつかのばかげたパフォーマンスの間違いに対する過剰な補償かもしれません。

論理ユニットを独自の物理ユニット(ソースファイルやパッケージなどのより大きなグループなど)に抽出するのはいつですか?2つのケースがあります。まず、ファイルが大きくなりすぎて、論理的に関連のないユニット間をスクロールするのは面倒です。第二に、他のプログラムで再利用できる機能がある場合。私は通常、データ操作関数などのグループ化されたユニットを別のファイルに配置することから始めます。その後、他のスクリプトからこのファイルを入手できます。

関数をデプロイする場合は、パッケージについて考え始める必要があります。さまざまな理由で、Rコードを本番環境にデプロイしたり、他のユーザーが再利用したりすることはありません(簡単に言うと、組織文化は他の言語、パフォーマンスに関する懸念、GPLなどを好みます)。また、私は常にソースファイルのコレクションを改良して追加する傾向があり、変更を加えるときにパッケージを処理したくありません。したがって、この面の詳細については、Dirkのような他のパッケージ関連の回答を確認する必要があります。

最後に、あなたの質問は必ずしもRに固有のものではないと思います。このような問題やコーディング慣行全般に関する多くの知識が含まれているSteveMcConnellによるCodeCompleteを読むことを強くお勧めします。

于 2009-08-13T03:02:17.180 に答える
15

私の簡潔な答え:

  1. 関数を注意深く記述し、一般的な十分な出力と入力を特定します。
  2. グローバル変数の使用を制限します。
  3. S3オブジェクトを使用し、必要に応じてS4オブジェクトを使用します。
  4. 特に関数がC/Fortranを呼び出している場合は、関数をパッケージに入れます。

Rは本番環境でますます使用されるようになっていると思います。そのため、再利用可能なコードの必要性は以前よりも高まっています。通訳は以前よりずっと頑強だと思います。RがCよりも100〜300倍遅いことは間違いありませんが、通常、ボトルネックは数行のコードに集中しており、C /C++に委任できます。データ操作や統計分析におけるRの強みを別の言語に委ねるのは間違いだと思います。このような場合、パフォーマンスの低下は少なく、いずれの場合も開発作業を節約する価値があります。実行時間だけが問題だとしたら、私たち全員がアセンブラーを作成することになります。

于 2009-08-16T12:32:24.997 に答える
11

私はパッケージの書き方を理解するつもりでしたが、時間を費やしていません。ミニプロジェクトごとに、すべての低レベル関数を「functions /」というフォルダーに保持し、明示的に作成した別の名前空間にそれらをソースします。

次のコード行は、検索パスに「myfuncs」という名前の環境がまだ存在しない場合は作成し(attachを使用)、「functions/」ディレクトリの.rファイルに含まれる関数を入力します( sys.source)。私は通常、これらの行を、高レベルの関数(低レベルの関数を呼び出す)が呼び出される「ユーザーインターフェイス」用のメインスクリプトの先頭に配置します。

if( length(grep("^myfuncs$",search()))==0 )
  attach("myfuncs",pos=2)
for( f in list.files("functions","\\.r$",full=TRUE) )
  sys.source(f,pos.to.env(grep("^myfuncs$",search())))

変更を加えるときは、いつでも同じ行で再ソースするか、次のようなものを使用できます。

evalq(f <- function(x) x * 2, pos.to.env(grep("^myfuncs$",search())))

作成した環境での追加/変更を評価します。

それは私が知っている厄介なことですが、それについてあまり正式である必要はありません(しかし、機会があれば、パッケージシステムを奨励します-将来的にはそのように移行することを願っています)。

コーディング規約に関しては、これが美学に関して私が見た唯一のことです(私はそれらが好きで、大まかに従いますが、Rではあまり多くの中括弧を使用しません):

http://www1.maths.lth.se/help/R/RCC/

useRでのさまざまなプレゼンテーション(通常は基調講演)で提案された代入演算子として、[、drop = FALSE]と<-の使用に関する他の「規則」があります!会議ですが、これらのいずれも厳密ではないと思います(ただし、[、drop = FALSE]は、期待する入力がわからないプログラムに役立ちます)。

于 2009-08-12T19:41:03.647 に答える
6

パッケージを支持する別の人として私を数えてください。必要な場合(つまりリリースされるまで)まで、マニュアルページやビネットの記述がかなり苦手であることは認めますが、ソースdoeをバンドルするための非常に便利な方法になります。さらに、コードの保守に真剣に取り組む場合、Dirkが提起するポイントはすべてplyaになります。

于 2009-08-19T01:56:32.060 に答える
4

私も同意します。package.skeleton()関数を使用して開始します。コードが二度と実行されないと思われる場合でも、後で時間を節約できる、より一般的なコードを作成する動機付けに役立つ場合があります。

地球環境へのアクセスに関しては、推奨されていませんが、<<-演算子を使用すると簡単にアクセスできます。

于 2009-08-12T17:31:32.737 に答える
3

パッケージの書き方をまだ学んでいないので、私はいつもサブスクリプトを調達して整理してきました。クラスを書くのと似ていますが、それほど複雑ではありません。プログラム的にはエレガントではありませんが、時間の経過とともに分析を積み上げていきます。動作する大きなセクションができたら、それを別のスクリプトに移動して、ワークスペースオブジェクトを使用するため、ソースを作成することがよくあります。おそらく、いくつかのソースからデータをインポートし、それらすべてを並べ替えて、交差点を見つける必要があります。そのセクションを追加のスクリプトに入れるかもしれません。ただし、「アプリケーション」を他の人に配布したい場合、またはインタラクティブな入力を使用する場合は、パッケージがおそらく適切なルートです。研究者として、分析コードを配布する必要はめったにありませんが、多くの場合、それを拡張または微調整する必要があります。

于 2009-08-12T20:19:17.500 に答える
1

私はまた、Rの大規模なプロジェクトをまとめるための適切なワークフローの聖杯を探していました。昨年、私はrsuiteと呼ばれるこのパッケージを見つけました、そして確かに、それは私が探していたものでした。このRパッケージは、大規模なRプロジェクトの展開用に明示的に開発されましたが、小規模、中規模、および大規模のRプロジェクトに使用できることがわかりました。実例へのリンクをすぐに示します(以下)が、最初に、を使用してRプロジェクトを構築する新しいパラダイムについて説明しrsuiteます。

ノート。私はの作成者または開発者ではありませんrsuite

  1. 私たちはRStudioですべて間違ったプロジェクトを行ってきました。目標は、プロジェクトやパッケージの作成ではなく、より広い範囲の作成であるべきです。rsuiteでは、可能なすべての組み合わせで、標準のRプロジェクトとRパッケージを保持するスーパープロジェクトまたはマスタープロジェクトを作成します。

  2. makeRスーパープロジェクトを使用することで、その下にあるRプロジェクトの下位レベルを管理するためのUnixは不要になります。上部でRスクリプトを使用します。披露させて。rsuiteマスタープロジェクトを作成すると、次のフォルダー構造が得られます。

ここに画像の説明を入力してください

  1. このフォルダーRは、プロジェクト管理スクリプトを配置する場所です。これは、を置き換えるものmakeです。

  2. フォルダpackagesrsuite、スーパープロジェクトを構成するすべてのパッケージを保持するフォルダです。インターネットからアクセスできないパッケージをコピーして貼り付けることもでき、rsuiteもそれを構築します。

  3. このフォルダーは、パッケージファイルに示されているすべてのパッケージバイナリを書き込むdeployment場所です。したがって、これにより、それ自体で、完全に再現可能なアクロスタイムを予測できます。rsuiteDESCRIPTION

  4. rsuiteすべてのオペレーティングシステム用のクライアントが付属しています。私はそれらすべてをテストしました。addinただし、RStudio用としてインストールすることもできます。

  5. rsuitecondaまた、独自のフォルダに分離されたインストールを構築することもできますconda。これは環境ではなく、マシンのAnacondaから派生した物理的なPythonインストールです。これはRと連携して機能し、SystemRequirements必要なすべてのPythonパッケージを任意のcondaチャネルからインストールできます。

  6. ローカルリポジトリを作成して、オフラインのときにRパッケージをプルしたり、全体をより高速に構築したりすることもできます。

  7. 必要に応じて、Rプロジェクトをzipファイルとしてビルドし、同僚と共有することもできます。同僚に同じRバージョンがインストールされていれば、実行されます。

  8. もう1つのオプションは、Ubuntu、Debian、またはCentOSでプロジェクト全体のコンテナーを構築することです。したがって、プロジェクトビルドとzipファイルを共有する代わりに、Docker実行の準備ができているプロジェクトとコンテナ全体を共有します。

rsuite私は完全な再現性を探して多くの実験を行っており、グローバル環境にインストールするパッケージに依存することは避けています。これは間違っています。パッケージの更新をインストールするとすぐに、プロジェクトが機能しなくなることがよくあります。特に、特定のパラメーターを持つ関数への非常に特殊な呼び出しを持つパッケージは機能しなくなります。

私が最初に実験を始めたのはbookdown電子ブックでした。私は、6か月以上の時間のテストを生き残るためにブックダウンを持っているほど幸運だったことはありません。それで、私がしたことは、rsuiteフレームワークに従うように元のブックダウンプロジェクトを変換することです。deploymentこれで、プロジェクトのフォルダーに独自のパッケージセットがあるため、グローバルR環境の更新について心配する必要はありません。

次に私がしたことは、機械学習プロジェクトを作成することでしたが、rsuite途中でした。マスター、最上位のオーケストレーションプロジェクト、およびマスターの管理下にあるすべてのサブプロジェクトとパッケージ。これにより、Rを使用したコーディング方法が大幅に変わり、生産性が向上します。

その後、私はと呼ばれる私の新しいパッケージで働き始めましたrTorch。これは、主にrsuite;のために可能でした。それはあなたが考えて大きくなることを可能にします。

ただし、アドバイスが1つあります。学習rsuiteは簡単ではありません。Rプロジェクトを作成する新しい方法を提示するので、それは難しいと感じます。最初の試みでがっかりしないでください、あなたがそれを作るまで斜面を登り続けてください。オペレーティングシステムとファイルシステムに関する高度な知識が必要です。

RStudioいつの日か、メニューのようにオーケストレーションプロジェクトを生み出すことができると期待してrsuiteいます。素晴らしいものになるだろう。

リンク:

RSuiteGitHUbリポジトリ

r4dsブックダウン

ケラスと光沢のあるチュートリアル

moderndive-book-rsuite

解釈可能_ml-rsuite

IntroMachineLearningWithR-rsuite

clark-intro_ml-rsuite

hyndman-bookdown-rsuite

statistics_rethinking-rsuite

fread-benchmarks-rsuite

dataviz-rsuite

Retail-segmentation-h2o-tutorial

telco-customer-churn-tutorial

sclerotinia_rsuite

于 2019-08-04T22:12:26.693 に答える
-6

Rは、インタラクティブな使用や小さなスクリプトには問題ありませんが、大きなプログラムには使用しません。私はほとんどのプログラミングに主流の言語を使用し、それをRインターフェースでラップします。

于 2009-08-12T19:42:45.327 に答える