是否可以设置一个函数';在R中运行时,s环境?

是否可以设置一个函数';在R中运行时,s环境?,r,function,R,Function,如果定义函数,默认情况下它们都是全局环境的一部分。 我想知道是否有办法将函数的父环境设置为调用环境(而 运行时-函数可能在不同的位置被调用!)。因此,对于嵌套函数, 应该可以只在一个环境中定义一个变量,我希望有这样的例子 fun1 <- function() { # variable "my_env" defined only in this environment subfun() # calls subsubfun() return(NULL) }

如果定义函数,默认情况下它们都是
全局环境的一部分。
我想知道是否有办法将函数的父环境设置为调用环境(而
运行时-函数可能在不同的位置被调用!)。因此,对于嵌套函数,
应该可以只在一个环境中定义一个变量,我希望有这样的例子

fun1 <- function() {
  # variable "my_env" defined only in this environment
  subfun() # calls subsubfun()
  return(NULL)
} 
从docs
?parent.frame

sys.parent如果n为1,则返回父帧的编号 默认设置),如果n为2,则为祖父母,依此类推。另请参见“注释”。
(…)父帧(n)是 sys.frame(sys.parent(n))(实现效率稍高)


严格来说,sys.parentparent.frame指的是 父解释函数。因此,内部功能(可能或 可能不会设置上下文,因此可能会或可能不会出现在调用堆栈上) 可能不会被计算在内,S3方法也可以做一些令人惊讶的事情。 注意延迟计算的影响:这两个函数 在计算调用堆栈时,而不是在调用堆栈 我们称之为。将调用作为函数参数传递给它们不太可能 这是个好主意

首先是一个示例,它不起作用,因为所有函数都是全局环境的一部分

subfun0 <- function() {
  e <- parent.frame()
  attr(e, "name") <- "my_env"
  assign("my_env", 1,
         envir = parent.frame(),
         inherits = FALSE, immediate = TRUE)
  return(NULL)
}

subsubfun <- function() {
  print("  subsubfun")
  print("  =========")
  print(exists("my_env"))
  print(exists("my_env", parent.frame()))
  env <- parent.frame()
  print(exists("my_env", parent.env(env)))
  return(NULL)
}

subfun <- function() {
  print(" subfun")
  print(" ======")
  print(exists("my_env"))
  print(exists("my_env", parent.frame()))
  env <- parent.frame()
  print(exists("my_env", parent.env(env)))
  subsubfun()
  return(NULL)
}

fun1 <- function() {
  print("fun1")
  print("====")
  subfun0()
  print(exists("my_env"))
  print(exists("my_env", parent.frame()))
  env <- parent.frame()
  print(exists("my_env", parent.env(env)))
  subfun()
  return(NULL)
}

fun1()

subfun0使用此代码,您可以获得您想要的:

subfun0 <- function() {
    e <- parent.frame()
    attr(e, "name") <- "my_env"
    assign("my_env", 1,
                 envir = parent.frame(),
                 inherits = FALSE, immediate = TRUE)
    return(NULL)
}

subsubfun <- function() {
    print("  subsubfun")
    print("  =========")
    print(exists("my_env"))
    print(exists("my_env", parent.frame()))
    print(exists("my_env", parent.frame(2)))
    return(NULL)
}

subfun <- function() {
    print(" subfun")
    print(" ======")
    print(exists("my_env"))
    print(exists("my_env", parent.frame()))
    print(exists("my_env", parent.frame(2)))
    subsubfun()
    return(NULL)
}

fun1 <- function() {
    print("fun1")
    print("====")
    subfun0()
    print(exists("my_env"))
    print(exists("my_env", parent.frame()))
    print(exists("my_env", parent.frame(2)))
    subfun()
    return(NULL)
}

fun1()

关键是:
parent.frame(2)
不等于
parent.env(parent.frame())

我不明白您为什么需要它。。为什么不能直接将参数传递给函数?或者为什么不将环境作为参数传递?@Edo我希望跟踪特殊变量,而无需重写每个函数。我认为这会增加一些很好的灵活性。具体的触发是非常好的问题…跟踪。。?什么意思?ps:environment的“track”意思是你想看看在几个函数之间传递的变量的值是如何随时间变化的?@Edo你是对的,“track”是误导性的,我的意思是你可以创建一个变量,你知道“一直”,如果它存在,它必须存在于特定的环境和特定的名称中。我试过
environment(),你能解释一下为什么“
parent.frame(2)
不等于
parent.env(parent.frame())
”?我将文档添加到问题中,但对我来说,这并不十分清楚-你的结果当然是!(见我对问题的编辑)我相信,你会找到比我能说的更好的解释。特别是,请注意调用环境和绑定环境之间的区别我的意思是“调用环境和封闭环境”。这就是区别对你的例子的重要性所在。
subfun0 <- function() {
    e <- parent.frame()
    attr(e, "name") <- "my_env"
    assign("my_env", 1,
                 envir = parent.frame(),
                 inherits = FALSE, immediate = TRUE)
    return(NULL)
}

subsubfun <- function() {
    print("  subsubfun")
    print("  =========")
    print(exists("my_env"))
    print(exists("my_env", parent.frame()))
    print(exists("my_env", parent.frame(2)))
    return(NULL)
}

subfun <- function() {
    print(" subfun")
    print(" ======")
    print(exists("my_env"))
    print(exists("my_env", parent.frame()))
    print(exists("my_env", parent.frame(2)))
    subsubfun()
    return(NULL)
}

fun1 <- function() {
    print("fun1")
    print("====")
    subfun0()
    print(exists("my_env"))
    print(exists("my_env", parent.frame()))
    print(exists("my_env", parent.frame(2)))
    subfun()
    return(NULL)
}

fun1()
[1] "fun1"
[1] "===="
[1] TRUE
[1] FALSE
[1] FALSE
[1] " subfun"
[1] " ======"
[1] FALSE
[1] TRUE
[1] FALSE
[1] "  subsubfun"
[1] "  ========="
[1] FALSE
[1] FALSE
[1] TRUE
NULL