2012-01-07 6 views
26

[この質問はchat room, by Spacedmanで解決されましたが、私は将来的に他人の利益のためにそれを掲示しています。]R内の関数内のローカル環境をどのように参照できますか?

私はそれのlocalFunc内部を作成する機能、myFuncを、持っています。 (NB:これはパッケージに含まれていませんが、地球環境にあります)localFuncが検索パスに存在する場所を知りたいのですが、mvbutils::foodwebで分析したいと思います。ここで

は一例です。

myFunc <- function(){ 
    require(data.table) 
    require(mvbutils) 
    localFunc <- function(x){ 
     return(as.data.table(x)) 
    } 

    vecPrune <- c("localFunc",ls("package:data.table")) 
    ix <- match("data.table",search()) 
    tmpWeb <- foodweb(where = c(1,ix), prune = vecPrune, plotting = FALSE) 
    return(tmpWeb) 
} 

しかし、myFunc()への呼び出しは、localFuncdata.table()を呼び出すことを示していないようです。これは間違っています - 何がありますか?

(NB:where引数が検索パスを指定する。)


アップデート1:トミーとSpacedmanが指摘するように、トリックenvironment()を指定することです。 foodweb()への呼び出しは、where = c(1, ix)を参照しています。インデックス1は間違いです。それは、search()ベクトルの最初の項目であることが多い(常に?).GlobalEnvが検索する正しい場所であると考えたことから生じました。それは間違いです。代わりに、environment()を参照する必要があり、正しい呼び出しは以下のとおりです。 (NB:ixsearch()data.table()出力での位置を指定)

tmpWeb <- foodweb(where = c(environment(),ix), prune = vecPrune, plotting = FALSE) 

これはローカル関数にRスクリプトファイルからコードをラップcheckScriptDependencies呼び出された関数に、this questionに対する回答に表示され、それをfoodwebによって分析する。これはenvironment()の使い方の制限された例であり、Tommyはこの文脈でそれと同様の機能をどのように使用するかをよく説明しています。

答えて

34

現在の環境を取得するには、environment()を呼び出してください。

一般に、sys.frameは現在コールスタックにある環境のいずれかを返し、sys.nframeはコールスタックの現在の深さを返します。 sys.framesは、コールスタック上のすべての環境のリストを返します。

environment(f)は、関数f(関数とグローバル変数を検索する)のクロージャ環境を返します。

parent.env(e)は、eにシンボルが見つからない場合に表示される親環境を返します。

f <- function() { 
    function() list(curEnv=environment(), parent=parent.env(environment()), 
      grandParent=parent.env(parent.env(environment())), callStack=sys.frames(), 
      callStackDepth=sys.nframe()) 
} 
g <- function(f, n=2) if (n>2) g(f, n-1) else f() 

floc <- f() # generate a local function 
g(floc, 3) # call it 

これは、現在の環境でリストを返す3のスタックの深さでローカル関数flocを呼び出します、それは親(fでローカル環境)だし、それはfが定義された壮大な親(です、従ってglobalenv)。また、スタックフレーム(環境)のリストを返します。これらは、gの再帰呼び出しの環境です(最後のものは現在の環境であるflocです)。

+0

これは私がチャットルームで言ったことです。今すぐ@iterator、彼にチックを与える:) – Spacedman

+0

@Spacedmanあなたはあなたのチャンスを持っていた。:)トミー、ありがとう - 何が起こっているのあなたの精緻化が役立ちます。私はSpacedmanのチャットのコメントから答えを知っていましたが、質問を自己答弁にしたくありませんでした。あなたがしたように、誰かがより説得力のある説明をすることを望んでいました。 – Iterator

+0

curEnvはcallStack [3]と同じですが、parentとgrandparentは他のcallStacksとまったく異なっていますが、なぜですか? – qed

関連する問題