这可能不是正确的术语,但希望我可以理解我的观点.
我经常最终做类似的事情:
myVar = 1
f <- function(myvar) { return(myVar); }
# f(2) = 1 now
Run Code Online (Sandbox Code Playgroud)
R愉快地使用了函数范围之外的变量,这让我摸不着头脑,想知道我怎么可能得到我的结果.
是否有任何选项说"强迫我只使用之前已在此功能范围内分配值的变量"?use strict例如,Perl就是这样做的.但我不知道R有相当于my.
编辑:谢谢,我知道我对他们的看法不同.实际上,这个例子是专门为说明这个问题而创建的!
我想知道当我这样做时R是否可以自动警告我.
编辑2:此外,如果Rkward或其他IDE提供此功能,我也想知道.
Tom*_*mmy 28
据我所知,R没有提供"使用严格"模式.所以你有两个选择:
1 - 确保所有"严格"功能都没有globalenv作为环境.你可以为此定义一个很好的包装函数,但最简单的是调用local:
# Use "local" directly to control the function environment
f <- local( function(myvar) { return(myVar); }, as.environment(2))
f(3) # Error in f(3) : object 'myVar' not found
# Create a wrapper function "strict" to do it for you...
strict <- function(f, pos=2) eval(substitute(f), as.environment(pos))
f <- strict( function(myvar) { return(myVar); } )
f(3) # Error in f(3) : object 'myVar' not found
Run Code Online (Sandbox Code Playgroud)
2 - 进行代码分析,警告您"使用不当".
这是一个checkStrict有希望做你想要的功能.它使用了优秀的codetools包装.
# Checks a function for use of global variables
# Returns TRUE if ok, FALSE if globals were found.
checkStrict <- function(f, silent=FALSE) {
vars <- codetools::findGlobals(f)
found <- !vapply(vars, exists, logical(1), envir=as.environment(2))
if (!silent && any(found)) {
warning("global variables used: ", paste(names(found)[found], collapse=', '))
return(invisible(FALSE))
}
!any(found)
}
Run Code Online (Sandbox Code Playgroud)
尝试一下:
> myVar = 1
> f <- function(myvar) { return(myVar); }
> checkStrict(f)
Warning message:
In checkStrict(f) : global variables used: myVar
Run Code Online (Sandbox Code Playgroud)
Ben*_*ker 12
checkUsage在codetools包中是有帮助的,但不会让你一路走来.在myVar没有定义的干净会话中,
f <- function(myvar) { return(myVar); }
codetools::checkUsage(f)
Run Code Online (Sandbox Code Playgroud)
给
<anonymous>: no visible binding for global variable ‘myVar’
Run Code Online (Sandbox Code Playgroud)
但是一旦你定义myVar,checkUsage就很高兴.
请参阅?codetools在codetools包:这可能是一些有有用:
> findGlobals(f)
[1] "{" "myVar" "return"
> findLocals(f)
character(0)
Run Code Online (Sandbox Code Playgroud)
使用get(x, inherits=FALSE)将强制本地范围.
myVar = 1
f2 <- function(myvar) get("myVar", inherits=FALSE)
f3 <- function(myvar){
myVar <- myvar
get("myVar", inherits=FALSE)
}
Run Code Online (Sandbox Code Playgroud)
输出:
> f2(8)
Error in get("myVar", inherits = FALSE) : object 'myVar' not found
> f3(8)
[1] 8
Run Code Online (Sandbox Code Playgroud)
modulesCRAN上有一个新的软件包可以解决这个常见问题(请参阅此处的插图).使用时modules,该函数会引发错误,而不是静默返回错误的结果.
# without modules
myVar <- 1
f <- function(myvar) { return(myVar) }
f(2)
[1] 1
# with modules
library(modules)
m <- module({
f <- function(myvar) { return(myVar) }
})
m$f(2)
Error in m$f(2) : object 'myVar' not found
Run Code Online (Sandbox Code Playgroud)
这是我第一次使用它.它似乎很简单,所以我可以将它包含在我的常规工作流程中,以防止出现耗时的事故.
你需要修正错字: myvar!= myVar.那一切都会奏效......
范围分辨率是从内到外的'从内到外',然后是封闭的,依此类推.
编辑现在您已经澄清了您的问题,请查看包codetools(它是R Base集的一部分):
R> library(codetools)
R> f <- function(myVAR) { return(myvar) }
R> checkUsage(f)
<anonymous>: no visible binding for global variable 'myvar'
R>
Run Code Online (Sandbox Code Playgroud)