在mapply中将函数名称作为参数传递?

4
我想在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 有没有什么办法可以解决这个问题?
2个回答

5

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是一个特定的对象,即一个函数。我在哪里可以找到关于函数方面的这种行为的解释?例如,我可以有一个函数列表,但是我不允许(现在我明白了)拥有一个带有函数列的数据框。 - Robert McDonald
1
这是R要求原子向量或“原始”类型的地方与您可以拥有更一般列表的地方之间的区别。从技术上讲,您可以在data.frame中使用函数,但它们必须在“列表列”中。例如,您可以执行x <- data.frame(a=1:2); x$b <- list(mean, sum)。但这会使诸如write.table之类的事情混乱,因为您无法将函数写入文本中。函数是极少数不像向量或列表那样隐式行为的东西,需要进行一些包装。 - MrFlick

0

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接