Rolf Turner
2012-Jan-07 02:43 UTC
[R] Putting an index explicitly into function code --- a curiosity.
I want to create a list of functions in a for loop, with the index of the loop appearing explicitly in the function code. After quite a bit of thrashing around I figured out how to do it. Here is a toy example: junk <- vector("list",4) for(i in 1:4) { itmp <- i junk[[i]] <- eval(bquote(function(x){42 + .(itmp)*x})) } So I'm *basically* happy, but there's something I don't understand: Why do I need "itmp"? That is, if I do junk <- vector("list",4) for(i in 1:4) { junk[[i]] <- eval(bquote(function(x){42 + .(i)*x})) } then every entry of "junk" is equal to function (x) { 42 + 4L * x } i.e. I seem to get the *last* value of the index always substituted, rather than the "current" value. Something (subtle?) is going on that I don't understand. And than makes me feel not quite comfy. Can anyone enlighten me? Ta. cheers, Rolf Turner P. S. Also: Is there a *better* way of accomplishing my objective than what I came up with? R. T.
R. Michael Weylandt <michael.weylandt@gmail.com>
2012-Jan-07 02:51 UTC
[R] Putting an index explicitly into function code --- a curiosity.
I imagine the answer will involve lazy evaluation and require you use force() but I'm not quite qualified to pronounce and not at a computer to test. Michael On Jan 6, 2012, at 8:43 PM, Rolf Turner <rolf.turner at xtra.co.nz> wrote:> > I want to create a list of functions in a for loop, with the index > of the loop appearing explicitly in the function code. > > After quite a bit of thrashing around I figured out how to do it. > > Here is a toy example: > > junk <- vector("list",4) > for(i in 1:4) { > itmp <- i > junk[[i]] <- eval(bquote(function(x){42 + .(itmp)*x})) > } > > So I'm *basically* happy, but there's something I don't understand: > Why do I need "itmp"? > > That is, if I do > > junk <- vector("list",4) > for(i in 1:4) { > junk[[i]] <- eval(bquote(function(x){42 + .(i)*x})) > } > > then every entry of "junk" is equal to > > function (x) > { > 42 + 4L * x > } > > i.e. I seem to get the *last* value of the index always substituted, rather than > the "current" value. Something (subtle?) is going on that I don't understand. > And than makes me feel not quite comfy. Can anyone enlighten me? > > Ta. > > cheers, > > Rolf Turner > > P. S. Also: Is there a *better* way of accomplishing my objective than what I came up with? > > R. T. > > ______________________________________________ > R-help at 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.
Gabor Grothendieck
2012-Jan-07 03:46 UTC
[R] Putting an index explicitly into function code --- a curiosity.
On Fri, Jan 6, 2012 at 9:43 PM, Rolf Turner <rolf.turner at xtra.co.nz> wrote:> > I want to create a list of functions in a for loop, with the index > of the loop appearing explicitly in the function code. > > After quite a bit of thrashing around I figured out how to do it. > > Here is a toy example: > > junk <- vector("list",4) > for(i in 1:4) { > ? ?itmp <- i > ? ?junk[[i]] <- eval(bquote(function(x){42 + .(itmp)*x})) > } > > So I'm *basically* happy, but there's something I don't understand: > Why do I need "itmp"? > > That is, if I do > > junk <- vector("list",4) > for(i in 1:4) { > ? ?junk[[i]] <- eval(bquote(function(x){42 + .(i)*x})) > } > > then every entry of "junk" is equal to > > function (x) > { > ? ?42 + 4L * x > } > > i.e. I seem to get the *last* value of the index always substituted, rather > than > the "current" value. ?Something (subtle?) is going on that I don't > understand. > And than makes me feel not quite comfy. ?Can anyone enlighten me?This seems quite strange. For example, if we replace the for with a while then we don't need to force i: junk <- vector("list",4) i <- 1 while(i <= 4) { junk[[i]] <- eval(bquote(function(x){42 + .(i)*x})) i <- i + 1 } junk I am using:> R.version.string[1] "R version 2.14.1 Patched (2011-12-26 r58001)"> win.version()[1] "Windows Vista (build 6002) Service Pack 2" -- Statistics & Software Consulting GKX Group, GKX Associates Inc. tel: 1-877-GKX-GROUP email: ggrothendieck at gmail.com
Carl Witthoft
2012-Jan-07 16:24 UTC
[R] Putting an index explicitly into function code --- a curiosity.
Now that we've all satisfied our curiosity :-) about force() in for and while loops, I suppose it would be impolite to ask Rolf whether there isn't a much neater and simpler way to make his internal functions grab whatever the index 'i' is pointing them to? -- Sent from my Cray XK6 "Pendeo-navem mei anguillae plena est."