【问题标题】:Create new functions using a list of functions and list of function parameters to Be Passed使用要传递的函数列表和函数参数列表创建新函数
【发布时间】:2015-05-08 19:19:13
【问题描述】:

我正在尝试从函数列表和要传递给这些函数的参数列表中创建新函数,但到目前为止我还不能这样做。请看下面的例子。

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]]))
}

目标是为任意函数和参数动态地执行此操作。

【问题讨论】:

    标签: r


    【解决方案1】:

    好吧,force() 在 for 循环中不起作用,因为 for 循环不会创建新环境。基于我的previous question,我创建了一个capture() 函数

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

    这允许

    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)
    }
    

    我们为函数创建一个本地私有环境来存储它们的默认参数值。

    这给了

    fnew(2)
    # [1] 3
    znew(2)
    # [1] 30
    

    【讨论】:

    • 谢谢@Frank。我在测试中搞砸了。我已经更新了解决方案。
    【解决方案2】:

    这个怎么样:

    for(x in names(fun_list)) {
      formals(fun_list[[x]])$params <- params_list[[x]]
      assign(paste0(x, "new"), fun_list[[x]])
    }
    

    【讨论】:

    • 多么简单的解决方案。你太棒了。
    • 这确实改变了原始fun_list 列表中的功能,这可能是可取的,也可能不是。如果你愿意,你可以在改变正式之前复制一份。
    【解决方案3】:

    这在精神上是相似的:

    ps  <- list(fp=1,zp=c(3,5))
    f0s <- substitute(list(f=function(x)x+fp,z=function(a)a*zp1*zp2),as.list(unlist(ps))) 
    f0s # list(f = function(x) x + 1, z = function(a) a * 3 * 5)
    
    fs  <- eval(f0s)
    fs$f(1) # 2
    

    要完成 OP 中描述的花哨的事情,您可能不得不与formals 混淆。

    【讨论】:

      猜你喜欢
      • 2019-11-28
      • 2023-03-12
      • 1970-01-01
      • 2021-05-16
      • 2012-04-03
      • 2018-03-13
      • 1970-01-01
      • 2013-09-15
      • 1970-01-01
      相关资源
      最近更新 更多