R: how do you merge/combine two environments?

前端 未结 3 1351
[愿得一人]
[愿得一人] 2021-02-18 23:01

This is a simple question but the answer is apparently not so simple... Is it possible to combine environments in R?

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


        
相关标签:
3条回答
  • 2021-02-18 23:32

    1) Make one environment the parent of the other and use 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:

    # 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:

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

    2) Convert to lists:

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

    ADDED Second approach.

    0 讨论(0)
  • 2021-02-18 23:34

    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
    
    0 讨论(0)
  • 2021-02-18 23:54

    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
    
    0 讨论(0)
提交回复
热议问题