Imports / Dependsを使用するタイミングのより良い説明


148

R拡張機能の記述」マニュアルには、インポートまたは依存関係をいつ使用するかに関する次のガイダンスが記載されています。

一般的なルールは

  • ライブラリ(pkgname)を使用してパッケージをロードするために名前空間のみが必要なパッケージは、「依存」フィールドではなく「インポート」フィールドにリストする必要があります。
  • library(pkgname)を使用してパッケージを正常にロードするためにアタッチする必要があるパッケージは、「依存」フィールドのみにリストされている必要があります。

誰かがこれについてもう少し明確にできますか?パッケージに名前空間のみが必要な場合と、パッケージを添付する必要がある場合を区別するにはどうすればよいですか?両方の例は何ですか?典型的なパッケージは、他のパッケージの関数を呼び出すことがある関数の集まりにすぎないと思います(多少の作業がすでにコード化されています)。このシナリオは上記の1または2ですか?

編集する

この特定のトピックに関するセクションを含むブログ投稿を書きました(「インポートv依存」を検索してください)。視覚的に理解しやすくなります。


1
あなたのブログ投稿は、私がモジュールの計画を始めたときのパッケージ構造に関するすべてを教えてくれました。ありがとう!
Konrad Rudolph、

回答:


143

"Imports"よりも安全です"Depends"(また、それを使用するパッケージを、を使用する他のパッケージよりも「より良い市民」にします"Depends")。

"Depends"別のパッケージからの機能はメインサーチパス(によって返される環境、すなわちリストに他のパッケージを取り付けることによって利用可能であることを確実にするディレクティブ試みsearch())。ただし、後でロードされる別のパッケージが同じ名前の関数を検索パスの前に配置した場合、この戦略は妨げられる可能性があります。Chambers(SoDA内)は"gam"gamおよびmgcvパッケージの両方にある関数の例を使用します。他の2つのパッケージが読み込まれた場合、1つはに依存しgam、もう1つはに依存しmgcvます。への呼び出しによって検出される関数はgam()、それら2つのパッケージが添付された順序によって異なります。良くない。

"Imports"ディレクティブは、その機能に配置される任意の支持パッケージに使用されるべきである<imports:packageName>(直後検索し<namespace:packageName>、代わりに通常の検索パス上)。上記の例のいずれかのパッケージで"Imports"メカニズム(ファイル内のディレクティブimportまたはimportFromディレクティブも必要)を使用した場合NAMESPACE、問題は2つの点で改善されます。(1)パッケージ自体が、どのmgcv関数を使用するかを制御します。(2)インポートされたオブジェクトからメイン検索パスを離しておくことにより、他のmgcv関数の他のパッケージの依存関係を壊すことさえありません。

これが、名前空間の使用が非常に有効な理由であり、CRANによって強制されるようになった理由であり、(特に)を使用する方"Imports"がを使用するよりも安全な理由"Depends"です。


重要な警告を追加するために編集:

上記のアドバイスには、残念ながら一般的な例外が1つあります。パッケージが、別のパッケージにAあるパッケージに依存している場合、パッケージはディレクティブを使用して添付する必要があります。"Depends"BA"Depends

これは、パッケージ内の関数がA、パッケージBとその関数がsearch()パスに接続されることを想定して記述されているためです。

"Depends"ディレクティブは、ロードしたパッケージを添付しますA、でポイントパッケージA自身の"Depends"原因パッケージは、連鎖反応では、ディレクティブの意志をB同様にロードされ、装着されます。パッケージ内Aの関数はB、依存するパッケージ内の関数を見つけることができます。

"Imports"ディレクティブは、ロードされますが、いないパッケージを添付Aしてますどちらも負荷パッケージを添付しませんB。("Imports"結局のところ、パッケージ作成者は名前空間メカニズムを使用しており、そのパッケージAはアクセスが必要な"Imports"すべての関数を指すために使用されていることを想定していますB。)パッケージA内の関数に依存するパッケージ内の関数への関数による呼び出しBは結果として失敗します。

唯一の2つのソリューションは、次のいずれかです。

  1. ディレクティブAを使用してパッケージにパッケージを添付させます"Depends"
  2. 長期的には、パッケージのメンテナに連絡し、A名前空間を構築するためのより慎重な作業を依頼する(この関連する回答の Martin Morganの言葉で)。

1
最近同様の質問をし、最近これらの問題に大いに取り組んできましたが、これらは微妙でよくコミュニケーションが取れていない概念です。:私はあなたが別の説明についてはこちらを参照してくださいよstackoverflow.com/questions/7880355/...
ブライアン・ハンソン

@BryanHanson-そのリンクにメモを書いてくれてありがとう。ImportsDependswrtのバージョン要件の違い、および.Rdファイル内の例のチェックは実際に微妙であり、知っておく価値があります。
Josh O'Brien

1
「依存」を使用する依存関係に関する警告は恐ろしいことです。つまり、他の人もそうするまで、基本的に私のパッケージで「インポート」を使用することはできません。=(
ケンウィリアムズ

まだはっきりしていないことの1つは、パッケージを作成していて、それをしたいImports: ggplot2場合、なぜパッケージがautoplot関数を見つけられないのですか?明らかDependsにパッケージライブラリを添付しているggplot2ので問題ありません。たとえばautoplot.myFunction()@import ggplot2タグを使用する関数がありますが、パッケージにはありますがImports: ggplot2Error in eval(expr, envir, enclos) : could not find function "autoplot"使用しようとするとエラーが発生します。
nathaneastwood 2015年

1
@ウィレムありがとう。もちろんあなたは正しいです。誤解を招く内容を排除するために、回答を編集しました。これが答えを複雑にした理由の1つは、OPがDependsとのImportsセクションを参照して彼の質問を組み立てた一方で、DESCRIPTION関数に「依存」するのではなく、関数を「インポート」することの意味について本当に尋ねていたことです。後者は私が答えようとした(そして-おそらく-この答えを探しているほとんどの人が知りたいと思っている)質問なので、それ以外の点では答えを変更しません。
Josh O'Brien

31

ハドリー・ウィッカムは簡単な説明をします(http://r-pkgs.had.co.nz/namespace.html):

いずれかのパッケージをリストDependsまたはImports必要なときにそれがインストールされますことを保証します。主な違いはImports、パッケージをロードするだけで、Dependsそれを添付することです。他の違いはありません。[...]

特に理由がない限り、パッケージは常にImportsnotにリストする必要がありますDependsこれは、優れたパッケージは自己完結型であり、グローバル環境(検索パスを含む)への変更を最小限に抑えるためです。唯一の例外は、パッケージが別のパッケージと組み合わせて使用​​するように設計されている場合です。たとえば、アナログパッケージはビーガンの上に構築されます。ビーガンなしでは役に立たないので、のDepends代わりにビーガンになっていImportsます。同様に、ggplot2は、インポートするのではなく、実際にスケールに依存する必要があります。


15

SfDAの商工会議所は、このパッケージが「名前空間」メカニズムを使用している場合に「インポート」を使用するように言っています。すべてのパッケージがそれらを持つ必要があるため、答えは常に「インポート」を使用する可能性があります。以前は、実際に名前空間がなくてもパッケージをロードできましたが、その場合は、Dependsを使用する必要がありました。


2
「imports」でパッケージが指定されていて、パッケージ内の関数を使用したい場合、独自の関数でlibrary(...)を呼び出す必要がありますか、それともすべての関数が検索パスですでに使用可能ですか?また、SfDAとは何ですか?リンク?
SFun28

2
データ分析用のソフトウェアspringer.com/statistics/computanional+statistics/book/… ...質問については、答えはわかりませんが、最小限のテストパッケージを簡単に作り上げて答えを見つけることができます経験的に...
ベン・ボルカー、2011

1
SfDA == "データ分析用ソフトウェア"。[65] r-project.org/doc/bib/R-books.htmlで。パッケージが別のパッケージを指定している場合、コンソールでlibrary()またはrequire()を使用すると、depend(encies)およびimport(ations)のロードについて通知するメッセージが表示されます。はい、利用できるはずです。
IRTFM 2011

4
+1-これも私の強い印象です。また、importsで指定されたパッケージは<namespace:packageName>、の一部として、の直後に検索されます<imports:packageName>。これ以上の呼び出しlibrary()は必要ありませんImport。edパッケージが見つからない場合を除き、Rはパッケージのロード時にコンソールで通知しません。
Josh O'Brien

5

使用するものを決定するのに役立つ簡単な質問を次に示します。

あなたのパッケージは、エンドユーザーが別のパッケージの機能に直接アクセスできる必要がありますか?

  • いいえ->インポート(最も一般的な答え)
  • はい->依存

「Depends」を使用する必要があるのは、パッケージが別のパッケージのアドオンまたはコンパニオンの場合のみです。エンドユーザーは、パッケージと「Depends」パッケージの両方の関数をコードで使用します。エンドユーザーが関数とのみやり取りし、他のパッケージがバックグラウンドでのみ機能する場合は、代わりに「インポート」を使用します。

これに対する警告は、通常どおりにパッケージを「インポート」に追加する場合、コードはそのパッケージから関数を参照する必要があることです。たとえばdplyr::mutate()、だけではなく、完全な名前空間構文を使用しますmutate()。コードを読むのが少し不格好になりますが、パッケージの衛生状態を改善するために支払うのは少額です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.