2012-01-07 59 views
26

[這個問題已經在解決chat room, by Spacedman,但我張貼他人在未來受益。]如何在R中引用函數中的本地環境?

我有一個函數,myFunc,它在其中創建localFunc。 (注意:這不是在一個包中,而是在全球環境中。)我想知道在搜索路徑中存在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()呼叫似乎並不表明localFunc電話data.table()。這是不正確的 - 什麼給了?

(NB:本where參數指定的搜索路徑。)


更新1:作爲托米和Spacedman指出,關鍵是要指定environment()。撥打foodweb()的電話是指where = c(1, ix)。索引1是一個錯誤。這是因爲認爲.GlobalEnv,它經常(總是?)search()矢量中的第一項,是搜索的正確位置。這是錯誤的。相反,應該參考environment(),正確的調用如下。 (NB:ix指定data.table()search()輸出的位置)

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

這出現在回答this question,在稱爲checkScriptDependencies函數,它包裝從R腳本文件中的代碼轉換爲本地函數,然後通過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 

這將調用本地函數floc爲3。堆棧深度它返回一個列表與當前的環境下,它的父(在f當地的環境),它的盛大母公司(其中f定義,所以globalenv)。它還返回堆棧幀(環境)的列表。這些是g中遞歸調用的環境(除了最後一個是當前環境floc)。

+0

這就是我在聊天室中所說的。現在@iterator,給他打勾:) – Spacedman 2012-01-08 13:04:11

+0

@Spacedman你有機會。:)湯米,謝謝 - 你對發生的事情的闡述是有幫助的。我知道Spacedman的聊天評論的答案,但不想讓問題自我回答。正如你所做的那樣,我希望有人能夠提出更有說服力的解釋。 – Iterator 2012-01-08 14:03:06

+0

curEnv與callStack [[3]]相同,父母和祖父母與其他callStacks完全不同,爲什麼? – qed 2013-06-10 13:54:00