采购时 RStudio 中的环境

Environments in RStudio when sourcing

我发现查找 RStudio 中脚本的 WD 的常用方法是 "dirname(parent.frame(2)$ofile)"。我试图研究它的含义,阅读了很多关于环境的解释,但我仍然没有更深入地理解这个命令。我运行这个脚本:

print(environment())
print(parent.frame(1))
print(parent.frame(2))
print(parent.frame(3))
print(parent.frame(4))

f <- function() {
  print('Do:')
  print(environment())
  print(parent.frame(1))
  print(parent.frame(2))
  print(parent.frame(3))
  print(parent.frame(4))
}

f()

print("Parent 1:")
print(ls(parent.frame(1)))
print("Parent 2:")
print(ls(parent.frame(2)))

print(identical(environment(),parent.frame(1)))
print(identical(environment(),parent.frame(2)))
print(identical(environment(),parent.frame(3)))
print(identical(environment(),parent.frame(4)))

我得到了输出:

<environment: R_GlobalEnv>
<environment: 0x111987ab0>
<environment: 0x107fef700>
<environment: R_GlobalEnv>
<environment: R_GlobalEnv>
[1] "Do:"
<environment: 0x1119957d8>
<environment: R_GlobalEnv>
<environment: 0x111995998>
<environment: 0x107fef700>
<environment: R_GlobalEnv>
[1] "Parent 1:"
[1] "enclos" "envir"  "expr"  
[1] "Parent 2:"
 [1] "chdir"              "continue.echo"      "curr.fun"           "deparseCtrl"       
 [5] "echo"               "ei"                 "enc"                "encoding"          
 [9] "envir"              "exprs"              "file"               "filename"          
[13] "from_file"          "have_encoding"      "i"                  "i.symbol"          
[17] "keep.source"        "lastshown"          "lines"              "loc"               
[21] "local"              "max.deparse.length" "Ne"                 "ofile"             
[25] "print.eval"         "prompt.echo"        "skip.echo"          "spaced"            
[29] "srcfile"            "srcrefs"            "tail"               "use_file"          
[33] "verbose"            "width.cutoff"       "yy"                
[1] FALSE
[1] FALSE
[1] TRUE
[1] TRUE

我不确定我是否理解输出。

1) Global Environment 的 parents 1 和 2 究竟是什么?我在哪里可以阅读更多关于它们的属性,包括使用过的 $ofile?

2) 为什么 parent.frame(1) 不等同于函数内的 parent.frame(2)?它们不是相同的吗 - Global Env 的父级?

3) 为什么当数字足够大时 parent.frame 开始返回全局环境?这只是函数的编写方式还是这个层次结构有一些逻辑?

当您在 parent.frame 上层时,您可以看到调用您的函数的函数的环境。 source() 函数有很多使其工作的代码。它不只是将命令转储到您的控制台中。基本上是 运行 类似

source <- function(...) {
   ...
   eval(ei, envir)
   ...
}

其中 ei 是您文件中的表达式之一。然后eval看起来像这样

eval <- function (expr, envir , enclos = ) {
    .Internal(eval(expr, envir, enclos))
}

因此,当您从源文件中调用的函数调用第一个 parent.frame() 时,它将首先看到 eval() 调用。如果您查看 formals(eval),您会发现它具有您的第一个父项中的那三个变量。第二个父级列出了在 source() 函数本身中创建的所有变量,包括我们刚刚看到的 ei 变量。所以这些值是

# parent.frame(4)
# parent.frame(3)
source <- function(...) {
   # parent.frame(2)
   eval(ei, envir)
}
eval <- function (expr, envir , enclos = ) {
     # parent.frame(1)
    .Internal(eval(expr, envir, enclos))
                  # ^^ your code
}

但 R 中的变量解析不会在调用函数的环境中查找。相反,它使用词法作用域,因此它会查找定义(未调用)函数的位置。如果你想获得那个环境,你可以从函数内部调用 parent.env(environment()) 。用一个简单的函数,你应该得到全局环境。所以这实际上意味着 parent.frame 只是一个不幸的名字,因为那不是 "really" 它是什么。