通过 (...) 时避免参数重复 [英] Avoid argument duplication when passing through (...)

查看:15
本文介绍了通过 (...) 时避免参数重复的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑功能

f <- function(x, X) mean(c(x,X))

我如何自动(通过操作 f())更改 f() 的签名,以便它可以与 lapply()<一起使用/code>,即不返回以下明显错误?

How can I automatically (by manipulation of f()) change the signature of f() such that it can be used with lapply(), i.e., without returning the following obvious error?

lapply(X=list(1), FUN=f, X=1)
Error in lapply(X = list(1), FUN = f, X = 1) : 
  formal argument "X" matched by multiple actual arguments

到目前为止我使用的方法是从 f() 中删除所有参数,将它们分配到环境中,然后在该环境中评估 f().

The approach I used so far is to remove all arguments from f(), assign them into an environment, and evaluatef() in that environment.

integrateArgs <- function (f, args) 
{
    form <- formals(f)
    if (!is.null(form)) 
        for (i in seq_along(form)) assign(names(form)[i], form[[i]])
    if (!is.null(args)) 
        for (i in seq_along(args)) assign(names(args)[i], args[[i]])
    ff <- function() {
    }
    parent.env(environment(ff)) <- parent.env(environment(f))
    body(ff) <- body(f)
    if (any(names(form) == "...")) 
        formals(ff) <- form[names(form) == "..."]
    ff
}
fnew <- integrateArgs(f, list(x=1, X=4))
lapply(list(fnew), function(x) x())
[[1]]
[1] 2.5

但是,如果 f() 是来自另一个 R 包的调用编译代码的函数,则该方法会导致以下错误.

However, that approach leads to the following error if f() is a function from another R package that calls compiled code.

fnew2 <- integrateArgs(dnorm, list(x=1, mean=4))
lapply(list(fnew2), function(x) x())
Error in x() (from #1) : object 'C_dnorm' not found

有更好的解决方案吗?

推荐答案

正如 MrFlick 在评论中所建议的,一个解决方案是

As suggested in a comment by MrFlick, one solution is

library(purrr)
integrateArgs <- function(f, args){
    do.call(partial, c(list(f), args))
}
fnew2 <- integrateArgs(dnorm, list(x=1, mean=4))
lapply(list(fnew2), function(x) x())
[[1]]
[1] 0.004431848

以下类似的方法不需要包purrr:

The following similar approach does not require the package purrr:

integrateArgs <- function(f, args){
    do.call(function(f, ...) {
        eval(call("function", NULL,
                  substitute(f(...))), envir = environment(f))}, 
        c(f = list(f), args))
}
fnew2 <- integrateArgs(dnorm, list(x=1, mean=4))
lapply(list(fnew2), function(x) x())
[[1]]
[1] 0.004431848

现在 optimParallel 版本 0.7-4 中使用了类似的方法来使用 parallel::parLapply() 并行执行函数:https://cran.r-project.org/package=optimParallel

A similar approach is now used in optimParallel version 0.7-4 to execute functions in parallel using parallel::parLapply(): https://cran.r-project.org/package=optimParallel

这篇关于通过 (...) 时避免参数重复的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆