Reputation: 1441
I am using a function within a function in R
to create new variables. What I need is to be able to use these variables in the parent environment, BUT not global.
For instance, one solution is to use the global assignment operator <<-
:
f1 <- function(x){
cat("X is ", x, "\n")
f2 <- function(){
cat("X will now be transfromed\n")
y <<- x + 4 # Use Global assignment
}
f2()
cat("Y is ", y, "\n")
}
f1(x = 5)
But I have over 20 variables, so this will clutter my workspace and is bad practice.
I was wondering if there is a better solution without having to play with concepts such as vars_to_parent <- new.env()
.
Is there is some elegant R
sorcery where you have a new assignment operator, maybe something silly such as:
`<p-` <- function(){assign variable in such a way that its available in parent}
Which could help you to get these newly created variables to parent environment:
f1 <- function(x){
cat("X is ", x, "\n")
f2 <- function(){
cat("X will now be transfromed\n")
y <p- x + 4 # New cool assignment operator
}
f2()
cat("Y is ", y, "\n")
}
f1(x = 5)
Upvotes: 4
Views: 580
Reputation: 270298
The last line of f
will copy all variables in f
to the specified environment. Alternately, replace as.list(environment())
with list("a", "b")
or to only copy variables beginning with a lower case letter, say, as.list(ls(pattern = "^[a-z]"))
if (exists("a")) rm(a)
if (exists("b")) rm(b)
f <- function(envir = parent.frame()) {
a <- b <- 1
invisible( list2env(as.list(environment()), envir) )
}
f()
a
## [1] 1
b
## [1] 1
Rather than inject the variables directly into the parent another possibility which is a bit cleaner is to return the environment itself:
f2 <- function(envir = parent.frame()) {
a <- b <- 1
environment()
}
e <- f()
e$a
## [1] 1
e$b
## [1] 1
or return a list by replacing the last statement in f2 with:
list2env(environment())
Upvotes: 3