如何在R中获取变量的环境

时间:2022-11-09 23:23:08

I was wondering if there is anyway to get the environment of a declared variable. Say I already have declared a variable to an environment and want to use that variable's environment to declare a few more variables. Something like getEnv("variable")

我想知道是否还有获得声明变量的环境。假设我已经向环境声明了一个变量,并希望使用该变量的环境来声明更多变量。类似于getEnv(“变量”)

3 个解决方案

#1


7  

Refer to: http://adv-r.had.co.nz/Environments.html#env-basics

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

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

The where function is described in the above website. It only finds the first environment the variable appears in, but could easily be modified to find all.

where功能在上面的网站中描述。它只找到变量出现的第一个环境,但可以轻松修改以查找所有变量。

#2


5  

You can get all objects in your workspace with ls(), so you can then check which of those are environments:

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

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

I need to use get() there because ls() returns character names of objects rather than the objects themselves. Now given some object x, we want to find which environments it exists in. All we need to do is iterate through each environment in envirs, and check if they contain whatever object we're looking for. Something along the lines of (checking for a variable x):

我需要在那里使用get(),因为ls()返回对象的字符名称而不是对象本身。现在给出一些对象x,我们想要找到它存在的环境。我们需要做的就是遍历envirs中的每个环境,并检查它们是否包含我们正在寻找的任何对象。 (检查变量x)的一些东西:

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

Here's a function to do all this:

这是一个完成所有这些的功能:

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] 
}

This is more or less the same as what I did outside the function. gobjects reads from ls(), this time explicitly checking the global environment .GlobalEnv, since it is now within a function.

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

envirs is the same as before, except now it will check .GlobalEnv as well. xin is storing the names of which environments x was found in. The line:

envirs和以前一样,除了现在它将检查.GlobalEnv。 xin正在存储找到x的环境的名称。该行:

xobj <- deparse(substitute(x))

Allows object to be tested without quotes e.g. getEnv(x) versus getEnv('x'). That's a matter of preference though, you can change it to accept characters instead.

允许在没有引号的情况下测试对象,例如getEnv(x)与getEnv('x')。这是一个偏好的问题,你可以改为接受角色。


Here's a few tests.

这是一些测试。

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"

This only checks environments created within .GlobalEnv. I'm sure you can work out how to extend it to search across more environments though if you need.

这仅检查.GlobalEnv中创建的环境。我相信如果你需要,你可以找出如何扩展它以搜索更多环境。

I'm surprised there isn't some in-built function for this. Or maybe there is and I don't know about it. I've never actually needed to do anything like this before so maybe it's not actually surprising.

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

#3


0  

How about this:

这个怎么样:

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

Then we can:

然后我们可以:

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>

#1


7  

Refer to: http://adv-r.had.co.nz/Environments.html#env-basics

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

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

The where function is described in the above website. It only finds the first environment the variable appears in, but could easily be modified to find all.

where功能在上面的网站中描述。它只找到变量出现的第一个环境,但可以轻松修改以查找所有变量。

#2


5  

You can get all objects in your workspace with ls(), so you can then check which of those are environments:

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

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

I need to use get() there because ls() returns character names of objects rather than the objects themselves. Now given some object x, we want to find which environments it exists in. All we need to do is iterate through each environment in envirs, and check if they contain whatever object we're looking for. Something along the lines of (checking for a variable x):

我需要在那里使用get(),因为ls()返回对象的字符名称而不是对象本身。现在给出一些对象x,我们想要找到它存在的环境。我们需要做的就是遍历envirs中的每个环境,并检查它们是否包含我们正在寻找的任何对象。 (检查变量x)的一些东西:

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

Here's a function to do all this:

这是一个完成所有这些的功能:

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] 
}

This is more or less the same as what I did outside the function. gobjects reads from ls(), this time explicitly checking the global environment .GlobalEnv, since it is now within a function.

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

envirs is the same as before, except now it will check .GlobalEnv as well. xin is storing the names of which environments x was found in. The line:

envirs和以前一样,除了现在它将检查.GlobalEnv。 xin正在存储找到x的环境的名称。该行:

xobj <- deparse(substitute(x))

Allows object to be tested without quotes e.g. getEnv(x) versus getEnv('x'). That's a matter of preference though, you can change it to accept characters instead.

允许在没有引号的情况下测试对象,例如getEnv(x)与getEnv('x')。这是一个偏好的问题,你可以改为接受角色。


Here's a few tests.

这是一些测试。

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"

This only checks environments created within .GlobalEnv. I'm sure you can work out how to extend it to search across more environments though if you need.

这仅检查.GlobalEnv中创建的环境。我相信如果你需要,你可以找出如何扩展它以搜索更多环境。

I'm surprised there isn't some in-built function for this. Or maybe there is and I don't know about it. I've never actually needed to do anything like this before so maybe it's not actually surprising.

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

#3


0  

How about this:

这个怎么样:

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

Then we can:

然后我们可以:

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>