[R] Environment question

Duncan Murdoch murdoch.duncan at gmail.com
Fri Nov 13 20:13:20 CET 2015


On 13/11/2015 12:53 PM, ALBERTO VIEIRA FERREIRA MONTEIRO wrote:
> I have another environment question.
>
> I understand why this works as expected:
>
> f.factory <- function()
> {
>    y <- 2
>    fname <- paste("plus", y, sep = ".")
>    f <- function(x) x + y
>    assign(fname, f, envir = globalenv())
> }
>
> f.factory()
> plus.2(2) # 4
>
> and I also understand why this does NOT work:
>
> f.factory <- function()
> {
>    for (y in 2:3) {
>      fname <- paste("plus", y, sep = ".")
>      f <- function(x) x + y
>      assign(fname, f, envir = globalenv())
>    }
> }
>
> f.factory()
> plus.2(2) # 5
>    
> (the reason is that both plus.2 and plus.3 have the
> same environment as f.factory when f.factory terminates,
> which assign 2 to variable y in the first case and 3 in
> the second case)
>
> However, I don't know an elegant way to adapt f.factory
> so that it works as expected. Any suggestions?

I think Bill answered your question.  I'd suggest that you should ask a 
different question.  It's generally a bad idea to use assign(), 
especially for assignments into the global environment. Your f.factory 
should return a value, it shouldn't modify globalenv().   It's often a 
bad idea to refer to the environment explicitly at all.  So my 
recommended solution might be this variation on Bill's:

f.factory4 <- function()
{
   result <- list()
   for (y in 2:3) {
     result[[y]] <- local({
       ylocal <- y
       function(x) x + ylocal
     })
     names(result)[y] <- paste("plus", y, sep = ".")
   }
   result
}

The "names" line is optional; with it, you can use

f <- f.factory4()
f$plus.2(2)

but with or without it you can use

f[[2]](2)

Duncan Murdoch



More information about the R-help mailing list