複雑なRプロジェクトに着手すると、私のスクリプトはすぐに長くて混乱します。
私のコードを常に楽しみたいと思うように、私が採用できるプラクティスは何ですか?私は次のようなことを考えています
基本的に、大きなRスクリプトを整理するための経験則は何ですか?
標準的な答えは、パッケージを使用することです。 R Extensionsの記述 マニュアルおよびWeb上のさまざまなチュートリアルを参照してください。
それはあなたに与えます
R CMD check
_による多くの健全性チェックコード上でsource()
を実行するだけで、本当に短いスニペットで機能します。内部リポジトリ用の内部パッケージを作成できるので、それを公開する予定がない場合でも、それ以外はすべてパッケージに含める必要があります。
「編集方法」の部分については、セクション6の R Internals マニュアルに優れたRコーディング標準があります。 EmacsのESSモード でデフォルトを使用する傾向があります。
Update 2008-Aug-13:David Smithが Google R Style Guide についてブログに書きました。
独自のファイルにさまざまな機能を追加するのが好きです。
しかし、私はRのパッケージシステムが好きではありません。使いにくいです。
環境内にファイルの機能(他のすべての言語が「名前空間」と呼んでいるもの)を配置し、添付するための軽量の代替手段を好みます。たとえば、次のような関数の「util」グループを作成しました。
_util = new.env()
util$bgrep = function [...]
util$timeit = function [...]
while("util" %in% search())
detach("util")
attach(util)
_
これはすべてファイル内にあります til.R 。ソースを取得すると、「util」環境が得られるため、util$bgrep()
などを呼び出すことができます。しかし、さらにattach()
呼び出しはbgrep()
だけを呼び出し、そのようなものは直接動作します。これらのすべての関数を独自の環境に配置しなかった場合、それらはインタープリターのトップレベル名前空間(ls()
が示すもの)を汚染します。
すべてのファイルがモジュールであるPythonのシステムをシミュレートしようとしていました。持っていた方が良いでしょうが、これは問題ないようです。
特にプログラマーの場合、これは少し明白に聞こえるかもしれませんが、ここではコードの論理的および物理的単位について考える方法を示します。
これがあなたの場合かどうかはわかりませんが、Rで作業しているとき、大規模で複雑なプログラムを念頭に置いて始めることはめったにありません。通常、1つのスクリプトで開始し、コードを論理的に分離可能なユニットに分離します。多くの場合、関数を使用します。データ操作および視覚化コードは、独自の関数などに配置されます。また、そのような関数は、ファイルの1つのセクションにグループ化されます(上部のデータ操作、視覚化など)。最終的には、スクリプトを簡単に保守して欠陥率を下げる方法を考えたいと思います。
機能をどの程度細かく/粗くするかはさまざまであり、さまざまな経験則があります。 15行のコード、または「関数は名前で識別される1つのタスクを実行する必要があります」など。あなたのマイレージは異なります。 Rは参照による呼び出しをサポートしていないので、データフレームや同様の構造体を渡す必要がある場合、通常は関数を細かくしすぎます。しかし、これは私が最初にRで始めたときのいくつかのばかげたパフォーマンスの間違いに対する過剰な補償かもしれません。
論理ユニットを独自の物理ユニット(ソースファイルやパッケージなどのより大きなグループなど)に抽出する場合二つのケースがあります。まず、ファイルが大きくなりすぎて、論理的に無関係なユニット間をスクロールするのが面倒な場合。第二に、他のプログラムで再利用できる機能がある場合。通常は、データ操作関数などのグループ化されたユニットを別のファイルに配置することから始めます。その後、このファイルを他のスクリプトから取得できます。
関数をデプロイする場合は、パッケージについて考え始める必要があります。さまざまな理由で、Rコードを実稼働環境で展開したり、他の人が再利用したりすることはありません(簡単に言うと、組織文化は他の言語、パフォーマンスに関する懸念、GPLなどを好みます)。また、ソースファイルのコレクションを絶えず改良して追加する傾向があり、変更を加える際にはパッケージを扱いたくありません。したがって、この面の詳細については、Dirkのような他のパッケージ関連の回答を確認してください。
最後に、あなたの質問は必ずしもRに特定のものではないと思います。SteveMcConnellのCode Completeを読むことをお勧めします。
ダークのアドバイスに同意します!私見、単純なスクリプトから文書化されたパッケージへのプログラムの編成は、Rでのプログラミングの場合、WordからTeX/LaTeXに切り替えて作成するようなものです。 Friedrich Leischによる非常に便利なRパッケージの作成:チュートリアルをご覧になることをお勧めします。
私の簡潔な答え:
Rは実稼働環境でますます使用されているため、再利用可能なコードの必要性は以前よりも大きくなっています。通訳は以前よりもずっと堅牢だと思います。 RがCよりも100〜300倍遅いことは間違いありませんが、通常、ボトルネックはC/C++に委任できるコードの数行に集中しています。データ操作と統計分析におけるRの長所を他の言語に委任するのは間違いだと思います。これらの場合、パフォーマンスのペナルティは低く、いずれにしても開発労力を節約する価値があります。実行時間だけが問題であれば、私たちはすべてアセンブラーを作成することになります。
私はパッケージの書き方を理解するつもりでしたが、時間を費やしていません。ミニプロジェクトごとに、低レベル関数をすべて「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]は、期待する入力がわからないプログラムには便利です)。
パッケージを好むもう一人の人として私を数えてください。マニュアルページやビネットを書く必要があるかどうか(リリースされるまで)はかなり貧弱であることは認めますが、それはソースdoeをバンドルする本当に便利な方法になります。さらに、コードの保守について真剣に考えると、Dirkが提起するポイントはすべてplyaになります。
私も同意します。 package.skeleton()関数を使用して開始します。コードが再び実行されることはないと思う場合でも、後で時間を節約できるより一般的なコードを作成する動機付けに役立つ場合があります。
グローバル環境へのアクセスに関しては、<<-演算子を使用すると簡単ですが、推奨されません。
パッケージの書き方をまだ学んでいないので、私は常にサブスクリプトを調達することで整理してきました。クラスを書くことに似ていますが、それほど複雑ではありません。プログラム的にエレガントではありませんが、時間の経過とともに分析を積み重ねていきます。動作する大きなセクションを作成したら、ワークスペースオブジェクトを使用するため、それを別のスクリプトに移動して、単にソースにするだけです。おそらく、いくつかのソースからデータをインポートし、それらをすべてソートして、交差点を見つける必要があります。そのセクションを追加のスクリプトに入れることができます。ただし、「アプリケーション」を他の人に配布したい場合、または何らかのインタラクティブな入力を使用する場合は、おそらくパッケージが適切なルートです。研究者として、私は分析コードを配布する必要はほとんどありませんが、頻繁にそれを増強または微調整する必要があります。
また、R大規模プロジェクトをまとめるための適切なワークフローの聖杯を探しています。昨年、このパッケージは rsuite と呼ばれていましたが、私が探していたものでした。このRパッケージは、大規模なRプロジェクトの展開用に明示的に開発されましたが、小規模、中規模、大規模なRプロジェクトに使用できることがわかりました。実世界の例へのリンクをすぐに(下記)提供しますが、最初にrsuite
を使用してRプロジェクトを構築する新しいパラダイムを説明します。
注意。私はrsuite
の作成者でも開発者でもありません。
私たちはRStudioですべて間違ったプロジェクトを行ってきました。目標は、プロジェクトやパッケージの作成ではなく、より大きなスコープの作成であるべきです。 rsuiteでは、スーパープロジェクトまたはマスタープロジェクトを作成します。これは、可能なすべての組み合わせで、標準のRプロジェクトとRパッケージを保持します。
Rスーパープロジェクトを作成することにより、下位のRプロジェクトの下位レベルを管理するためにUnix make
は必要なくなります。上部でRスクリプトを使用します。披露させて。 rsuiteマスタープロジェクトを作成すると、次のフォルダー構造が得られます。
フォルダーR
は、プロジェクト管理スクリプトを配置する場所であり、make
を置き換えるものです。
フォルダーpackages
は、rsuite
がスーパープロジェクトを構成するすべてのパッケージを保持するフォルダーです。また、インターネットからアクセスできないパッケージをコピーして貼り付けることもできます。rsuiteも同様にビルドします。
フォルダーdeployment
は、_rsuite
がパッケージDESCRIPTION
ファイルで示されたすべてのパッケージバイナリを書き込む場所です。したがって、これにより、完全に再現可能な時間を予測できます。
rsuite
には、すべてのオペレーティングシステム用のクライアントが付属しています。私はそれらをすべてテストしました。ただし、RStudioのaddin
としてインストールすることもできます。
rsuite
では、独自のフォルダーconda
に分離conda
インストールを構築することもできます。これは環境ではなく、マシンのAnacondaから派生した物理Pythonインストールです。これは、RのSystemRequirements
と連携して動作します。Rから、必要なcondaチャネルから、必要なPythonパッケージをすべてインストールできます。
また、オフラインのときにRパッケージをプルするローカルリポジトリを作成したり、すべてをより速くビルドしたりすることもできます。
必要に応じて、RプロジェクトをZipファイルとしてビルドし、同僚と共有することもできます。同僚に同じRバージョンがインストールされていれば実行されます。
別のオプションは、Ubuntu、Debian、またはCentOSでプロジェクト全体のコンテナを構築することです。そのため、プロジェクトビルドでZipファイルを共有する代わりに、Docker
コンテナー全体をプロジェクトの実行準備が整った状態で共有します。
rsuite
で多くの実験を行って、完全な再現性を求め、グローバル環境にインストールするパッケージに依存しないようにしています。パッケージの更新をインストールするとすぐに、プロジェクトが動作を停止することが多いため、これは間違っています。特に、特定のパラメーターを持つ関数への非常に具体的な呼び出しを持つパッケージです。
私が最初に実験を始めたのは、bookdown
の電子書籍でした。私は、6か月以上の時の試練を乗り切るためのブックダウンができるほど幸運ではありませんでした。だから、私がしたことは、元のブックダウンプロジェクトをrsuite
フレームワークに従うように変換することです。プロジェクトのdeployment
フォルダーに独自のパッケージセットがあるため、グローバルなR環境の更新について心配する必要はありません。
次にしたことは、機械学習プロジェクトを作成することでしたが、rsuite
の方法で作成しました。マスター、最上位のオーケストレーションプロジェクト、およびマスターの制御下にあるすべてのサブプロジェクトとパッケージ。 Rでコーディングする方法が本当に変わり、生産性が向上します。
その後、rTorch
という私の新しいパッケージで作業を始めました。これは、主にrsuite
;により可能になりました。考えて大きくなることができます。
ただし、アドバイスがあります。 rsuite
の学習は簡単ではありません。 Rプロジェクトを作成する新しい方法を提示するため、苦労します。最初の試みでがっかりしないでください、あなたがそれを作るまで斜面を登り続けてください。オペレーティングシステムとファイルシステムの高度な知識が必要です。
いつの日かRStudio
により、メニューからrsuite
が行うようなオーケストレーションプロジェクトを生成できるようになります。素晴らしいものになるだろう。
リンク: