[R] dynamically creating functions in r

William Dunlap wdunlap at tibco.com
Wed Oct 5 21:55:21 CEST 2011


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.



More information about the R-help mailing list