15

我想知道是否有任何方法可以获取已声明变量的环境。假设我已经向环境声明了一个变量,并希望使用该变量的环境来声明更多变量。像 getEnv("variable")

4

4 回答 4

8

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

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

上面的网站中描述了 where 函数。它仅查找变量出现的第一个环境,但可以轻松修改以查找所有环境。

于 2015-01-16T06:26:55.587 回答
7

您可以使用 获取工作区中的所有对象,ls()然后可以检查其中哪些是环境:

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

我需要在get()那里使用,因为ls()返回对象的字符名称而不是对象本身。现在给定一些 object 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] 
}

这与我在函数之外所做的或多或少相同。gobjects从 读取ls(),这次显式检查全局环境.GlobalEnv,因为它现在在函数中。

envirs和以前一样,除了现在它也会检查.GlobalEnvxin正在存储在其中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. 我敢肯定,如果需要,您可以解决如何扩展它以在更多环境中进行搜索。

我很惊讶没有一些内置功能。或者也许有,但我不知道。我以前从来没有真正需要做这样的事情,所以也许这并不奇怪。

于 2013-05-17T13:49:16.860 回答
5

这个怎么样:

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>
于 2014-02-20T06:48:10.953 回答
0

find正如注释中已经建议的那样,您可以使用搜索 中对象的环境searchpath。如果您想在函数调用堆栈exists中查找,您可以使用sys.frame's.

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>
于 2020-01-28T08:48:30.847 回答