4

I would like to delay the evaluation of a function argument in R. Example:

my_func <- function(FUN){print(FUN); print(FUN)}
my_func(runif(1))
#> [1] 0.2833882
#> [1] 0.2833882

Created on 2019-07-21 by the reprex package (v0.2.1)

This works as documented because runif(1) is only evaluated once and its results printed twice.

Instead, I don't want runif(1) to be evaluated until it is within each print() statement. This would generate two different random numbers.

In other words, I don't want FUN to "resolve" --- if that is the right word --- to runif(1) until we are within a print() statement.

Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
David Kane
  • 363
  • 1
  • 2
  • 8

3 Answers3

3

You can also achieve this with substitute and eval:

my_func <- function(FUN) {
  print(eval(substitute(FUN)))
  print(eval(substitute(FUN)))
}

my_func(runif(1))
#> [1] 0.09973534
#> [1] 0.8096205

my_func(runif(1))
#> [1] 0.2231202
#> [1] 0.5386637

NB: For additional details, check out this chapter Non-standard evaluation of Advanced R

Joris C.
  • 5,721
  • 3
  • 12
  • 27
2

Here is one trick with match.call and eval

my_func <- function(FUN){
  print(eval(match.call()[[2]])) 
  print(eval(match.call()[[2]]))
}

my_func(runif(1))

#[1] 0.7439711
#[1] 0.5011816

my_func(runif(1))
#[1] 0.7864152
#[1] 0.730453
Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
1

provide and expression

f = function(EXPR){
  print(EXPR)
  eval(EXPR)
}

EXPR = expression(runif(1))
> f(EXPR)
expression(runif(1))
[1] 0.1761139

provide an string

f2 = function(STR){
  print(STR)
  eval(parse(text = STR)) 
}

STR = "runif(1)"
> f2(STR)
[1] "runif(1)"
[1] 0.7630865
Daniel Fischer
  • 947
  • 6
  • 8