Force evaluation with deparse in R

88 Views Asked by At

I have a function that produces a function:

fun1 <- function (x)
    return (function() x)

By the time a function is produced, the value of x is already basically a constant:

fun2 <- fun1 ("a")

However, when I have fun2 printed, it won't show the actual value, it only shows "x" even though it is by now obsolete:

> fun2
function() x
<environment: 0x55a9f94f9fc8>

How can I force the evaluation of x so that fun2 gets printed as

function() "a"

or however it was produced?

2

There are 2 best solutions below

3
On BEST ANSWER

There's no need to resort to deparse here. You can write the evaluated value of x into the body of the newly created function:

fun1 <- function (x){
  f <- function() x
  body(f) <- x
  f
}

So that:

fun1("a")
#> function () 
#> "a"
#> <environment: 0x00000146d0449dd8>

and

f <- fun1("a")
f()
#> [1] "a"

EDIT

If you wanted f to take an argument you could do:

fun1 <- function (x){
  f <- function(y) y + x
  body(f)[[3]] <- x
  f
}

so that

fun1(3)
#> function (y) 
#> y + 3
#> <environment: 0x00000146d4b702a0>
1
On

This substitutes all instances of x in the body of fun. In the example fun1 has one argument but it would continue to work with multiple fun1 arguments used in fun substituting them all into fun. We have also set the environment of fun to the environment in the caller of fun1 allowing the caller to change that by specifying envir if needed.

fun1 <- function (x, envir = parent.frame()) {
    fun <- function() x
    body(fun) <- do.call("substitute", list(body(fun)))
    environment(fun) <- envir
    fun
}

fun2 <- fun1("a")
fun2
## function () 
## "a"

environment(fun2)
## <environment: R_GlobalEnv>