Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create new functions using a list of functions and list of function parameters to Be Passed

Tags:

r

I am trying to create new functions from a list of function and a list of parameters to be passed to these functions, but am unable to do so so far. Please see the example below.

fun_list <- list(f = function(x, params) {x+params[1]}, 
          z = function(a, params) {a * params[1] * params[2]})
params_list <- list(f = 1, z = c(3, 5))

# goal is to create 2 new functions in global environment
#  fnew <- function(x) {x+1}
#  znew <- function(a) {a*3*5}

# I've tried
for(x in names(fun_list)){
  force(x)
  assign(paste0(x, "new"), function(...) fun_list[[x]] (...,  params = params_list[[x]]))
}

The goal is to do this dynamically for arbitrary functions and parameters.

like image 935
k13 Avatar asked Dec 25 '22 19:12

k13


2 Answers

Well, force() doesn't work in a for-loop because for loops do not create new environments. Based on a previous question of mine, I created a capture() function

capture <- function(...) {
    vars <- sapply(substitute(...()), deparse); 
    pf <- parent.frame(); 
    Map(assign, vars, mget(vars, envir=pf, inherits = TRUE), MoreArgs=list(envir=pf))
}

this allows

for(x in names(fun_list)) {
    f = local({ 
           capture(x); 
           p = params_list[[x]]; 
           f = fun_list[[x]]; 
           function(x) f(x, p)
    })
    assign(paste0(x, "new"), f)
}

where we create a local, private environment for the functions to store their default parameter values.

Which gives

fnew(2)
# [1] 3
znew(2)
# [1] 30
like image 163
MrFlick Avatar answered Feb 13 '23 03:02

MrFlick


How about this:

for(x in names(fun_list)) {
  formals(fun_list[[x]])$params <- params_list[[x]]
  assign(paste0(x, "new"), fun_list[[x]])
}
like image 35
B.Shankar Avatar answered Feb 13 '23 02:02

B.Shankar