0

I would like to use values within variables for defining functions in R. However, after declaring the function I can still see the variable names instead of their values inside the function definition. Here is an example:

> variable <- 10 > fn <- function() {message(variable*2)} > fn function() {message(variable*2)} 

And what I am expecting to see:

> variable <- 10 > fn <- function() {message(variable*2)} > fn function() {message(10*2)} 

How could I fix this?

6
  • 1
    Why exactly are you trying to change the behavior? R is a functional language and creates closures. If you don't want variable to be a free variable, you can create a closure around it, but it won't change the function definition. Is this just a display issue? Or is there some behavior that you are trying to change? Commented Sep 5, 2024 at 16:14
  • 1
    @MrFlick I want to use the primary function inside another function which will store the primary function into an output object. Without the actual values, there is no record what kind of operations were used exactly, as the contents of the variables will change during each run. Commented Sep 5, 2024 at 16:23
  • Thanks all for the tips, I need to test them. I would also like to verify a related thing. If a function is declared using the variables of a enclosing function, and the variable names stay in the inner function's definition, are the contents of the variables preserved with the inner function? I want to ensure, because once the enclosing function is executed I believe its memory reservations are erased, but are the variables with their contents put into to the environment of the inner function (or what is the proper terminology). My tests shows that this is the case, in line with common sense. Commented Sep 6, 2024 at 8:06
  • 1
    The variables in the enclosing function are stored in an environment which is the parent of the new function's environment. As long as that reference continues to exist they will not be erased. If the enclosing function returns the new function (as in my answer below), they remain until that returned function is deleted. Commented Sep 6, 2024 at 14:51
  • 1
    What you need to be careful about is lazy evaluation. If you are referring to an argument of the enclosing function, it won't be evaluated until first used. That's why I used force(variable). Commented Sep 6, 2024 at 14:53

2 Answers 2

3

Like @MrFlick in his comment, I don't know why you would want to do this. But in case you have a reason for it, here's one way to do it:

fn <- function() 1 # dummy declaration body(fn) <- substitute( # The body of the function {message(variable*2)}, # The substitutions you want list(variable = 10)) fn #> function () #> { #> message(10 * 2) #> } 

Created on 2024-09-05 with reprex v2.1.1

Edited to add:

I just read your response to his comment. I think you are taking the wrong approach here. This is a better way to do what you want:

makeFn <- function(variable) { force(variable) # Make sure it is evaluated function() {message(variable*2)} } fn10 <- makeFn(10) fn20 <- makeFn(20) fn10() #> 20 fn20() #> 40 

Created on 2024-09-05 with reprex v2.1.1

Sign up to request clarification or add additional context in comments.

Comments

3

Rather than modify the function code wrap the variable together with the function in the same environment using local . (Depending on what is in the function you may need to add the envir = .GlobalEnv argument to local.)

fn <- local({ variable <- 10 function() {message(variable*2)} }) fn() ## 20 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.