it is possible to dynamically create functions in R using lists? what I want to do is something like this: a = list() for (i in 1:10) a[[i]] = function(seed = i) runif(seed) so that when I call a[i] I get random draws 1,2,....i unfortunately R only uses the last i . I would also like to know if there is a run-all function without explicitly looping or using lapply. for example if I have a list 'b' of functions if I called run-all(b) all the functions in list 'b' would be run thanks. -- View this message in context: http://r.789695.n4.nabble.com/dynamically-creating-functions-in-r-tp3874767p3874767.html Sent from the R help mailing list archive at Nabble.com.
Hi, On Wed, Oct 5, 2011 at 10:57 AM, honeyoak <honeyoak at gmail.com> wrote:> it is possible to dynamically create functions in R using lists? what I want > to do is something like this: > > ? ? ?a = list() > ? ? ?for (i in 1:10) a[[i]] = function(seed = i) runif(seed) > > so that when I call a[i] I get random draws 1,2,....i unfortunately R only > uses the last i .I'm not sure I understand what you want. Do you want to set a new seed for the random number generator, or do you want a random vector of length i each time? If the former, I'm not sure why you'd want to do that, but your choice of variable names makes me wonder. If the latter, you just need a bit of clean-up. a <- list() for (i in 1:10) { a[[i]] <- runif(i) } But that's not dynamically creating a function, so maybe I'm missing the point.> I would also like to know if there is a run-all function > without explicitly looping or using lapply. for example if I have a list 'b' > of functions if I called > > ? ? ?run-all(b) > > all the functions in list 'b' would be run > > thanks.What's wrong with lapply? I think we need to know more about what you're trying to do. You might also want to look at do.call(). Sarah -- Sarah Goslee http://www.functionaldiversity.org
On 05/10/2011 10:57 AM, honeyoak wrote:> it is possible to dynamically create functions in R using lists? what I want > to do is something like this: > > a = list() > for (i in 1:10) a[[i]] = function(seed = i) runif(seed) > > so that when I call a[i] I get random draws 1,2,....i unfortunately R only > uses the last i .That is because you never evaluate it until you call the function. You can do what you want in several ways; one is for (i in 1:10) a[[i]] <- local( { default <- i; function(seed = default) runif(seed) } ) Duncan Murdoch> I would also like to know if there is a run-all function > without explicitly looping or using lapply. for example if I have a list 'b' > of functions if I called > > run-all(b) > > all the functions in list 'b' would be run > > thanks. > > -- > View this message in context: http://r.789695.n4.nabble.com/dynamically-creating-functions-in-r-tp3874767p3874767.html > Sent from the R help mailing list archive at Nabble.com. > > ______________________________________________ > 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.
Creating expressions and functions dynamically can be tricky. Usually I use functions like call(), substitute(), and formals(); very occasionally I use parse(text=). Here is one way to make a family of functions that differ only in the default value their their argument: > funsA <- lapply(1:3, function(i){ retval <- function(arg=i)arg^2 formals(retval)$arg <- i retval }) > sapply(funsA, function(f)f()) [1] 1 4 9 > funsA[[2]] function (arg = 2L) arg^2 <environment: 0x2985d18> Here is a way to make the functions differ in their bodies: > funsB <- lapply(c("sin", "cos", "sqrt"), function(fname) eval(substitute(function(x)f(x)^2, list(f=as.name(fname))))) > sapply(funsB, function(f)f(pi/3)) [1] 0.750000 0.250000 1.047198 > funsB[[2]] function (x) cos(x)^2 <environment: 0x2412b20> You can also add things to environment(yourFunction), where you arrange that each function has its own personal environment, instead of altering the function itself. This works, but can look a bit mysterious to the na?ve user who doesn't know to look in the environment of the function: > funsC <- lapply(1:3, function(i){ retval <- function(arg=i)arg^2 with(environment(retval), i <- i) retval }) > sapply(funsC, function(f)f()) [1] 1 4 9 > funsC[[2]] function (arg = i) arg^2 <environment: 0x2b0f230> > as.list(environment(funsC[[2]])) $retval function (arg = i) arg^2 <environment: 0x2b0f230> $i [1] 2 Bill Dunlap Spotfire, TIBCO Software wdunlap tibco.com> -----Original Message----- > From: r-help-bounces at r-project.org [mailto:r-help-bounces at r-project.org] On Behalf Of honeyoak > Sent: Wednesday, October 05, 2011 7:57 AM > To: r-help at r-project.org > Subject: [R] dynamically creating functions in r > > it is possible to dynamically create functions in R using lists? what I want > to do is something like this: > > a = list() > for (i in 1:10) a[[i]] = function(seed = i) runif(seed) > > so that when I call a[i] I get random draws 1,2,....i unfortunately R only > uses the last i . I would also like to know if there is a run-all function > without explicitly looping or using lapply. for example if I have a list 'b' > of functions if I called > > run-all(b) > > all the functions in list 'b' would be run > > thanks. > > -- > View this message in context: http://r.789695.n4.nabble.com/dynamically-creating-functions-in-r- > tp3874767p3874767.html > Sent from the R help mailing list archive at Nabble.com. > > ______________________________________________ > 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.
Another way to build functions "from scratch" : > func<-'x^2+5' > funcderiv<- D(parse(text=func), 'x') ) > newtparam <- function(zvar) {} > body(newtparam)[2] <- parse(text=paste('newz <- (',func,')/eval(funcderiv)',collapse='')) > body(newtparam)[3] <- parse(text=paste('return(invisible(newz))')) > newtparam function (zvar) { newz <- (x^2 + 5)/eval(funcderiv) return(invisible(newz)) } The important thing to know if you go with this method is that body(your_function)[1] is always "{}" Carl -- ----- Sent from my Cray XK6