我首先定义了新的变量x
,然后在其体内创建了需要x
的函数(而不是参数)。见下面的代码
x <- c(1,2,3)
f1 <- function() {
x^2
}
rm(x)
f2 <- function() {
x <- c(1,2,3)
f1()
}
f(2)
Error in f1() : object 'x' not found
当我删除x
并定义首先定义f2
然后执行x
的新功能f1
时,它会显示找不到的对象x
。
我只是想知道为什么这不起作用以及如何克服这个问题。我不希望x
在f1
中成为名称作为参数。
请提供适当的标题,因为我不知道这是什么问题。
答案 0 :(得分:6)
您可以使用closure制作具有所需属性的f1
:
makeF <- function(){
x <- c(1,2,3)
f1 <- function() {
x^2
}
f1
}
f1 <- makeF()
f1() #returns 1 4 9
全局范围内没有x
,但f1
仍然知道它所定义的环境中的x
。
答案 1 :(得分:4)
简而言之:您期待动态范围但是R的词汇范围的受害者:
动态范围=在运行时确定命令的封闭环境
词法范围=命令的封闭环境在&#34;编译时确定&#34;
要了解当前和父环境中变量x
的查找路径,请尝试使用此代码。
它表明这两个函数不共享x
中的f2
定义的环境,因此无法找到它:
# list all parent environments of an environment to show the "search path"
parents <- function(env) {
while (TRUE) {
name <- environmentName(env)
txt <- if (nzchar(name)) name else format(env)
cat(txt, "\n")
if (txt == "R_EmptyEnv") break
env <- parent.env(env)
}
}
x <- c(1,2,3)
f1 <- function() {
print("f1:")
parents(environment())
x^2
}
f1() # works
# [1] "f1:"
# <environment: 0x4ebb8b8>
# R_GlobalEnv
# ...
rm(x)
f2 <- function() {
print("f2:")
parents(environment())
x <- c(1,2,3)
f1()
}
f2() # does not find "x"
# [1] "f2:"
# <environment: 0x47b2d18>
# R_GlobalEnv
# ...
# [1] "f1:"
# <environment: 0x4765828>
# R_GlobalEnv
# ...
可能的解决方案:
在全局环境中声明x
(由于缺少封装而导致编程风格不佳)
使用函数参数(这是函数的作用)
如果x
每次调用f1
时始终具有相同的值,则使用闭包(不适合初学者)。请参阅@JohnColeman的其他答案......
我强烈建议使用2.(添加x作为参数 - 为什么要避免这种情况?)。