【问题标题】:mapply for all arguments' combinations [R]映射所有参数的组合 [R]
【发布时间】:2016-03-09 11:12:03
【问题描述】:

考虑这个接收 3 个参数的玩具函数:

toy <- function(x, y, z){
    paste(x, y, z)
}

对于每个参数,我有多个值(每个参数不一定有相同的数字),我想将 toy 函数应用于这些参数的不同组合。

所以我想,好吧,让我们使用apply函数mapply的多元版本。

mapply(FUN = toy, x = 1:2, y = c("#", "$"), z = c("a", "b"))

[1] "1 # a" "2 $ b"

但这并不是我想要的。事实上,根据帮助mapply“将 FUN 应用于每个 ... 参数的第一个元素、第二个元素、第三个元素等等。”。而我想要的是将 FUN 应用于所有参数的所有不同组合。

所以,而不是

[1] "1 # a" "2 $ b"

我想要的结果是:

[1] "1 # a" "1 # b" "1 $ a" "1 $ b" "2 # a" "2 # b" "2 $ a" "2 $ b"

那么,我的问题是这样做的聪明方法是什么?

当然,我可以事先准备好组合并安排mapply 的参数,以便它们包含-rowwise- 所有组合。但我只是认为这可能是一项相当常见的任务,并且可能已经有一个函数,在 apply-family 中,可以做到这一点。

【问题讨论】:

  • 你可以做do.call(paste, expand.grid(x = 1:2, y = c("#", "$"), z = c("a", "b")))也许

标签: r mapply


【解决方案1】:

您可以将do.callexpand.grid 结合起来使用无限量的输入,如下所示

toy <- function(...) do.call(paste, expand.grid(...))

那么,你可以这样做

x = 1:2 ; y = c("#", "$") ; z = c("a", "b")
toy(x, y, z)
# [1] "1 # a" "2 # a" "1 $ a" "2 $ a" "1 # b" "2 # b" "1 $ b" "2 $ b"

这适用于任何输入。你可以试试toy(x, y, z, y, y, y, z) 之类的东西,例如为了验证。

【讨论】:

  • 感谢expand.grid 准备组合。我只需要分两步完成。首先是args &lt;- expand.grid(x = 1:2, y = c("#", "$"), z = c("a", "b")),然后是mapply(FUN = toy, x = args$x, y = args$y, z = args$z),因为像mapply(FUN = toy, expand.grid(x = 1:2, y = c("#", "$"), z = c("a", "b"))) 这样直接这样做是行不通的(mapply 只会收到一个参数;data.frame)。我只是认为有一些内部功能可以解决问题。使用do.callpaste 是为了这个特殊的玩具功能。我的实际功能不同。
  • 好吧,虽然do.call 是矢量化的并且比mapply 更高效,但也许它并不总是可以扩展到更一般的情况。
猜你喜欢
  • 2021-09-28
  • 1970-01-01
  • 1970-01-01
  • 2016-07-23
  • 2016-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-31
相关资源
最近更新 更多