簡體   English   中英

如何在R中獲取變量的環境

[英]How to get environment of a variable in R

我想知道是否有辦法獲得聲明變量的環境。 假設我已經向環境聲明了一個變量,並且想使用該變量的環境來聲明更多變量。 類似於 getEnv("variable")

參考: http : //adv-r.had.co.nz/Environments.html#env-basics

library(pryr)
x <- 5
where("x")
#> <environment: R_GlobalEnv>
where("mean")
#> <environment: base>

where 函數在上面的網站中有描述。 它只找到變量出現的第一個環境,但可以輕松修改以找到所有環境。

您可以使用ls()獲取工作區中的所有對象,然后您可以檢查其中哪些是環境:

envirs <- ls()[sapply(ls(), function(x) is.environment(get(x)))]

我需要在那里使用get()因為ls()返回對象的字符名稱而不是對象本身。 現在給定一些對象x ,我們想要找到它存在於哪些環境中。我們需要做的就是遍歷envirs每個環境,並檢查它們是否包含我們正在尋找的任何對象。 類似於(檢查變量x )的內容:

sapply(envirs, function(e) 'x' %in% ls(envir=get(e)))

這是一個完成所有這些工作的函數:

getEnv <- function(x) {
  xobj <- deparse(substitute(x))
  gobjects <- ls(envir=.GlobalEnv)
  envirs <- gobjects[sapply(gobjects, function(x) is.environment(get(x)))]
  envirs <- c('.GlobalEnv', envirs)
  xin <- sapply(envirs, function(e) xobj %in% ls(envir=get(e)))
  envirs[xin] 
}

這或多或少與我在函數外所做的相同。 gobjectsls()讀取,這次顯式檢查全局環境.GlobalEnv ,因為它現在在一個函數中。

envirs和以前一樣,除了現在它也會檢查.GlobalEnv xin存儲了在哪些環境中找到x的名稱。該行:

xobj <- deparse(substitute(x))

允許在沒有引號的情況下測試對象,例如getEnv(x)getEnv('x') 不過,這是一個偏好問題,您可以將其更改為接受字符。


這里有一些測試。

x1 <- 1
getEnv(x1)
# ".GlobalEnv"

x2 <- 2.1
e2 <- new.env()
assign('x2', 2.2, e2)
getEnv(x2)
# ".GlobalEnv" "e2" 

e3 <- new.env()
assign('x3', 3, e3)
getEnv(x3)
# "e3"

這僅檢查在.GlobalEnv創建的環境。 我敢肯定,如果需要,您可以想出如何擴展它以在更多環境中進行搜索。

我很驚訝沒有一些內置的功能。 或者也許有,但我不知道。 我以前從未真正需要做這樣的事情,所以也許這並不奇怪。

這個怎么樣:

getEnvOf <- function(what, which=rev(sys.parents())) {
  for (frame in which)
    if (exists(what, frame=frame, inherits=FALSE)) 
      return(sys.frame(frame))
  return(NULL)
}

然后我們可以:

x <- 1
getEnvOf("x")
# <environment: R_GlobalEnv>

getEnvOf("y")
# NULL

f <- function() getEnvOf("x")
f()
# <environment: R_GlobalEnv>

g <- function() { x <- 2; getEnvOf("x") }
g()
# <environment: 0x114c26518>

您可以使用find ,正如注釋中已經建議的那樣,在searchpath搜索對象的環境。 如果您想在函數調用堆棧中搜索,您可以使用exists來查看sys.frame

findFrame <- function(what) {
  n <- sys.nframe()-1
  Filter(Negate(is.null), lapply(n:0, function(i) {
    if(exists(what, sys.frame(i), inherits=FALSE)) sys.frame(i)}))
}

x <- 0
f1 <- function() {
  x <- 1
  f2()
}
f2 <- function() {
  x <- 2
  tt  <- find("x")
  print(sapply(tt, as.environment))
  tt <- findFrame("x")
  print(tt)
}
a <- new.env(parent=emptyenv())
a$x <- 3
attach(a)
b <- new.env(parent=emptyenv())
b$x <- 4

find("x")
#[1] ".GlobalEnv" "a"

findFrame("x")
#[[1]]
#<environment: R_GlobalEnv>

f1()
#$.GlobalEnv
#<environment: R_GlobalEnv>
#
#$a
#<environment: 0x5576b0c7bb80>
#attr(,"name")
#[1] "a"
#
#[[1]]
#<environment: 0x5576af2fa1f8>
#
#[[2]]
#<environment: 0x5576aedcab20>
#
#[[3]]
#<environment: R_GlobalEnv>

f2()
#$.GlobalEnv
#<environment: R_GlobalEnv>
#
#$a
#<environment: 0x5576b0c7bb80>
#attr(,"name")
#[1] "a"
#
#[[1]]
#<environment: 0x5576b013bef0>
#
#[[2]]
#<environment: R_GlobalEnv>

暫無
暫無

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

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