在使用R函数的情况下,环境的父级父环境是否也是该环境的父级? [英] Is in case of R functions a parent's parent environment of an environment also parent to the environment?

查看:47
本文介绍了在使用R函数的情况下,环境的父级父环境是否也是该环境的父级?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设,我创建了环境(E)的父母的父母环境(E2< =环境E1< =环境E).我的问题是,E2是否也是E的父母.对我而言,很明显,答案是肯定的,但是以下内容代码似乎相反.

Assume, I create a parent's parent environment (E2 <= environment E1 <= environmet E) of an environment (E). My questions is, whether E2 is also parent to E. To me it was clear, that the answer was yes, but the following code seems to state the opposite.

怎么了?请参见下面可复制示例的最后一行,其中 print(parent-parent )产生

What is wrong? See the last line in the reproducible example below, where print(parent-parent) yields

#[1]否#我希望这里是TRUE!

从文档?parent.env

如果遵循通过反复调用而找到的附件链来自任何环境的parent.env,最终一个到达空环境emptyenv(),什么都不能分配.

If one follows the chain of enclosures found by repeatedly calling parent.env from any environment, eventually one reaches the empty environment emptyenv(), into which nothing may be assigned.

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)))
  # print(parent.env(env)) # <environment: R_GlobalEnv>??
  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()
# [1] "fun1"
# [1] "===="
# [1] TRUE #     OK
# [1] FALSE
# [1] FALSE
# [1] " subfun"
# [1] " ======"
# [1] FALSE
# [1] TRUE #     OK
# [1] FALSE
# [1] "  subsubfun"
# [1] "  ========="
# [1] FALSE
# [1] FALSE
# [1] FALSE #    I would expect a TRUE here!!

推荐答案

问题是您实际上是在全局环境中定义所有函数,因此它们的父级是全局环境.

The problem is that you are actually defining all your functions in the global environment, therefore their parent is the global environment.

如果在其他函数中定义函数,您将获得期望的结果.看下面的例子.

You get what you would expect if you define your functions inside other functions. Look at the example below.

(我还创建了一个打印所有父环境直到全局环境的函数)

(Also I created a function that prints all parent environments till the global environment)

env_genealogy <- function(env){
    
    while(!identical(env, globalenv())){
        
        env <- parent.env(env)
        print(env)
        
    }
    
}



fun1 <- function() {
    subfun0 <- function() {
        
        print(" subfun0")
        print(" ======")
        
        env_genealogy(environment())
        
        e <- parent.frame()
        attr(e, "name") <- "my_env"
        assign("my_env", 1,
                     envir = parent.frame(),
                     inherits = FALSE, immediate = TRUE)
        return(NULL)
    }
    
    
    subfun <- function() {
        
        subsubfun <- function() {
            print("  subsubfun")
            print("  =========")
            
            env_genealogy(environment())
            
            print(exists("my_env"))
            print(exists("my_env", parent.frame()))
            env <- parent.frame()
            print(exists("my_env", parent.env(env)))
            # print(parent.env(env)) # <environment: R_GlobalEnv>??
            return(NULL)
        }
        
        print(" subfun")
        print(" ======")
        
        env_genealogy(environment())
        
        print(exists("my_env"))
        print(exists("my_env", parent.frame()))
        env <- parent.frame()
        print(exists("my_env", parent.env(env)))
        subsubfun()
        return(NULL)
    }
    
    
    
    print("fun1")
    print("====")
    
    env_genealogy(environment())
    
    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()

[1] "fun1"
[1] "===="
<environment: R_GlobalEnv>
[1] " subfun0"
[1] " ======"
<environment: 0x000001b0e4b124d8>
<environment: R_GlobalEnv>
[1] TRUE
[1] FALSE
[1] FALSE
[1] " subfun"
[1] " ======"
<environment: 0x000001b0e4b124d8>
attr(,"name")
[1] "my_env"
<environment: R_GlobalEnv>
[1] TRUE
[1] TRUE
[1] FALSE
[1] "  subsubfun"
[1] "  ========="
<environment: 0x000001b0e552add0>
<environment: 0x000001b0e4b124d8>
attr(,"name")
[1] "my_env"
<environment: R_GlobalEnv>
[1] TRUE
[1] TRUE
[1] TRUE
NULL

有关更多详细信息,请在此处

For more details, have a look here

举个简单的例子,您可以看一下:

For a minimal example, you can look at this:

a <- function(){
    
    i
    
}
 
a()
> #> Error in a() : object "i" not found

b <- function(){
    
    i <- 1
    
    a()
    
}
b()
> #> Error in a() : object "i" not found
 
d <- function(){
    
    i <<- 1
    a()
    
}
d()
#> [1] 1
rm(i)
 
 
f <- function(){
    
    g <- a
    i <- 2
    g()
    
}
f()
#> Error in g() : object "i" not found

h <- function(){
    
    l <- function() i
    i <- 2
    l()
    
}
h()
#> [1] 2

当您调用 a()时,您会收到错误消息,因为未定义 i .

When you call a() you get an error because i was not defined.

即使您在 b()中定义了 i ,您也会遇到相同的错误,因为 b 的环境未与共享一个.这是你的情况.

Even if you define i inside b() you get the same error because b's environment is not shared with a. This is your case.

d()之所以有效,是因为我们将 i 分配给具有<<-的全局环境.

d() works because we assign i to the global environment with <<-.

f()不起作用:即使我们在 f 中定义了 g ,我们也复制了 a ,它也复制了其父环境.

f() doesn't work: even if we defined g inside f, we made a copy of a which copied also its parent environment.

我们在 h()中得到一个结果,因为 l()是在内部定义的.这是我在回答中向您展示的情况.

We get a result in h() because l() was defined inside. This is the case I showed you in my answer.

这篇关于在使用R函数的情况下,环境的父级父环境是否也是该环境的父级?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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