[R] retrieving object names passed indirectly to a function

Michael Bedward michael.bedward at gmail.com
Wed Sep 15 14:28:53 CEST 2010


Answering my own question (in case it's of use to anyone else) here is
the example code again but now using call and eval to accomplish the
desired output:

foo <- function(p1, p2) {
  p1name <- deparse(substitute(p1))
  p2name <- deparse(substitute(p2))

  # The real function runs a simulation, but
  # here we just confirm the object names
  # and values passed as args
  cat("passed", p1name, "with value", p1, "\n")
  cat("passed", p2name, "with value", p2, "\n")
}

foo.driver <- function(param.table) {
  for (i in 1:nrow(param.table)) {
    foo.call <- call("foo",
        as.name(param.table$p1[i]),
        as.name(param.table$p2[i]) )

    for (rep in 1:param.table$repl[i]) {
      eval(foo.call)
    }
  }
}

# some objects in the global env which will be used as args to foo
p1a <- 1.1
p1b <- 1.2
p2a <- 2.1
p2b <- 2.2

# the controlling table for foo.driver
param.table <- data.frame(p1=c("p1a", "p1b"), p2=c("p2a","p2b"),
   replicates=c(1,1), stringsAsFactors=FALSE)

# Now run foo.driver with param.table...
foo.driver(param.table)

The code above produces the following output:
passed p1a with value 1.1
passed p2a with value 2.1
passed p1b with value 1.2
passed p2b with value 2.2

Happy :)

Michael

On 15 September 2010 16:07, Michael Bedward <michael.bedward at gmail.com> wrote:
> Hi folks,
>
> I'm stuck with a problem that I suspect has a trivial solution...
>
> I have a function, call it foo, that takes a number of arguments which
> it uses as parameters for a simulation. For later analysis, foo stores
> the names of the objects passed to it along with the simulation
> results in its output (written to a database). The objects names are
> accessed with deparse(substitute(argname)).
>
> A second function, call it foo.driver, takes as input a data.frame
> with cols corresponding to foo arguments containing the character
> names of objects. For each row of the data.frame in turn, it retrieves
> the required objects from the global environment and passes them to
> function foo.
>
> Where I am stuck is in how foo.driver should pass an object to foo
> such that calling deparse(substitute(argname)) in foo will retrieve
> the correct name (ie. that specified in foo.driver's input
> data.frame).
>
> Hopefully, the following toy code example illustrates what I'm trying to do...
>
> # some objects in the global environment to provide param values to foo
> p1.1 <- 1
> p1.2 <- 2
> p2.1 <- 3
> p2.2 <- 4
>
> # controlling table
> arg.table <- data.frame(p1=c("p1.1", "p2.2"), p2=c("p2.1", "p2.2"),
> replicates=c(100, 100))
>
> foo.driver <- function( arg.table ) {
>  for (i in 1:nrow(arg.table)) {
>    for (j in 1:arg.table$replicates[i]) {
>      # somehow retrieve objects named in cols p1 and p2 and
>      # pass them to foo with their original names
>      # (e.g. some clever use of get and assign ?)
>    }
>  }
> }
>
> foo <- function(p1, p2) {
>  # retrieve and store arg names
>  p1name <- deparse(substitute(p1))
>  p2name <- deparse(substitute(p2))
>
>  # run simulation with values of p1 and p2 then
>  # store results together with names of objects
>  # passed as args to output database
> }
>
> My actual simulation function involves a large number of arguments of
> various classes and if at all possible I prefer to avoid hacking it
> (e.g to accept object names rather than objects).
>
> Any tips much appreciated.
>
> Michael
>



More information about the R-help mailing list