采购时 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" 它是什么。
我发现查找 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" 它是什么。