1

I want to store the output of a function as a new variable on the global environment, any suggestions?

a <- 4
doubleit <- function(x){
   doubled <- x * 2
}

What I want is to have a variable on the global environment called doubled with any value entered via doubleit.

7
  • 2
    Try doubleit <- function(x){assign('doubled', x*2, envir=.GlobalEnv)} Commented Jan 16, 2015 at 17:17
  • 5
    Some people might also use <<- for this. (And don't be surprised if people pop up in the comments to tell you this whole thing is a bad idea.) Commented Jan 16, 2015 at 17:19
  • 1
    Because you're modifying the global environment from within a function (a different environment). It's never a good idea Commented Jan 16, 2015 at 17:21
  • 6
    Not required at all. Try doubleit <- function(x) x * 2; doubled <- doubleit(a) Then pass doubled to the other function Or you can nest them otherFun(doubleit(a)) Commented Jan 16, 2015 at 17:27
  • 1
    Its a bad idea because: if there's a variable called "doubled" already you will overwrite it; if instead you want to create a variable called "twiced" you can't without creating a new function and lots of other reasons. Functions really shouldn't have these "side effects", they should only return values which you can then assign in the function call. Commented Jan 16, 2015 at 17:56

1 Answer 1

1

Sometimes there are legitimate reasons why 2 or more functions may need to share some variables, such as saving a state, or setting an option in one function to use in future function calls. Another case is where the one function will be called by another function (e.g. optim) that you do not control, so you cannot have your function return information from the function to use latter (it will confuse the intermediate function).

While there are legitimate reasons, using a global variable to share this information is not the best approach and can lead to hard to find errors, overwriting of data, and other problems.

One of the better options is to use object oriented programming where the shared information is stored in an object (and you can have more than 1) and the functions that need to share the information are methods. Here is an example using the R6 package:

> library(R6)
> 
> counter <- R6Class(
+   "counter",
+   public = list(
+       value = 0,
+       inc = function(amount=1) {
+         self$value <- self$value + amount
+       },
+       dec = function(amount=1) {
+         self$value <- self$value - amount
+       }
+     )    
+   )
> 
> c1 <- counter$new()
> c2 <- counter$new()
> 
> c1$value
[1] 0
> (c1$inc())
[1] 1
> (c1$inc())
[1] 2
> (c1$inc(5))
[1] 7
> (c2$inc())
[1] 1
> (c2$inc())
[1] 2
> (c1$dec())
[1] 6
> c1$value
[1] 6
> c2$value
[1] 2
> 

Another option (great for options, file handles, etc. in packages) it to have an environment other than the global environment that the functions can access. Here is another example using this technique (but notice that there is only one counter possible at a time this way)

> myenv <- new.env(parent=emptyenv())
> myenv$value <- 0
> 
> inc <- function(amount=1) {
+   myenv$value <- myenv$value + amount
+ }
> 
> dec <- function(amount=1) {
+   myenv$value <- myenv$value - amount
+ }
> 
> myenv$value
[1] 0
> (inc())
[1] 1
> (inc())
[1] 2
> (inc(3))
[1] 5
> (dec())
[1] 4
> myenv$value
[1] 4

If the new environment is in the global environment then you still need to be careful that it is not overwritten, but that is usually not much of a problem if you choose a good name. If this is part of a package then the new environment goes in the package namespace and is not directly accessible (able to be corrupted) by the user while allowing the functions to pass information back and forth.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.