【问题标题】:how to pass arguments as a list in R function如何在R函数中将参数作为列表传递
【发布时间】:2014-12-03 20:53:20
【问题描述】:

我的函数有很多参数。所以我想创建一个参数列表并将它们传递给函数。

?mean函数为例:

mean(x, trim = 0, na.rm = FALSE, ...)

假设我想计算1:10 的平均值,分配给变量x,但将其他参数作为列表传递:

gm <- list (trim = 0, na.rm = FALSE)

mean(1:10, gm)
#R> Error in mean.default(1:10, gm) : 'trim' must be numeric of length one

我尝试使用do.call,但也不起作用。

do.call(mean,list(1:10, gm))
#R> Error in mean.default(1:10, list(trim = 0, na.rm = FALSE)) : 
#R>   'trim' must be numeric of length one

【问题讨论】:

  • 完整,do.call(mean,c(list(1:10), gm))。注意list(1:10, gm)c(list(1:10), gm) 返回的对象在形状(长度)上的差异。

标签: r function arguments


【解决方案1】:

这也可以通过 rlang::exec 和 unquote-splice 运算符 !!! 来完成。

rlang::exec(mean, 1:10, !!!gm)
#> [1] 5.5

【讨论】:

    【解决方案2】:

    您可以设置默认参数,如果您重复执行此操作作为使用do.call 的替代方法,这可能会很方便。您可以使用formals 执行此操作,如下所示:

    f <- mean.default
    formals(f)[match(names(formals(f)), names(gm))] <- gm
    
    f(1:10)
    #R> [1] 5.5
    

    这有一些需要注意的极端情况。一方面,我使用mean.default 而不是mean,否则我必须将gm 的参数放在... 之前。

    do.call 的另一种替代方法是创建一个call 并使用eval

    cl <- as.call(c(list(quote(mean), x = 1:10), gm))
    cl
    #R> mean(x = 1:10, trim = 0, na.rm = FALSE)
    
    eval(cl)
    #R> [1] 5.5
    

    【讨论】:

      【解决方案3】:

      如评论中所述,您的 gmdo.call 的形状错误,它将您的选项列表解释为 trim 参数。

      要使参数的形状正确,请使用c

      gm <- list(trim=0, na.rm=FALSE)
      do.call(mean, c(list(1:10), gm))
      [1] 5.5
      

      【讨论】: