Overcoming environment obstacles in R

Recently, while working on a function inside my ggloop package, I came across an unusual problem. There is a function which is called as an argument inside another function. It goes something like this:

# Define the "outer" function.
outer.fun <- function(arg1, arg2){
  print(arg1)

}

# Define the "inner" function.
inner.fun <- function(iarg){
  return(iarg)
}

# Call the "inner" function as an "outer" function argument.
outer.fun(arg1 = inner.fun(args), arg2 = x)

Because inner.fun() is passed as an argument to outer.fun(), it has the same calling environment as outer.fun(). So, if I want the inner.fun‘s argument to be the other argument passed to outer.fun, then it cannot look in the calling environment for that value.

Solution

While reading Hadley Wickham’s Advanced R, I came across the solution to my problem in the section on calling environments. A function can be written so as to pass along its body (an aliasing method).

When this is done, the aliasing function passes along the body of a function to a variable – this turns the variable into a function (binding). It also passes the unique evaluation environment used to evaluate arguments and expressions before the function body.

In essence, calling one function and assigning it a name gives that name the function body: making it a function itself. In my case, the solution would look something like this:

# Define the outer function.
outer.fun <- function(arg1, arg2){
  # Bind the return value (function body)
  # to a new variable: arg3.
  arg3 <- arg1  

  # Pass arg2 to arg3() and print
  # the returned value.
  print(arg3(arg2))

}

# Define the "inner" function.
inner.fun <- function(){
  function(iarg){
    return(iarg)
  {
}

# Call the "inner" function as an "outer" function argument.
outer.fun(arg1 = inner.fun(args), arg2 = x)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s