Reputation: 1205
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.
Upvotes: 1
Views: 4220
Reputation: 49660
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.
Upvotes: 1