【问题标题】:Pass function name as argument in mapply?在mapply中将函数名作为参数传递?
【发布时间】:2019-10-25 15:08:56
【问题描述】:

我想在 mapply 中将函数名作为参数传递:

f2 <- function(a, b) a + b^2
f <- function(a, b, func) func(a, b)
f(1, 3, f2)  ## returns 10
mapply(f2,  1:2,  3)  ## returns [1] 10 11
mapply(function(a, b) f(a, b, f2), 1:2,  3) ## returns [1] 10 11
mapply(f,  1:2,  3,  f2)  ## fails

最后的mapply调用产生错误

Error in dots[[3L]][[1L]] : object of type 'closure' is not subsettable

有什么办法吗?

【问题讨论】:

    标签: r mapply


    【解决方案1】:

    mapply 假设您要遍历在第一个函数之后传递的所有向量。但是您希望每次迭代都使用相同的 f2 值。您可以使用MoreArgs= 参数来做到这一点

    mapply(f,  1:2,  3,  MoreArgs=list(func=f2))
    

    你对 3 没有同样的问题,因为 R 将执行向量循环以将 3 扩展为 c(3,3) 以匹配与 c(1,2) 相同的长度。 R 中的函数没有相同的隐式回收行为。但是如果你想让值始终保持不变,最好把它放在MoreArgs参数中

    【讨论】:

    • 完美! R 显然知道 f2 是一个特定的对象,即一个函数。我在哪里可以找到这种行为 wrt 函数的解释?例如,我可以有一个函数列表,但我不允许(我现在理解)有一个带有函数列的数据框。
    • 这是 R 想要的原子向量或“原始”类型与您可以拥有更通用列表的位置之间的区别。从技术上讲,您可以在 data.frame 中具有某种功能,但它们必须位于“列表列”中。就像你可以做x &lt;- data.frame(a=1:2); x$b &lt;- list(mean, sum)。但这会弄乱write.table 之类的东西,因为您无法将函数写入文本。函数是为数不多的在没有包装的情况下不会像向量或列表那样隐式表现的东西之一。
    【解决方案2】:

    1) 将函数包装在一个列表中:

    mapply(f,  1:2,  3,  list(f2))
    ## [1] 10 11
    

    2) 通常具有函数参数的函数使用match.fun,以便可以传递函数或包含其名称的字符串。例如,mapply 本身就是这样做的,因此上面的代码行同样可以写成:mapply("f", 1:2, 3, list(f2))。如果f是这样写的,那么我们可以简单地将f2的名称指定为字符串,即"f2"

    f <- function(a, b, func) {
      func <- match.fun(func)
      func(a, b)
    }
    
    mapply(f,  1:2,  3,  "f2")
    ## [1] 10 11
    

    【讨论】:

      猜你喜欢
      • 2016-02-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-04
      • 1970-01-01
      • 2013-12-08
      • 1970-01-01
      • 2019-11-23
      相关资源
      最近更新 更多