首页 > 解决方案 > 覆盖多个参数,更快的方法

问题描述

假设我有两个向量

 a <- c(1,2,3,4,5)
 b <- c(6,7,8,9,10)

和一个函数

calc <- function(x,y){x + y)

我想将此函数应用于 中a的每个值的第一个值b。假设在我的情况下,只允许来自和作为输入calc的单个值,所以不会工作,因为长度(b)不是 1(给我一个错误)。ablapply(a,calc,b)

mapply没有给我想要的解决方案,它只将函数应用于配对值,即1+6,2+7等。

所以我构建了一个函数,它给了我想要的解决方案

myfunc <- function(z){lapply(a,calc,z)}

并将其应用于 b

solution <- lapply(b,myfunc)

我们在这里看到与lapply(a,calc,b)嵌套或嵌套的区别lapply(a,lapply,calc,b)在于它为我提供了自己列表中的所有值。这就是我想要的,或者至少它是一个给我正确结果且没有错误的函数。

现在,有没有更快/更简单的方法,因为我只是在这里做了一点实验。而且我的功能比它需要 10 分钟大得多calc,但也许我必须缩小我原来的功能,这里不会有更快的方法......

编辑:

在我的功能中有这样的东西,

calc <- function(x,y){
# ...
number <- x
example <- head(number,n=y)
# ...
}

其中向量作为 y 的输入不再起作用。lapply(a,lapply,calc,b)或我得到lapply(a,calc,b)一个错误,

Error in head.default(number, n = y) : length(n) == 1L is not TRUE 

标签: rapplylapplymapply

解决方案


正如弗洛里安所说,outer()可能是一种选择。

outer(a, b, calc)
#      [,1] [,2] [,3] [,4] [,5]
# [1,]    7    8    9   10   11
# [2,]    8    9   10   11   12
# [3,]    9   10   11   12   13
# [4,]   10   11   12   13   14
# [5,]   11   12   13   14   15

但正如 MichaelChirico 所提到的,使用未矢量化的函数将无法正常工作。在这种情况下,必须一起破解其他东西。这些可能会也可能不会比您当前的解决方案更快。

所有组合(因此两者calc(1, 6)calc(6, 1)执行,类似于outer()

计算次数:n 2

eg <- expand.grid(a, b)

m1 <- mapply(calc, eg[,1], eg[, 2])
matrix(m1, 5)
#      [,1] [,2] [,3] [,4] [,5]
# [1,]    7    8    9   10   11
# [2,]    8    9   10   11   12
# [3,]    9   10   11   12   13
# [4,]   10   11   12   13   14
# [5,]   11   12   13   14   15

只有独特的组合(所以假设你的功能是对称的)

计算次数:(n 2 - n) / 2

cn <- t(combn(1:length(a), 2))

m2 <- mapply(calc, a[cn[, 1]], b[cn[, 2]])
mat <- matrix(, length(a), length(a))
mat[upper.tri(mat)] <- m2
mat
#      [,1] [,2] [,3] [,4] [,5]
# [1,]   NA    8    9   10   11
# [2,]   NA   NA   10   11   12
# [3,]   NA   NA   NA   12   13
# [4,]   NA   NA   NA   NA   14
# [5,]   NA   NA   NA   NA   NA

第二个忽略对角线,但添加这些值很容易,因为这就是 OPmapply()调用返回的内容。

diag(mat) <- mapply(calc, a, b)
mat
#      [,1] [,2] [,3] [,4] [,5]
# [1,]    7    8    9   10   11
# [2,]   NA    9   10   11   12
# [3,]   NA   NA   11   12   13
# [4,]   NA   NA   NA   13   14
# [5,]   NA   NA   NA   NA   15

推荐阅读