R: deep copy of function argument

Consider the following code

i = 3 j = i i = 4 # j != i 

However i want

 i = 3 f <- function(x, j=i) x * j i = 4 f(4) # 16, but i want it to be 12 

If you're wondering why I want to do this, you can consider this code - the application is a model with several abbreviations. The diagonals of the transition matrix are the sum of the other decrements in this row. I would like to determine the decrements that I need, than to calculate other functions using these decrements. In this case, I only need uxt01 and uxt10, and from them I want to create the uxt00 and uxt11 functions. I wanted something that scales to higher dimensions.

 Qxt <- matrix(c(uxt00=function(t=0,x=0) 0, uxt01=function(t=0,x=0) 0.05, uxt10=function(t=0,x=0) 0.07 uxt11=function(t=0,x=0) 0), 2, 2, byrow=TRUE) Qxt.diag <- function(Qxt) { ndecrements <- length(Qxt[1,]) for(index in seq(1, N, N+1)) { # 1, 4 Qxt[[index]] <- function(t=0, x=0, i=index, N=ndecrements) { row <- ceiling(index/ndecr) row.decrements <- seq( (row - 1)*N + 1, (row)*N) other.decrements <- row.decrements[which(row.decrements != i] -sum(unlist(lapply(Qxt.fns[[other.decrements]], function(f) f(t,x)))) } } Qxt.fns } 
+6
source share
2 answers

This can be done by manually setting the default expression for the formal parameter j , after creating the function:

 i <- 3; f <- function(x,j) x*j; f; ## function(x,j) x*j formals(f); ## $x ## ## ## $j ## ## formals(f)$j <- i; f; ## function (x, j = 3) ## x * j formals(f); ## $x ## ## ## $j ## [1] 3 ## i <- 4; f(4); ## [1] 12 

This is only possible because R is an amazing language and provides full read / write access to all three special properties of functions, which:

  • Parse tree containing body: body() .
  • Formal parameters and their default values ​​(which the trees themselves process): formals() .
  • Environment (which is used to implement closures): environment() .
+9
source

Assign it to another variable if you want to reuse i :

 default_value = i f = function(x, j = default_value) x * j 
 i = 4 f(4) # 12 

Of course, you should not let this variable just lie - it is as bad as the source code. You can do this "private" for the function, though by defining both together in the local environment:

 f = local({ default_value = i function(x, j = default_value) x * j }) 
+5
source

All Articles