2011-09-02 10 views
29

Rの名前空間メカニズムは、ユーザが見ることができる機能を1つ〜exportに許可します。さらに、他のパッケージの機能をimportにすることができます。輸出の利益は明らかですが、私は輸入の利益を理解する上でより多くの問題があります。Rの名前空間でのインポートの利点は何ですか?

1つの利点は、パッケージを添付してメモリを節約することなく他のパッケージの機能を使用できることです。これはセクション1.6.4 in the writing R extensions manualに例示されている。

ただし、インポート機能には他にも利点があります。特に、section 1.6.6 (that deals with S4 classes)はstats4パッケージのnamespaceを示す:

export(mle) 
importFrom("graphics", plot) 
importFrom("stats", optim, qchisq) 
## For these, we define methods or (AIC, BIC, nobs) an implicit generic: 
importFrom("stats", AIC, BIC, coef, confint, logLik, nobs, profile, 
      update, vcov) 
exportClasses(mle, profile.mle, summary.mle) 
## All methods for imported generics: 
exportMethods(coef, confint, logLik, plot, profile, summary, show, update, vcov) 
## implicit generics which do not have any methods here 
export(AIC, BIC, nobs) 

ここS4クラスもジェネリックでもないインポートされた機能は、(それがthat section例に記載されているように、同様にインポートを使用することが理にかなっている)が存在しますRが起動すると自動的にロードされるgraphicsパッケージのplotのような機能を実行します。

私の質問は、plot,optimまたはqchisqのような関数をインポートする利点は何ですか?

答えて

23

ファンクションfooがパッケージバーからインポートされた場合、ファンクションfooを持つパッケージBazを添付するなどして、ユーザが検索パスに対して行う操作に関係なく検出されます。名前空間がなければ、パッケージコードはBaz::fooを使用して突然見つかるでしょう。効率の問題もあります(fooは検索パス上のすべてのシンボルを検索した後ではなく直ちに見つかります)。しかし、ほとんどのアプリケーションではこれは簡単なことです。同様に、importFromは、より少ない衝突(または意図しない機能の使用)およびより効率的なルックアップのためにimportよりも改善されています。

S4(とS3)を使うと、かなり複雑になることがあります。 graphics::plotのような非ジェネリック関数は、2つの異なるパッケージでジェネリック(setGeneric)に昇格させることができ、それぞれのジェネリックに独自のメソッドセットをアタッチすることができます。パッケージ作成者は、plotが一般的であるため、どのメソッドのディスパッチテーブル、それらのクラスおよびメソッドが正確かを知りたいと考えます。

pkg::fooで関数を呼び出すと、常に目的の関数に解決されます。 pkgはDESCRIPTIONファイルのDepends:フィールド(Importsにあるかもしれませんが、pkgからインポートしないような誤解を招くような広告のようです)にリストされ、ユーザーの検索パスが汚染されている必要があります。また、2つのシンボルルックアップと関数呼び出し(::)が含まれているため、効率が悪いです。私の怠惰で注意深さの欠如の部分は、::の使用が退屈でエラーが起こりやすいとも見ています。

パッケージcodetoolsBioC(ユーザー名とパスワードreadonlyとSVNを経由して)既存のパッケージから名前空間ファイルを生成することができます(あるいは少なくともそれはR-develのの最近の変更はなしでパッケージの名前空間を導入することができる前に、私はそうではありませんそのようなパッケージでcodetoolsBioCを試しました)。

+0

つまり、そのような関数をインポートすることは、その関数を汎用的に宣伝したい場合にのみ意味があります。 (検索パスに 'plot'と呼ばれる他の関数がないと仮定したい場合) – Henrik

+2

パッケージが使用する関数(常に利用可能なbase以外のパッケージから)をインポートすることは常に理にかなっています。 3番目のパッケージは 'plot = function(...) 'という関数を定義しています。ユーザーは検索パスを制御できません。 –

+0

しかし、私が常に '::'演算子を使って関数を呼び出すと(例えば 'plot()'の代わりに常に 'graphics :: plot()')、パッケージがすでに接続されている場合はインポートの利点はありますか? – Henrik