save(),意外行为

时间:2014-07-22 17:12:18

标签: r save

我试图通过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()中查看标准环境?

2 个答案:

答案 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