2010-07-18 131 views
10

我試圖編寫一個函數,它限制了R變量的範圍。例如,限制變量範圍

source("LimitScope.R") 
y = 0 
f = function(){ 
    #Raises an error as y is a global variable 
    x = y 
} 

我想過測試變量環境,但並不確定如何做到這一點。

的原因

我教R鍵本科生。在他們的第一對實踐中,他們中的一些人總是忘記變量作用域,所以他們提交的函數不起作用。舉例來說,我總是得到類似的東西:

n = 10 
f = function(x){ 
    #Raises an error 
    #as I just source f and test it for a few test cases. 
    return(x*n) 
} 

我在一個快速的函數後會'關閉'範圍。正如你可以想象的那樣,它不一定非常強大,因爲它只是爲少數實際情況提供的。

+0

出於興趣,您爲什麼要這麼做? – 2010-07-19 13:13:59

+0

我在答案中添加了一個關於爲什麼要這樣做的部分。 – csgillespie 2010-08-06 16:18:29

+0

參見http://stackoverflow.com/questions/6216968/r-force-local-scope – 2011-11-17 01:33:07

回答

4

我不確定你是否想要這樣做,但local()函數應該有所幫助,codetools庫也是如此。

在你的榜樣,儘量

f = local(function() { ... }, baseenv()) 

它不會做你想要什麼,但它應該讓你更接近。

1

您可以檢查如果y存在於使用exists('y',envir=.GlobalEnv)

3

可以強制變量是本地版本與此功能的全球環境:

get_local <- function(variable) 
{ 
    get(variable, envir = parent.frame(), inherits = FALSE) 
} 

比較這些情況

y <- 0  
f <- function() 
{ 
    x <- y 
}  
print(f())  # 0 

y <- 0  
f <- function() 
{ 
    y <- get_local("y") 
    x <- y 
}  
print(f())  # Error: 'y' not found 

根據你在做什麼,你可能還想檢查y是否是f的參數,使用formalArgsformals

g <- function(x, y = TRUE, z = c("foo", "bar"), ...) 0 

formalArgs(g) 
# [1] "x" "y" "z" "..." 

formals(g) 
#$x 
# 
# 
#$y 
#[1] TRUE 
# 
#$z 
#c("foo", "bar") 
# 
#$... 

編輯:的「如何關閉詞法作用域而不改變功能的內容」是難以解決的更一般的點。我相當肯定,範圍規則是根深蒂固的R.另一種方法可能是使用S-Plus,因爲它有different scoping rules

0

偶然發生在我身上的是我在ESS中有一個分割屏幕,左邊是一個R代碼的文件緩衝區,右邊是解釋器。我可能在解釋器中設置了一些值,同時我調試了我在緩衝區中工作的代碼。然後,緩衝區中的代碼可能意外地引用了我在英文中設置的內容。除非我每次都在全新的解釋器中評估我的緩衝區,否則很難檢測到問題,這不是ESS默認情況下的工作方式。

如果這是您經常看到的問題,那麼源代碼中的rm(list = ls(envir = .GlobalEnv))可能會有所幫助,但這當然會產生其他問題,例如擦除它們的任何內容在調試時用於保持狀態等。