David Kane
David Kane

Reputation: 473

How to delay the evaluation of function arguments in R?

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.

Upvotes: 5

Views: 720

Answers (3)

Daniel Fischer
Daniel Fischer

Reputation: 973

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

Upvotes: 0

Joris C.
Joris C.

Reputation: 6234

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

Upvotes: 3

Ronak Shah
Ronak Shah

Reputation: 389055

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

Upvotes: 2

Related Questions