我试图通过save()
保存函数调用中的变量f <- function(x) {
r <- x - g(x)
r
}
g <- function(y) {
r <- y * h(y)
r
}
h <- function(z) {
save(list = ls(all = TRUE), file = "hello.RData", envir = parent.frame())
r <- log(z)
if (r < 10)
r^2
else r^3
}
然而,这会返回错误&#34;找不到对象z&#34;,即使根据文档,parent.frame()是envir的标准值。
save(list = ls(all = TRUE), file = "hello.RData", envir = sys.frame())
不起作用
save(list = ls(all = TRUE), file = "hello.RData")
这很有效。但对我来说,如果没有文件中给出的标准值,那对环境来说实际上是什么有点神秘。
错误的原因是什么?为什么父框架要在save()中查看标准环境?
答案 0 :(得分:2)
需要注意的重要一点是,评估函数的默认值和传入的值的位置之间存在差异。考虑
ff<-function(a, b=a+2) {print(b)}
ff(2);
# [1] 4
ff(2, a+2);
# Error in print(b) : object 'a' not found
尽管b
的“默认”是a+2
,但我们不能只传递a+2
,因为它需要在不同的背景下进行评估。
这是另一个例子
gg<-function(a) {
ff(2, match.call());
}
ff<-function(a, b=match.call()) {
print(b)
}
ff(2);
# ff(a = 2)
gg(2)
# gg(a = 2);
尽管gg
将相同的“默认值”传递给ff
,但我们会遇到不同的行为。
这就是save(..., envir=parent.frame())
发生的事情。当您在h()
中调用该功能时,您将从调用h()
的位置获取帧,但如果您未指定环境,则save
调用parent.frame()
时, save
将获取调用save()
的框架。如果您想将当前环境明确地传递给save()
,您可以
save(list = ls(all = TRUE), file = "hello.RData", envir=environment())
但这基本上与不指定envir=
参数完全相同。
所以文档是正确的,只是行为不同,取决于实际调用parent.frame()
的人。
答案 1 :(得分:0)
这个问题与范围界定有关。有关范围界定的深入描述,请查看本文http://adv-r.had.co.nz/Functions.html#lexical-scoping
首先,通过指定envir = parent.frame(),您将选择全局环境。这是因为您的函数未在另一个函数或对象中定义。例如,请参阅下面定义的两个不同h函数中打印parent.frame之间的区别。
!> h <- function(z){
+ print(parent.frame())
+ }
>
>
> h(10)
<environment: R_GlobalEnv>
>
> h <- function(z){
+ b <- function(){
+ print(parent.frame())}
+ b()
+ }
>
> h()
<environment: 0x10f06b3c0>
我相信你要么想把你的函数嵌套在彼此里面(如上面的函数h和b所示),要么声明一个'全局变量'。这是由
完成的<<-
命令
例如:
> h <- function(z) {
+ r <<- log(z)
+ if (r < 10){
+ r <<- r^2}
+ else r<<- r^3
+ }
> h(1)
> r
[1] 0
> h(10)
> r
[1] 5.301898
> h(10000)
!> r
[1] 84.83037