简体   繁体   English

R:你如何合并/组合两个环境?

[英]R: how do you merge/combine two environments?

This is a simple question but the answer is apparently not so simple... Is it possible to combine environments in R? 这是一个简单的问题,但答案显然不是那么简单......是否可以将R中的环境结合起来?

E1 = new.env()
E2 = new.env()
E1$x = 25
E2$y = 7

Ok, now I want an environment (say, E3 ) that has both x and y defined. 好的,现在我想要一个同时定义了xy的环境(比方说, E3 )。

c(E1, E2)
#doesn't work
E3 = new.env(E1, E2)
#doesn't work

I have found other similar questions but they don't seem to work for me. 我找到了其他类似的问题,但它们似乎对我不起作用。

Use case: Maybe there's a reason this isn't easy...the reason I want to do this is thus: I use some functions to load up data. 使用案例:也许有一个原因这并不容易......我想这样做的原因是:我使用一些函数来加载数据。 Previously, I've just loaded it into the global environment, but I now have many different functions loading different types of data (which I call variously as needed), and so I wanted to keep the loaded data a bit more compartmentalized. 以前,我刚刚将它加载到全局环境中,但是我现在有许多不同的函数加载不同类型的数据(我根据需要不同地调用它),因此我希望保持加载的数据更加分区。 If I call 2 different loading functions E1=loadData1() and E2=loadData2() , and I now want to call a function that uses variables from both of these functions, I'd like to be able to say with(E1 & E2, someFunction()) . 如果我调用2个不同的加载函数E1=loadData1()E2=loadData2() ,我现在想要调用一个使用这两个函数中的变量的函数,我想能够说with(E1 & E2, someFunction()) Hence, merging my loaded environments seems appropriate. 因此,合并我加载的环境似乎是合适的。

So, what's the right way to merge them? 那么,合并它们的正确方法是什么? And, as an aside, do you have a different suggestion for how to better accomplish what I'm doing, if merging environments is not the right way? 而且,顺便说一下,如果合并环境不是正确的方法,你对如何更好地完成我正在做的事情有不同的建议吗?

1) Make one environment the parent of the other and use with(child, ...) : 1)使一个环境成为另一个环境的父项并使用with(child, ...)

parent <- new.env(); parent$x <- 1
child <- new.env(parent = parent); child$y <- 2

with(child, x + y) # x comes from child and y from parent
## [1] 3

You can link as many environments as you like in as long a chain as necessary. 您可以根据需要链接任意数量的环境。

Note that if the child were initially created with no parent then you can add a parent later using: 请注意,如果最初创建的子项没有父项,则可以稍后使用以下命令添加父项:

parent.env(child) <- parent

Thus we define LoadData1 and LoadData2 as: 因此我们将LoadData1LoadData2定义为:

# define LoadData1 to have a parent argument
LoadData1 <- function(parent = emptyenv()) {
        # calculation of environment e goes here
        parent.env(e) <- parent
        e
}

# define LoadData2 to have a parent argument
LoadData2 <- function(parent = emptyenv()) {
        # calculation of environment e goes here
        parent.env(e) <- parent
        e
}

# run
e1 <- LoadData1()
e2 <- LoadData2(parent = e1)
with(e2, dataFrom1 + dataFrom2)

If you don't want to modify LoadData1 and LoadData2 from what they are now: 如果您不想从现在的位置修改LoadData1LoadData2

e1 <- LoadData1()
e2 <- LoadData2()
parent.env(e2) <- e1
with(e2, dataFrom1 + dataFrom2)

2) Convert to lists: 2)转换为列表:

with(c(as.list(e1), as.list(e2)), somefunction())

ADDED Second approach. 增加第二种方法。

You can do it by combining them, converting the environments to lists, and then converting back: 您可以通过组合它们,将环境转换为列表,然后转换回来来实现:

E3 <- as.environment(sapply(c(E1,E2),as.list))
ls(env=E3)
[1] "x" "y"
E3$x
[1] 25
E3$y
[1] 7

I made this function: 我做了这个功能:

> appendEnv = function(e1, e2) {
+     e1name = deparse(substitute(e1))
+     e2name = deparse(substitute(e2))
+     listE1 = ls(e1)
+     listE2 = ls(e2)
+     for(v in listE2) {
+         if(v %in% listE1) warning(sprintf("Variable %s is in e1, too!", v))
+         e1[[v]] = e2[[v]]
+     }
+ }

> e1 = new.env()
> e2 = new.env()
> e1$x = 1
> e1$y = 2
> e2$y = 3
> e2$z = 4
> appendEnv(e1, e2)
Warning message:
In appendEnv(e1, e2) : Variable y is in e1, too!
> as.list(e1)
$x
[1] 1

$y
[1] 3

$z
[1] 4

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM