R 名前空間は、関連付けられたパッケージ内のすべての関数の直接の環境として機能します。言い換えると、bar()
パッケージfooの関数が別の関数を呼び出すとき、R エバリュエーターは、最初に 内<environment: namespace:foo>
、次に 、"imports.foo"
、<environment: namespace:base>
という<environment: R_GlobalEnv>
ように、 と入力して返された検索リストを下方向に別の関数を検索しますsearch()
。
名前空間の優れた側面の 1 つは、パッケージをより良い市民のように振る舞わせることができる<environment: namespace:foo>
ことimports:foo
です。(b) fooからインポートする他のパッケージへ。または (c) のような完全修飾関数呼び出しを介して。foo:::bar()
と、最近まで思っていたのですが…
振る舞い
この最近の SO の質問では、パッケージの名前空間に十分に隠されている関数が、一見無関係な関数の呼び出しによって見つかったというケースが強調されました。
group <- c("C","F","D","B","A","E")
num <- c(12,11,7,7,2,1)
data <- data.frame(group,num)
## Evaluated **before** attaching 'gmodels' package
T1 <- transform(data, group = reorder(group,-num))
## Evaluated **after** attaching 'gmodels
library(gmodels)
T2 <- transform(data, group = reorder(group,-num))
identical(T1, T2)
# [1] FALSE
その直接の原因
@Andrie は、gmodelsがパッケージ gdata からインポートされることを指摘して、元の質問に答えました。最初のものは によって計算され、2 番目のものは によって計算されるため、とは異なります。reorder.factor
transform()
T1
T2
stats:::reorder.default()
gdata:::reorder.factor()
私の質問
上記の への呼び出しtransform(data, group=reorder(...))
で、ディスパッチ メカニズムがreorder
検出されてから にディスパッチされるのはgdata:::reorder.factor()
どうしてでしょうか。
(回答には、 statsおよびbaseパッケージの関数を含む呼び出しからgdataの一見よく隠されているメソッドにつながるスコープ規則の説明が含まれている必要があります。)
さらに役立つ可能性のある詳細
どちら
gdata:::reorder.factor
もgdataパッケージ全体もgmodelsによって明示的にインポートされません。gmodelsのNAMESPACEファイルのimport*
ディレクティブは次のとおりです。importFrom(MASS, ginv) importFrom(gdata, frameApply) importFrom(gdata, nobs)
reorder()
またはtransform()
in<environment: namespace:gmodels>
、または inのメソッドはありません"imports:gmodels"
。ls(getNamespace("gmodels")) ls(parent.env(getNamespace("gmodels")))
gmodels をデタッチしても の動作は元に戻りません
reorder()
:gdata:::reorder.factor()
それでもディスパッチされます:detach("package:gmodels") T3 <- transform(data, group=reorder(group,-num)) identical(T3, T2) # [1] TRUE
reorder.factor()
ベース環境の S3 メソッドのリストに保存されていません。grep("reorder", ls(.__S3MethodsTable__.)) # integer(0)
ここ数日の R チャット スレッドには、いくつかの追加のアイデアが含まれています。Andrie、Brian Diggs、Gavin Simpson に感謝します。この質問の詳細。