簡體   English   中英

在 R 函數的情況下,環境的父級環境也是環境的父級嗎?

[英]Is in case of R functions a parent's parent environment of an environment also parent to the environment?

假設,我創建了一個環境 (E) 的父級父環境 (E2 <= environment E1 <= environmet E)。 我的問題是,E2 是否也是 E 的父級。對我來說很明顯,答案是肯定的,但以下代碼似乎相反。

怎么了? 請參閱下面可重現示例中的最后一行,其中print(parent-parent ) 產生

# [1] FALSE # I would expect a TRUE here!!

從文檔?parent.env

如果遵循通過從任何環境重復調用 parent.env 找到的外殼鏈,最終會到達空環境 emptyenv(),其中可能沒有分配任何內容。

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!!

問題是您實際上是在全局環境中定義所有函數,因此它們的父級是全局環境。

如果你在其他函數中定義你的函數,你會得到你所期望的。 看看下面的例子。

(我還創建了一個打印所有父環境直到全局環境的函數)

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

有關更多詳細信息,請查看此處


對於一個最小的例子,你可以看看這個:

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未定義。

即使你在b()定義i你也會得到同樣的錯誤,因為b的環境不與a共享。 這是你的情況。

d()有效,因為我們使用<<-i分配給全局環境。

f()不工作:即使我們定義gf ,我們做的副本a也復制其父環境。

我們在h()得到結果,因為l()是在其中定義的。 這就是我在回答中向您展示的情況。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM