R: copy/move one environment to another












17















I would like to ask if it is possible to copy/move all the objects of one environment to another, at once. For example:



f1 <- function() {
print(v1)
print(v2)
}

f2 <- function() {
v1 <- 1
v2 <- 2

# environment(f1)$v1 <- v1 # It works
# environment(f1)$v2 <- v2 # It works

environment(f1) <- environment(f2) # It does not work
}

f2()
f1()


TNX, in advance










share|improve this question





























    17















    I would like to ask if it is possible to copy/move all the objects of one environment to another, at once. For example:



    f1 <- function() {
    print(v1)
    print(v2)
    }

    f2 <- function() {
    v1 <- 1
    v2 <- 2

    # environment(f1)$v1 <- v1 # It works
    # environment(f1)$v2 <- v2 # It works

    environment(f1) <- environment(f2) # It does not work
    }

    f2()
    f1()


    TNX, in advance










    share|improve this question



























      17












      17








      17


      6






      I would like to ask if it is possible to copy/move all the objects of one environment to another, at once. For example:



      f1 <- function() {
      print(v1)
      print(v2)
      }

      f2 <- function() {
      v1 <- 1
      v2 <- 2

      # environment(f1)$v1 <- v1 # It works
      # environment(f1)$v2 <- v2 # It works

      environment(f1) <- environment(f2) # It does not work
      }

      f2()
      f1()


      TNX, in advance










      share|improve this question
















      I would like to ask if it is possible to copy/move all the objects of one environment to another, at once. For example:



      f1 <- function() {
      print(v1)
      print(v2)
      }

      f2 <- function() {
      v1 <- 1
      v2 <- 2

      # environment(f1)$v1 <- v1 # It works
      # environment(f1)$v2 <- v2 # It works

      environment(f1) <- environment(f2) # It does not work
      }

      f2()
      f1()


      TNX, in advance







      r






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Apr 1 '12 at 15:33







      Apostolos Polymeros

















      asked Apr 1 '12 at 15:23









      Apostolos PolymerosApostolos Polymeros

      418617




      418617
























          6 Answers
          6






          active

          oldest

          votes


















          25














          There seem to be at least 3 different things you can do:




          1. Clone an environment (create an exact duplicate)

          2. Copy the content of one environment to another environment

          3. Share the same environment


          To clone:



          # Make the source env
          e1 <- new.env()
          e1$foo <- 1
          e1$.bar <- 2 # a hidden name
          ls(e1) # only shows "foo"

          # This will clone e1
          e2 <- as.environment(as.list(e1, all.names=TRUE))

          # Check it...
          identical(e1, e2) # FALSE
          e2$foo
          e2$.bar


          To copy the content, you can do what @gsk showed. But again, the all.names flag is useful:



          # e1 is source env, e2 is dest env
          for(n in ls(e1, all.names=TRUE)) assign(n, get(n, e1), e2)


          To share the environment is what @koshke did. This is probably often much more useful. The result is the same as if creating a local function:



          f2 <- function() {
          v1 <- 1
          v2 <- 2

          # This local function has access to v1 and v2
          flocal <- function() {
          print(v1)
          print(v2)
          }

          return(flocal)
          }

          f1 <- f2()
          f1() # prints 1 and 2





          share|improve this answer


























          • it's a complete answer

            – Apostolos Polymeros
            Apr 1 '12 at 19:19



















          9














          Try this:



          f2 <- function() {
          v1 <- 1
          v2 <- 2
          environment(f1) <<- environment()
          }





          share|improve this answer
























          • You are right, thank you a lot !

            – Apostolos Polymeros
            Apr 1 '12 at 15:39











          • +1 - nice one...

            – Tommy
            Apr 1 '12 at 17:24



















          5














          You could use assign:



          f1 <- function() {
          print(v1)
          print(v2)
          }

          f2 <- function() {
          v1 <- 1
          v2 <- 2

          for(obj in c("v1","v2")) {
          assign(obj,get(obj),envir=f1.env)
          }
          }


          If you don't want to list out the objects, ls() takes an environment argument.



          And you'll have to figure out how to get f1.env to be an environment pointing inside f1 :-)






          share|improve this answer


























          • It is a very good answer

            – Apostolos Polymeros
            Apr 1 '12 at 15:42











          • Note that this code simply assigning v1 and v2 into .GlovalEnv...

            – kohske
            Apr 1 '12 at 15:44











          • Thanks! It was a fun question. @kohske's solution seems more elegant (as always!).

            – Ari B. Friedman
            Apr 1 '12 at 15:44











          • @kohske Uh oh. Maybe the ,envir option doesn't do what I thought it did. I'll look further.

            – Ari B. Friedman
            Apr 1 '12 at 15:47






          • 2





            For what it's worth, this answer seems to match the way I've seen it done internally in R code written by R core members ... so it may be "canonical". @kohske's is cleverer, but that makes me nervous.

            – Ben Bolker
            Apr 1 '12 at 16:09



















          2














          I use this function in my package to copy objects:



          copyEnv <- function(from, to, names=ls(from, all.names=TRUE)) {
          mapply(assign, names, mget(names, from), list(to),
          SIMPLIFY = FALSE, USE.NAMES = FALSE)
          invisible(NULL)
          }





          share|improve this answer































            1














            To do it:



            environment(f1) <- environment(f2) # It does not work


            Open the f1 environment and run do this:



            ls(load(f2))





            share|improve this answer

































              0














              The "clone" method posted by Tommy won't make a true (deep) clone when e1 contains names that reference other environments. For instance, if e1$nestedEnv references an environment, e2$nestedEnv will reference the same environment, not a copy of that environment. Thus, the name e1$nestedEnv$bar will reference the same memory location as e2$nestedEnv$bar and any new value assigned to e1$nestedEnv$bar will be reflected for e2$nestedEnv$bar as well. This may be desirable behavior, but calling e2 a clone of e1 could be misleading.



              Here is a function that will allow the user to make either a copy of an environment while also copying any nested environments (a "deep clone", using deep = TRUE), or just use the method proposed by Tommy to copy the environment while maintaining original references to any nested environments (using deep = FALSE).



              The 'deep = TRUE' method uses rapply to recursively call cloneEnv on nested environment within envir, for as many levels as the environments are nested. So, in the end, it recursively calls rapply, which is a bit of a mind bender, but works pretty well.



              Note that if a nested environment contains a name that references a parent environment, using the "deep" method will never return from the recursive calls. If I could have figured out a way to check for this, I would have included it...



              Note, too, that environments can have attributes, so copying the attributes would be necessary for a true clone, which this solution also addresses.



              cloneEnv <- function(envir, deep = T) {
              if(deep) {
              clone <- list2env(rapply(as.list(envir, all.names = TRUE), cloneEnv, classes = "environment", how = "replace"), parent = parent.env(envir))
              } else {
              clone <- list2env(as.list(envir, all.names = TRUE), parent = parent.env(envir))
              }
              attributes(clone) <- attributes(envir)
              return(clone)
              }


              An example:



              Create environment e1, which also contains a nested environment:



              e1 <- new.env()
              e1$foo <- "Christmas"
              e1$nestedEnv <- new.env()
              e1$nestedEnv$bar <- "New Years"


              Show the values for foo and bar:



              e1$foo
              [1] "Christmas"
              e1$nestedEnv$bar
              [1] "New Years"


              Make a deep clone (i.e. e2 contains makes a copy of nestedEnv)



              e2 <- cloneEnv(e1, deep = TRUE)


              nestedEnv in e1 references a difference environment than nestedEnv in e2:



              identical(e1$nestedEnv, e2$nestedEnv)
              [1] FALSE


              But the values are the same because e2$nestedEnv is a copy of e1$nestedEnv:



              e2$foo
              [1] "Christmas"
              e2$nestedEnv$bar
              [1] "New Years"


              Change the values in e2:



              e2$foo <- "Halloween"
              e2$nestedEnv$bar <- "Thanksgiving"


              And values in e1 remain unchanged, again, because e1$nestedEnv points to a different environment than e2$nestedEnv:



              e1$foo
              [1] "Christmas"
              e2$foo
              [1] "Halloween"

              e1$nestedEnv$bar
              [1] "New Years"
              e2$nestedEnv$bar
              [1] "Thanksgiving"


              Now, re-create e1 using Tommy's method:



              e2 <- cloneEnv(e1, deep = FALSE)


              nestedEnv in e2 points to the same environment as nestedEnv in e1:



              identical(e1$nestedEnv, e2$nestedEnv)
              [1] TRUE


              Update the values in e2 and e2's nestedEnv:



              e2$foo <- "Halloween"
              e2$nestedEnv$bar <- "Thanksgiving"


              Values of foo are independent:



              e1$foo
              [1] "Christmas"
              e2$foo
              [1] "Halloween"


              but updating value e2's bar has also updated e1's bar because e1$nestedEnv and e2$nestedEnv reference (point to) the same environment.



              e1$nestedEnv$bar
              [1] "Thanksgiving"
              e2$nestedEnv$bar
              [1] "Thanksgiving"





              share|improve this answer

























                Your Answer






                StackExchange.ifUsing("editor", function () {
                StackExchange.using("externalEditor", function () {
                StackExchange.using("snippets", function () {
                StackExchange.snippets.init();
                });
                });
                }, "code-snippets");

                StackExchange.ready(function() {
                var channelOptions = {
                tags: "".split(" "),
                id: "1"
                };
                initTagRenderer("".split(" "), "".split(" "), channelOptions);

                StackExchange.using("externalEditor", function() {
                // Have to fire editor after snippets, if snippets enabled
                if (StackExchange.settings.snippets.snippetsEnabled) {
                StackExchange.using("snippets", function() {
                createEditor();
                });
                }
                else {
                createEditor();
                }
                });

                function createEditor() {
                StackExchange.prepareEditor({
                heartbeatType: 'answer',
                autoActivateHeartbeat: false,
                convertImagesToLinks: true,
                noModals: true,
                showLowRepImageUploadWarning: true,
                reputationToPostImages: 10,
                bindNavPrevention: true,
                postfix: "",
                imageUploader: {
                brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
                contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
                allowUrls: true
                },
                onDemand: true,
                discardSelector: ".discard-answer"
                ,immediatelyShowMarkdownHelp:true
                });


                }
                });














                draft saved

                draft discarded


















                StackExchange.ready(
                function () {
                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f9965577%2fr-copy-move-one-environment-to-another%23new-answer', 'question_page');
                }
                );

                Post as a guest















                Required, but never shown

























                6 Answers
                6






                active

                oldest

                votes








                6 Answers
                6






                active

                oldest

                votes









                active

                oldest

                votes






                active

                oldest

                votes









                25














                There seem to be at least 3 different things you can do:




                1. Clone an environment (create an exact duplicate)

                2. Copy the content of one environment to another environment

                3. Share the same environment


                To clone:



                # Make the source env
                e1 <- new.env()
                e1$foo <- 1
                e1$.bar <- 2 # a hidden name
                ls(e1) # only shows "foo"

                # This will clone e1
                e2 <- as.environment(as.list(e1, all.names=TRUE))

                # Check it...
                identical(e1, e2) # FALSE
                e2$foo
                e2$.bar


                To copy the content, you can do what @gsk showed. But again, the all.names flag is useful:



                # e1 is source env, e2 is dest env
                for(n in ls(e1, all.names=TRUE)) assign(n, get(n, e1), e2)


                To share the environment is what @koshke did. This is probably often much more useful. The result is the same as if creating a local function:



                f2 <- function() {
                v1 <- 1
                v2 <- 2

                # This local function has access to v1 and v2
                flocal <- function() {
                print(v1)
                print(v2)
                }

                return(flocal)
                }

                f1 <- f2()
                f1() # prints 1 and 2





                share|improve this answer


























                • it's a complete answer

                  – Apostolos Polymeros
                  Apr 1 '12 at 19:19
















                25














                There seem to be at least 3 different things you can do:




                1. Clone an environment (create an exact duplicate)

                2. Copy the content of one environment to another environment

                3. Share the same environment


                To clone:



                # Make the source env
                e1 <- new.env()
                e1$foo <- 1
                e1$.bar <- 2 # a hidden name
                ls(e1) # only shows "foo"

                # This will clone e1
                e2 <- as.environment(as.list(e1, all.names=TRUE))

                # Check it...
                identical(e1, e2) # FALSE
                e2$foo
                e2$.bar


                To copy the content, you can do what @gsk showed. But again, the all.names flag is useful:



                # e1 is source env, e2 is dest env
                for(n in ls(e1, all.names=TRUE)) assign(n, get(n, e1), e2)


                To share the environment is what @koshke did. This is probably often much more useful. The result is the same as if creating a local function:



                f2 <- function() {
                v1 <- 1
                v2 <- 2

                # This local function has access to v1 and v2
                flocal <- function() {
                print(v1)
                print(v2)
                }

                return(flocal)
                }

                f1 <- f2()
                f1() # prints 1 and 2





                share|improve this answer


























                • it's a complete answer

                  – Apostolos Polymeros
                  Apr 1 '12 at 19:19














                25












                25








                25







                There seem to be at least 3 different things you can do:




                1. Clone an environment (create an exact duplicate)

                2. Copy the content of one environment to another environment

                3. Share the same environment


                To clone:



                # Make the source env
                e1 <- new.env()
                e1$foo <- 1
                e1$.bar <- 2 # a hidden name
                ls(e1) # only shows "foo"

                # This will clone e1
                e2 <- as.environment(as.list(e1, all.names=TRUE))

                # Check it...
                identical(e1, e2) # FALSE
                e2$foo
                e2$.bar


                To copy the content, you can do what @gsk showed. But again, the all.names flag is useful:



                # e1 is source env, e2 is dest env
                for(n in ls(e1, all.names=TRUE)) assign(n, get(n, e1), e2)


                To share the environment is what @koshke did. This is probably often much more useful. The result is the same as if creating a local function:



                f2 <- function() {
                v1 <- 1
                v2 <- 2

                # This local function has access to v1 and v2
                flocal <- function() {
                print(v1)
                print(v2)
                }

                return(flocal)
                }

                f1 <- f2()
                f1() # prints 1 and 2





                share|improve this answer















                There seem to be at least 3 different things you can do:




                1. Clone an environment (create an exact duplicate)

                2. Copy the content of one environment to another environment

                3. Share the same environment


                To clone:



                # Make the source env
                e1 <- new.env()
                e1$foo <- 1
                e1$.bar <- 2 # a hidden name
                ls(e1) # only shows "foo"

                # This will clone e1
                e2 <- as.environment(as.list(e1, all.names=TRUE))

                # Check it...
                identical(e1, e2) # FALSE
                e2$foo
                e2$.bar


                To copy the content, you can do what @gsk showed. But again, the all.names flag is useful:



                # e1 is source env, e2 is dest env
                for(n in ls(e1, all.names=TRUE)) assign(n, get(n, e1), e2)


                To share the environment is what @koshke did. This is probably often much more useful. The result is the same as if creating a local function:



                f2 <- function() {
                v1 <- 1
                v2 <- 2

                # This local function has access to v1 and v2
                flocal <- function() {
                print(v1)
                print(v2)
                }

                return(flocal)
                }

                f1 <- f2()
                f1() # prints 1 and 2






                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Apr 1 '12 at 17:49

























                answered Apr 1 '12 at 17:17









                TommyTommy

                31.7k87879




                31.7k87879













                • it's a complete answer

                  – Apostolos Polymeros
                  Apr 1 '12 at 19:19



















                • it's a complete answer

                  – Apostolos Polymeros
                  Apr 1 '12 at 19:19

















                it's a complete answer

                – Apostolos Polymeros
                Apr 1 '12 at 19:19





                it's a complete answer

                – Apostolos Polymeros
                Apr 1 '12 at 19:19













                9














                Try this:



                f2 <- function() {
                v1 <- 1
                v2 <- 2
                environment(f1) <<- environment()
                }





                share|improve this answer
























                • You are right, thank you a lot !

                  – Apostolos Polymeros
                  Apr 1 '12 at 15:39











                • +1 - nice one...

                  – Tommy
                  Apr 1 '12 at 17:24
















                9














                Try this:



                f2 <- function() {
                v1 <- 1
                v2 <- 2
                environment(f1) <<- environment()
                }





                share|improve this answer
























                • You are right, thank you a lot !

                  – Apostolos Polymeros
                  Apr 1 '12 at 15:39











                • +1 - nice one...

                  – Tommy
                  Apr 1 '12 at 17:24














                9












                9








                9







                Try this:



                f2 <- function() {
                v1 <- 1
                v2 <- 2
                environment(f1) <<- environment()
                }





                share|improve this answer













                Try this:



                f2 <- function() {
                v1 <- 1
                v2 <- 2
                environment(f1) <<- environment()
                }






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Apr 1 '12 at 15:33









                kohskekohske

                52.6k6144146




                52.6k6144146













                • You are right, thank you a lot !

                  – Apostolos Polymeros
                  Apr 1 '12 at 15:39











                • +1 - nice one...

                  – Tommy
                  Apr 1 '12 at 17:24



















                • You are right, thank you a lot !

                  – Apostolos Polymeros
                  Apr 1 '12 at 15:39











                • +1 - nice one...

                  – Tommy
                  Apr 1 '12 at 17:24

















                You are right, thank you a lot !

                – Apostolos Polymeros
                Apr 1 '12 at 15:39





                You are right, thank you a lot !

                – Apostolos Polymeros
                Apr 1 '12 at 15:39













                +1 - nice one...

                – Tommy
                Apr 1 '12 at 17:24





                +1 - nice one...

                – Tommy
                Apr 1 '12 at 17:24











                5














                You could use assign:



                f1 <- function() {
                print(v1)
                print(v2)
                }

                f2 <- function() {
                v1 <- 1
                v2 <- 2

                for(obj in c("v1","v2")) {
                assign(obj,get(obj),envir=f1.env)
                }
                }


                If you don't want to list out the objects, ls() takes an environment argument.



                And you'll have to figure out how to get f1.env to be an environment pointing inside f1 :-)






                share|improve this answer


























                • It is a very good answer

                  – Apostolos Polymeros
                  Apr 1 '12 at 15:42











                • Note that this code simply assigning v1 and v2 into .GlovalEnv...

                  – kohske
                  Apr 1 '12 at 15:44











                • Thanks! It was a fun question. @kohske's solution seems more elegant (as always!).

                  – Ari B. Friedman
                  Apr 1 '12 at 15:44











                • @kohske Uh oh. Maybe the ,envir option doesn't do what I thought it did. I'll look further.

                  – Ari B. Friedman
                  Apr 1 '12 at 15:47






                • 2





                  For what it's worth, this answer seems to match the way I've seen it done internally in R code written by R core members ... so it may be "canonical". @kohske's is cleverer, but that makes me nervous.

                  – Ben Bolker
                  Apr 1 '12 at 16:09
















                5














                You could use assign:



                f1 <- function() {
                print(v1)
                print(v2)
                }

                f2 <- function() {
                v1 <- 1
                v2 <- 2

                for(obj in c("v1","v2")) {
                assign(obj,get(obj),envir=f1.env)
                }
                }


                If you don't want to list out the objects, ls() takes an environment argument.



                And you'll have to figure out how to get f1.env to be an environment pointing inside f1 :-)






                share|improve this answer


























                • It is a very good answer

                  – Apostolos Polymeros
                  Apr 1 '12 at 15:42











                • Note that this code simply assigning v1 and v2 into .GlovalEnv...

                  – kohske
                  Apr 1 '12 at 15:44











                • Thanks! It was a fun question. @kohske's solution seems more elegant (as always!).

                  – Ari B. Friedman
                  Apr 1 '12 at 15:44











                • @kohske Uh oh. Maybe the ,envir option doesn't do what I thought it did. I'll look further.

                  – Ari B. Friedman
                  Apr 1 '12 at 15:47






                • 2





                  For what it's worth, this answer seems to match the way I've seen it done internally in R code written by R core members ... so it may be "canonical". @kohske's is cleverer, but that makes me nervous.

                  – Ben Bolker
                  Apr 1 '12 at 16:09














                5












                5








                5







                You could use assign:



                f1 <- function() {
                print(v1)
                print(v2)
                }

                f2 <- function() {
                v1 <- 1
                v2 <- 2

                for(obj in c("v1","v2")) {
                assign(obj,get(obj),envir=f1.env)
                }
                }


                If you don't want to list out the objects, ls() takes an environment argument.



                And you'll have to figure out how to get f1.env to be an environment pointing inside f1 :-)






                share|improve this answer















                You could use assign:



                f1 <- function() {
                print(v1)
                print(v2)
                }

                f2 <- function() {
                v1 <- 1
                v2 <- 2

                for(obj in c("v1","v2")) {
                assign(obj,get(obj),envir=f1.env)
                }
                }


                If you don't want to list out the objects, ls() takes an environment argument.



                And you'll have to figure out how to get f1.env to be an environment pointing inside f1 :-)







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Apr 1 '12 at 16:15

























                answered Apr 1 '12 at 15:38









                Ari B. FriedmanAri B. Friedman

                47.4k26149210




                47.4k26149210













                • It is a very good answer

                  – Apostolos Polymeros
                  Apr 1 '12 at 15:42











                • Note that this code simply assigning v1 and v2 into .GlovalEnv...

                  – kohske
                  Apr 1 '12 at 15:44











                • Thanks! It was a fun question. @kohske's solution seems more elegant (as always!).

                  – Ari B. Friedman
                  Apr 1 '12 at 15:44











                • @kohske Uh oh. Maybe the ,envir option doesn't do what I thought it did. I'll look further.

                  – Ari B. Friedman
                  Apr 1 '12 at 15:47






                • 2





                  For what it's worth, this answer seems to match the way I've seen it done internally in R code written by R core members ... so it may be "canonical". @kohske's is cleverer, but that makes me nervous.

                  – Ben Bolker
                  Apr 1 '12 at 16:09



















                • It is a very good answer

                  – Apostolos Polymeros
                  Apr 1 '12 at 15:42











                • Note that this code simply assigning v1 and v2 into .GlovalEnv...

                  – kohske
                  Apr 1 '12 at 15:44











                • Thanks! It was a fun question. @kohske's solution seems more elegant (as always!).

                  – Ari B. Friedman
                  Apr 1 '12 at 15:44











                • @kohske Uh oh. Maybe the ,envir option doesn't do what I thought it did. I'll look further.

                  – Ari B. Friedman
                  Apr 1 '12 at 15:47






                • 2





                  For what it's worth, this answer seems to match the way I've seen it done internally in R code written by R core members ... so it may be "canonical". @kohske's is cleverer, but that makes me nervous.

                  – Ben Bolker
                  Apr 1 '12 at 16:09

















                It is a very good answer

                – Apostolos Polymeros
                Apr 1 '12 at 15:42





                It is a very good answer

                – Apostolos Polymeros
                Apr 1 '12 at 15:42













                Note that this code simply assigning v1 and v2 into .GlovalEnv...

                – kohske
                Apr 1 '12 at 15:44





                Note that this code simply assigning v1 and v2 into .GlovalEnv...

                – kohske
                Apr 1 '12 at 15:44













                Thanks! It was a fun question. @kohske's solution seems more elegant (as always!).

                – Ari B. Friedman
                Apr 1 '12 at 15:44





                Thanks! It was a fun question. @kohske's solution seems more elegant (as always!).

                – Ari B. Friedman
                Apr 1 '12 at 15:44













                @kohske Uh oh. Maybe the ,envir option doesn't do what I thought it did. I'll look further.

                – Ari B. Friedman
                Apr 1 '12 at 15:47





                @kohske Uh oh. Maybe the ,envir option doesn't do what I thought it did. I'll look further.

                – Ari B. Friedman
                Apr 1 '12 at 15:47




                2




                2





                For what it's worth, this answer seems to match the way I've seen it done internally in R code written by R core members ... so it may be "canonical". @kohske's is cleverer, but that makes me nervous.

                – Ben Bolker
                Apr 1 '12 at 16:09





                For what it's worth, this answer seems to match the way I've seen it done internally in R code written by R core members ... so it may be "canonical". @kohske's is cleverer, but that makes me nervous.

                – Ben Bolker
                Apr 1 '12 at 16:09











                2














                I use this function in my package to copy objects:



                copyEnv <- function(from, to, names=ls(from, all.names=TRUE)) {
                mapply(assign, names, mget(names, from), list(to),
                SIMPLIFY = FALSE, USE.NAMES = FALSE)
                invisible(NULL)
                }





                share|improve this answer




























                  2














                  I use this function in my package to copy objects:



                  copyEnv <- function(from, to, names=ls(from, all.names=TRUE)) {
                  mapply(assign, names, mget(names, from), list(to),
                  SIMPLIFY = FALSE, USE.NAMES = FALSE)
                  invisible(NULL)
                  }





                  share|improve this answer


























                    2












                    2








                    2







                    I use this function in my package to copy objects:



                    copyEnv <- function(from, to, names=ls(from, all.names=TRUE)) {
                    mapply(assign, names, mget(names, from), list(to),
                    SIMPLIFY = FALSE, USE.NAMES = FALSE)
                    invisible(NULL)
                    }





                    share|improve this answer













                    I use this function in my package to copy objects:



                    copyEnv <- function(from, to, names=ls(from, all.names=TRUE)) {
                    mapply(assign, names, mget(names, from), list(to),
                    SIMPLIFY = FALSE, USE.NAMES = FALSE)
                    invisible(NULL)
                    }






                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Nov 1 '15 at 17:38









                    Neal FultzNeal Fultz

                    7,3242438




                    7,3242438























                        1














                        To do it:



                        environment(f1) <- environment(f2) # It does not work


                        Open the f1 environment and run do this:



                        ls(load(f2))





                        share|improve this answer






























                          1














                          To do it:



                          environment(f1) <- environment(f2) # It does not work


                          Open the f1 environment and run do this:



                          ls(load(f2))





                          share|improve this answer




























                            1












                            1








                            1







                            To do it:



                            environment(f1) <- environment(f2) # It does not work


                            Open the f1 environment and run do this:



                            ls(load(f2))





                            share|improve this answer















                            To do it:



                            environment(f1) <- environment(f2) # It does not work


                            Open the f1 environment and run do this:



                            ls(load(f2))






                            share|improve this answer














                            share|improve this answer



                            share|improve this answer








                            edited May 27 '14 at 19:00









                            elimirks

                            1,24721529




                            1,24721529










                            answered May 27 '14 at 18:36









                            Brunno OliveiraBrunno Oliveira

                            163




                            163























                                0














                                The "clone" method posted by Tommy won't make a true (deep) clone when e1 contains names that reference other environments. For instance, if e1$nestedEnv references an environment, e2$nestedEnv will reference the same environment, not a copy of that environment. Thus, the name e1$nestedEnv$bar will reference the same memory location as e2$nestedEnv$bar and any new value assigned to e1$nestedEnv$bar will be reflected for e2$nestedEnv$bar as well. This may be desirable behavior, but calling e2 a clone of e1 could be misleading.



                                Here is a function that will allow the user to make either a copy of an environment while also copying any nested environments (a "deep clone", using deep = TRUE), or just use the method proposed by Tommy to copy the environment while maintaining original references to any nested environments (using deep = FALSE).



                                The 'deep = TRUE' method uses rapply to recursively call cloneEnv on nested environment within envir, for as many levels as the environments are nested. So, in the end, it recursively calls rapply, which is a bit of a mind bender, but works pretty well.



                                Note that if a nested environment contains a name that references a parent environment, using the "deep" method will never return from the recursive calls. If I could have figured out a way to check for this, I would have included it...



                                Note, too, that environments can have attributes, so copying the attributes would be necessary for a true clone, which this solution also addresses.



                                cloneEnv <- function(envir, deep = T) {
                                if(deep) {
                                clone <- list2env(rapply(as.list(envir, all.names = TRUE), cloneEnv, classes = "environment", how = "replace"), parent = parent.env(envir))
                                } else {
                                clone <- list2env(as.list(envir, all.names = TRUE), parent = parent.env(envir))
                                }
                                attributes(clone) <- attributes(envir)
                                return(clone)
                                }


                                An example:



                                Create environment e1, which also contains a nested environment:



                                e1 <- new.env()
                                e1$foo <- "Christmas"
                                e1$nestedEnv <- new.env()
                                e1$nestedEnv$bar <- "New Years"


                                Show the values for foo and bar:



                                e1$foo
                                [1] "Christmas"
                                e1$nestedEnv$bar
                                [1] "New Years"


                                Make a deep clone (i.e. e2 contains makes a copy of nestedEnv)



                                e2 <- cloneEnv(e1, deep = TRUE)


                                nestedEnv in e1 references a difference environment than nestedEnv in e2:



                                identical(e1$nestedEnv, e2$nestedEnv)
                                [1] FALSE


                                But the values are the same because e2$nestedEnv is a copy of e1$nestedEnv:



                                e2$foo
                                [1] "Christmas"
                                e2$nestedEnv$bar
                                [1] "New Years"


                                Change the values in e2:



                                e2$foo <- "Halloween"
                                e2$nestedEnv$bar <- "Thanksgiving"


                                And values in e1 remain unchanged, again, because e1$nestedEnv points to a different environment than e2$nestedEnv:



                                e1$foo
                                [1] "Christmas"
                                e2$foo
                                [1] "Halloween"

                                e1$nestedEnv$bar
                                [1] "New Years"
                                e2$nestedEnv$bar
                                [1] "Thanksgiving"


                                Now, re-create e1 using Tommy's method:



                                e2 <- cloneEnv(e1, deep = FALSE)


                                nestedEnv in e2 points to the same environment as nestedEnv in e1:



                                identical(e1$nestedEnv, e2$nestedEnv)
                                [1] TRUE


                                Update the values in e2 and e2's nestedEnv:



                                e2$foo <- "Halloween"
                                e2$nestedEnv$bar <- "Thanksgiving"


                                Values of foo are independent:



                                e1$foo
                                [1] "Christmas"
                                e2$foo
                                [1] "Halloween"


                                but updating value e2's bar has also updated e1's bar because e1$nestedEnv and e2$nestedEnv reference (point to) the same environment.



                                e1$nestedEnv$bar
                                [1] "Thanksgiving"
                                e2$nestedEnv$bar
                                [1] "Thanksgiving"





                                share|improve this answer






























                                  0














                                  The "clone" method posted by Tommy won't make a true (deep) clone when e1 contains names that reference other environments. For instance, if e1$nestedEnv references an environment, e2$nestedEnv will reference the same environment, not a copy of that environment. Thus, the name e1$nestedEnv$bar will reference the same memory location as e2$nestedEnv$bar and any new value assigned to e1$nestedEnv$bar will be reflected for e2$nestedEnv$bar as well. This may be desirable behavior, but calling e2 a clone of e1 could be misleading.



                                  Here is a function that will allow the user to make either a copy of an environment while also copying any nested environments (a "deep clone", using deep = TRUE), or just use the method proposed by Tommy to copy the environment while maintaining original references to any nested environments (using deep = FALSE).



                                  The 'deep = TRUE' method uses rapply to recursively call cloneEnv on nested environment within envir, for as many levels as the environments are nested. So, in the end, it recursively calls rapply, which is a bit of a mind bender, but works pretty well.



                                  Note that if a nested environment contains a name that references a parent environment, using the "deep" method will never return from the recursive calls. If I could have figured out a way to check for this, I would have included it...



                                  Note, too, that environments can have attributes, so copying the attributes would be necessary for a true clone, which this solution also addresses.



                                  cloneEnv <- function(envir, deep = T) {
                                  if(deep) {
                                  clone <- list2env(rapply(as.list(envir, all.names = TRUE), cloneEnv, classes = "environment", how = "replace"), parent = parent.env(envir))
                                  } else {
                                  clone <- list2env(as.list(envir, all.names = TRUE), parent = parent.env(envir))
                                  }
                                  attributes(clone) <- attributes(envir)
                                  return(clone)
                                  }


                                  An example:



                                  Create environment e1, which also contains a nested environment:



                                  e1 <- new.env()
                                  e1$foo <- "Christmas"
                                  e1$nestedEnv <- new.env()
                                  e1$nestedEnv$bar <- "New Years"


                                  Show the values for foo and bar:



                                  e1$foo
                                  [1] "Christmas"
                                  e1$nestedEnv$bar
                                  [1] "New Years"


                                  Make a deep clone (i.e. e2 contains makes a copy of nestedEnv)



                                  e2 <- cloneEnv(e1, deep = TRUE)


                                  nestedEnv in e1 references a difference environment than nestedEnv in e2:



                                  identical(e1$nestedEnv, e2$nestedEnv)
                                  [1] FALSE


                                  But the values are the same because e2$nestedEnv is a copy of e1$nestedEnv:



                                  e2$foo
                                  [1] "Christmas"
                                  e2$nestedEnv$bar
                                  [1] "New Years"


                                  Change the values in e2:



                                  e2$foo <- "Halloween"
                                  e2$nestedEnv$bar <- "Thanksgiving"


                                  And values in e1 remain unchanged, again, because e1$nestedEnv points to a different environment than e2$nestedEnv:



                                  e1$foo
                                  [1] "Christmas"
                                  e2$foo
                                  [1] "Halloween"

                                  e1$nestedEnv$bar
                                  [1] "New Years"
                                  e2$nestedEnv$bar
                                  [1] "Thanksgiving"


                                  Now, re-create e1 using Tommy's method:



                                  e2 <- cloneEnv(e1, deep = FALSE)


                                  nestedEnv in e2 points to the same environment as nestedEnv in e1:



                                  identical(e1$nestedEnv, e2$nestedEnv)
                                  [1] TRUE


                                  Update the values in e2 and e2's nestedEnv:



                                  e2$foo <- "Halloween"
                                  e2$nestedEnv$bar <- "Thanksgiving"


                                  Values of foo are independent:



                                  e1$foo
                                  [1] "Christmas"
                                  e2$foo
                                  [1] "Halloween"


                                  but updating value e2's bar has also updated e1's bar because e1$nestedEnv and e2$nestedEnv reference (point to) the same environment.



                                  e1$nestedEnv$bar
                                  [1] "Thanksgiving"
                                  e2$nestedEnv$bar
                                  [1] "Thanksgiving"





                                  share|improve this answer




























                                    0












                                    0








                                    0







                                    The "clone" method posted by Tommy won't make a true (deep) clone when e1 contains names that reference other environments. For instance, if e1$nestedEnv references an environment, e2$nestedEnv will reference the same environment, not a copy of that environment. Thus, the name e1$nestedEnv$bar will reference the same memory location as e2$nestedEnv$bar and any new value assigned to e1$nestedEnv$bar will be reflected for e2$nestedEnv$bar as well. This may be desirable behavior, but calling e2 a clone of e1 could be misleading.



                                    Here is a function that will allow the user to make either a copy of an environment while also copying any nested environments (a "deep clone", using deep = TRUE), or just use the method proposed by Tommy to copy the environment while maintaining original references to any nested environments (using deep = FALSE).



                                    The 'deep = TRUE' method uses rapply to recursively call cloneEnv on nested environment within envir, for as many levels as the environments are nested. So, in the end, it recursively calls rapply, which is a bit of a mind bender, but works pretty well.



                                    Note that if a nested environment contains a name that references a parent environment, using the "deep" method will never return from the recursive calls. If I could have figured out a way to check for this, I would have included it...



                                    Note, too, that environments can have attributes, so copying the attributes would be necessary for a true clone, which this solution also addresses.



                                    cloneEnv <- function(envir, deep = T) {
                                    if(deep) {
                                    clone <- list2env(rapply(as.list(envir, all.names = TRUE), cloneEnv, classes = "environment", how = "replace"), parent = parent.env(envir))
                                    } else {
                                    clone <- list2env(as.list(envir, all.names = TRUE), parent = parent.env(envir))
                                    }
                                    attributes(clone) <- attributes(envir)
                                    return(clone)
                                    }


                                    An example:



                                    Create environment e1, which also contains a nested environment:



                                    e1 <- new.env()
                                    e1$foo <- "Christmas"
                                    e1$nestedEnv <- new.env()
                                    e1$nestedEnv$bar <- "New Years"


                                    Show the values for foo and bar:



                                    e1$foo
                                    [1] "Christmas"
                                    e1$nestedEnv$bar
                                    [1] "New Years"


                                    Make a deep clone (i.e. e2 contains makes a copy of nestedEnv)



                                    e2 <- cloneEnv(e1, deep = TRUE)


                                    nestedEnv in e1 references a difference environment than nestedEnv in e2:



                                    identical(e1$nestedEnv, e2$nestedEnv)
                                    [1] FALSE


                                    But the values are the same because e2$nestedEnv is a copy of e1$nestedEnv:



                                    e2$foo
                                    [1] "Christmas"
                                    e2$nestedEnv$bar
                                    [1] "New Years"


                                    Change the values in e2:



                                    e2$foo <- "Halloween"
                                    e2$nestedEnv$bar <- "Thanksgiving"


                                    And values in e1 remain unchanged, again, because e1$nestedEnv points to a different environment than e2$nestedEnv:



                                    e1$foo
                                    [1] "Christmas"
                                    e2$foo
                                    [1] "Halloween"

                                    e1$nestedEnv$bar
                                    [1] "New Years"
                                    e2$nestedEnv$bar
                                    [1] "Thanksgiving"


                                    Now, re-create e1 using Tommy's method:



                                    e2 <- cloneEnv(e1, deep = FALSE)


                                    nestedEnv in e2 points to the same environment as nestedEnv in e1:



                                    identical(e1$nestedEnv, e2$nestedEnv)
                                    [1] TRUE


                                    Update the values in e2 and e2's nestedEnv:



                                    e2$foo <- "Halloween"
                                    e2$nestedEnv$bar <- "Thanksgiving"


                                    Values of foo are independent:



                                    e1$foo
                                    [1] "Christmas"
                                    e2$foo
                                    [1] "Halloween"


                                    but updating value e2's bar has also updated e1's bar because e1$nestedEnv and e2$nestedEnv reference (point to) the same environment.



                                    e1$nestedEnv$bar
                                    [1] "Thanksgiving"
                                    e2$nestedEnv$bar
                                    [1] "Thanksgiving"





                                    share|improve this answer















                                    The "clone" method posted by Tommy won't make a true (deep) clone when e1 contains names that reference other environments. For instance, if e1$nestedEnv references an environment, e2$nestedEnv will reference the same environment, not a copy of that environment. Thus, the name e1$nestedEnv$bar will reference the same memory location as e2$nestedEnv$bar and any new value assigned to e1$nestedEnv$bar will be reflected for e2$nestedEnv$bar as well. This may be desirable behavior, but calling e2 a clone of e1 could be misleading.



                                    Here is a function that will allow the user to make either a copy of an environment while also copying any nested environments (a "deep clone", using deep = TRUE), or just use the method proposed by Tommy to copy the environment while maintaining original references to any nested environments (using deep = FALSE).



                                    The 'deep = TRUE' method uses rapply to recursively call cloneEnv on nested environment within envir, for as many levels as the environments are nested. So, in the end, it recursively calls rapply, which is a bit of a mind bender, but works pretty well.



                                    Note that if a nested environment contains a name that references a parent environment, using the "deep" method will never return from the recursive calls. If I could have figured out a way to check for this, I would have included it...



                                    Note, too, that environments can have attributes, so copying the attributes would be necessary for a true clone, which this solution also addresses.



                                    cloneEnv <- function(envir, deep = T) {
                                    if(deep) {
                                    clone <- list2env(rapply(as.list(envir, all.names = TRUE), cloneEnv, classes = "environment", how = "replace"), parent = parent.env(envir))
                                    } else {
                                    clone <- list2env(as.list(envir, all.names = TRUE), parent = parent.env(envir))
                                    }
                                    attributes(clone) <- attributes(envir)
                                    return(clone)
                                    }


                                    An example:



                                    Create environment e1, which also contains a nested environment:



                                    e1 <- new.env()
                                    e1$foo <- "Christmas"
                                    e1$nestedEnv <- new.env()
                                    e1$nestedEnv$bar <- "New Years"


                                    Show the values for foo and bar:



                                    e1$foo
                                    [1] "Christmas"
                                    e1$nestedEnv$bar
                                    [1] "New Years"


                                    Make a deep clone (i.e. e2 contains makes a copy of nestedEnv)



                                    e2 <- cloneEnv(e1, deep = TRUE)


                                    nestedEnv in e1 references a difference environment than nestedEnv in e2:



                                    identical(e1$nestedEnv, e2$nestedEnv)
                                    [1] FALSE


                                    But the values are the same because e2$nestedEnv is a copy of e1$nestedEnv:



                                    e2$foo
                                    [1] "Christmas"
                                    e2$nestedEnv$bar
                                    [1] "New Years"


                                    Change the values in e2:



                                    e2$foo <- "Halloween"
                                    e2$nestedEnv$bar <- "Thanksgiving"


                                    And values in e1 remain unchanged, again, because e1$nestedEnv points to a different environment than e2$nestedEnv:



                                    e1$foo
                                    [1] "Christmas"
                                    e2$foo
                                    [1] "Halloween"

                                    e1$nestedEnv$bar
                                    [1] "New Years"
                                    e2$nestedEnv$bar
                                    [1] "Thanksgiving"


                                    Now, re-create e1 using Tommy's method:



                                    e2 <- cloneEnv(e1, deep = FALSE)


                                    nestedEnv in e2 points to the same environment as nestedEnv in e1:



                                    identical(e1$nestedEnv, e2$nestedEnv)
                                    [1] TRUE


                                    Update the values in e2 and e2's nestedEnv:



                                    e2$foo <- "Halloween"
                                    e2$nestedEnv$bar <- "Thanksgiving"


                                    Values of foo are independent:



                                    e1$foo
                                    [1] "Christmas"
                                    e2$foo
                                    [1] "Halloween"


                                    but updating value e2's bar has also updated e1's bar because e1$nestedEnv and e2$nestedEnv reference (point to) the same environment.



                                    e1$nestedEnv$bar
                                    [1] "Thanksgiving"
                                    e2$nestedEnv$bar
                                    [1] "Thanksgiving"






                                    share|improve this answer














                                    share|improve this answer



                                    share|improve this answer








                                    edited Nov 13 '18 at 6:00

























                                    answered Nov 13 '18 at 5:40









                                    Geoffrey PooleGeoffrey Poole

                                    27126




                                    27126






























                                        draft saved

                                        draft discarded




















































                                        Thanks for contributing an answer to Stack Overflow!


                                        • Please be sure to answer the question. Provide details and share your research!

                                        But avoid



                                        • Asking for help, clarification, or responding to other answers.

                                        • Making statements based on opinion; back them up with references or personal experience.


                                        To learn more, see our tips on writing great answers.




                                        draft saved


                                        draft discarded














                                        StackExchange.ready(
                                        function () {
                                        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f9965577%2fr-copy-move-one-environment-to-another%23new-answer', 'question_page');
                                        }
                                        );

                                        Post as a guest















                                        Required, but never shown





















































                                        Required, but never shown














                                        Required, but never shown












                                        Required, but never shown







                                        Required, but never shown

































                                        Required, but never shown














                                        Required, but never shown












                                        Required, but never shown







                                        Required, but never shown







                                        Popular posts from this blog

                                        Full-time equivalent

                                        Bicuculline

                                        さくらももこ