我正在尝试编写一个限制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 :(得分:4)
我不确定您是否希望这样做,但local()
函数应该有帮助,codetools
库也应如此。
在您的示例中,请尝试
f = local( function() { ... }, baseenv())
它并不能完全符合您的要求,但它可以让您更接近。
答案 1 :(得分: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
的参数,使用formalArgs
还是formals
。
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。
答案 2 :(得分:1)
您可以使用exists('y',envir=.GlobalEnv)
答案 3 :(得分:0)
偶然发生在我身上的是我在ESS中有一个分屏,左边是R代码的文件缓冲区,右边是解释器。我可能在解释器中设置了一些值,同时我调试了我在缓冲区中处理的代码。然后,缓冲区中的代码可能会意外地引用我在intepreter中设置的内容。除非我每次都在一个新的解释器中评估我的缓冲区,否则很难检测到问题,这不是ESS默认工作的方式。
如果这是你经常看到的那种问题,你所提供的东西中的rm(list = ls(envir = .GlobalEnv))可能会有所帮助,但这当然会产生其他问题,例如删除它们的任何内容用于在调试时保持状态等