On 15/11/2010 4:10 PM, William Dunlap wrote:
You could make f[[i]] be function(t)t^2+i for i in 1:10
with
      f<- lapply(1:10, function(i)local({ force(i) ; function(x)x^2+i}))
After that we get the correct results
     >  f[[7]](100:103)
     [1] 10007 10208 10411 10616
but looking at the function doesn't immdiately tell you
what 'i' is in the function
     >  f[[7]]
     function (x)
     x^2 + i
     <environment: 0x19d7458>
You can find it in f[[7]]'s environment
     >  get("i", envir=environment(f[[7]]))
     [1] 7

The call to force() in the call to local() is not
necessary in this case, although it can help in
other situations.

I thought it would be clearer to use substitute.  My first guess was

 f <- list()
 for (i in 1:10)
   f[[i]] <- substitute(function(t) t^2 + increment, list(increment=i))

but this doesn't work; f[[i]] ends up as an expression evaluating to the function we want. So it looks okay

> f[[3]]
function(t) t^2 + 3L

but it doesn't work:

> f[[3]](1)
Error: attempt to apply non-function

So I tried to eval it:

> eval(f[[3]])
function(t) t^2 + increment

Now that's a puzzle!!  Why did increment come back?  But it works:

> eval(f[[3]])(1)
[1] 4

(I do actually know the answer to the puzzle, but it took me a while to figure out. Spoiler below.)

So here's what I'd recommend as an answer to the original question:

save <- options(keep.source=FALSE)
f <- list()
for (i in 1:10)
f[[i]] <- eval(substitute(function(t) t^2 + increment, list(increment=i)))
options(save)

Then things look just right:

> f[[3]]
function (t)
t^2 + 3L
> f[[3]](4)
[1] 19
> f[[3]](1)
[1] 4

Of course, I didn't quite meet my objective of coming up with code that looked simpler than your lapply() suggestion. But at least we end up with functions with simple environments that print properly.

Duncan Murdoch


Bill Dunlap
Spotfire, TIBCO Software
wdunlap tibco.com

-----Original Message-----
From: r-help-boun...@r-project.org
[mailto:r-help-boun...@r-project.org] On Behalf Of Eduardo de
Oliveira Horta
Sent: Monday, November 15, 2010 12:50 PM
To: r-help@r-project.org
Subject: [R] Defining functions inside loops

Hello,

I was trying to define a set of functions inside a loop, with
the loop index
working as a parameter for each function. Below I post a
simpler example, as
to illustrate what I was intending:

f<-list()
for (i in 1:10){
   f[[i]]<-function(t){
     f[[i]]<-t^2+i
   }
}
rm(i)

With that, I was expecting that f[[1]] would be a function
defined by t^2+1,
f[[2]] by t^2+2 and so on. However, the index i somehow
doesn't "get in" the
function definition on each loop, that is, the functions
f[[1]] through
f[[10]] are all defined by t^2+i. Thus, if I remove the
object i from the
workspace, I get an error when evaluating these functions.
Otherwise, if
don't remove the object i, it ends the loop with value equal
to 10 and then
f[[1]](t)=f[[2]](t)=...=f[[10]](t)=t^2+10.

I am aware that I could simply put

f<-function(u,i){
   f<-t^2+i
}

but that's really not what I want.

Any help would be appreciated. Thanks in advance,

Eduardo Horta

        [[alternative HTML version deleted]]

______________________________________________
R-help@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide
http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.


______________________________________________
R-help@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.

______________________________________________
R-help@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.

Reply via email to