在R中运行时是否可以设置函数的环境? [英] Is it possible to set a function's environment while runtime in R?

查看:62
本文介绍了在R中运行时是否可以设置函数的环境?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

If you define functions, they are all part of the Global Environment by default. I wonder, whether there is a way, to set a function's parent environmet to the calling environment (while runtime - a function might be called in different places!). Thus, in case of nested functions, it should become possible, to define a variable in only one envrionment and I would expect for an example like

fun1 <- function() {
  # variable "my_env" defined only in this environment
  subfun() # calls subsubfun()
  return(NULL)
} 

类似于

的输出存在("my_env",different_environments)

# [1] "fun1"
# [1] "===="
# [1] TRUE #     Only here: "here", in this function
# [1] FALSE
# [1] FALSE
# [1] " subfun"
# [1] " ======"
# [1] FALSE
# [1] TRUE #     Only here: "parent environment", in calling function
# [1] FALSE
# [1] "  subsubfun"
# [1] "  ========="
# [1] FALSE
# [1] FALSE
# [1] TRUE #     Only here: "parent-parent environment", in the function calling the function

从文档?parent.frame

sys.parent 返回父帧的编号,如果n为1(默认值),如果n为2,则为祖父母,依此类推.另请参见注释".
(...) parent.frame(n)是sys.frame(sys.parent(n))(执行效率略高).

sys.parent returns the number of the parent frame if n is 1 (the default), the grandparent if n is 2, and so on. See also the ‘Note’.
(...) parent.frame(n) is a convenient shorthand for sys.frame(sys.parent(n)) (implemented slightly more efficiently).

注意
严格地, sys.parent parent.frame 是指父解释函数.因此内部功能(可能是可能未设置上下文,因此可能不会出现在调用堆栈中)可能不算在内,S3方法也可以做令人惊讶的事情.当心懒惰评估的效果:这两个函数来看评估时的调用堆栈,而不是评估时的调用堆栈叫做.将调用作为函数参数传递给他们不太可能是个好主意.

Note
Strictly, sys.parent and parent.frame refer to the context of the parent interpreted function. So internal functions (which may or may not set contexts and so may or may not appear on the call stack) may not be counted, and S3 methods can also do surprising things. Beware of the effect of lazy evaluation: these two functions look at the call stack at the time they are evaluated, not at the time they are called. Passing calls to them as function arguments is unlikely to be a good idea.

一些示例从此处开始,该示例不起作用,因为所有功能都是全局环境的一部分.

Some example to start with from here, which does not work, as all functions are part of the global environment.

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()


(我刚刚意识到,我对呼叫环境"的印象完全错误,我的问题是,我能否在R中使用我的印象"?)


(I just realized, that I had a completely wrong picture of "calling environment" in mind and my questions is, could I make "my picture" work in R.)

推荐答案

使用此代码,您可以获得所需的确切信息:

With this code you get exactly what you're looking for:

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

重点在于: parent.frame(2)不等于 parent.env(parent.frame())

这篇关于在R中运行时是否可以设置函数的环境?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆