R中是否有“cross apply”函数?

4
在R中是否有类似以下形式的函数:
crossApply(v1, v2, func)

具有与以下功能相同的功能:
ret = c()
i = 1
for (e1 in v1) {
  for (e2 in v2) {
    ret[i] <- func(e1,e2)
    i <- i + 1
  }
}
return(ret)

谢谢您的提前帮助。
3个回答

6
我觉得你可能在寻找的是outer函数,虽然它与你的代码并不完全相同,但很接近。具体来说,outer会返回其前两个参数所有组合的矩阵(即外积)。
你可能需要将结果存储下来,然后提取下三角形成向量。做法可能像这样:
rs <- outer(1:4,-(5:7),"+")
rs[lower.tri(rs,diag = TRUE)]
[1] -4 -3 -2 -1 -4 -3 -2 -4 -3

谢谢!我该如何定义一个自定义函数以在外部使用?您能给个例子吗?每次尝试时都会出现错误,而我的错误消息是中文的,所以我想发布它们也没有多少帮助。 - Derrick Zhang
1
@SpiritZhang: emulatesum<-function(x,y) return(x + y) 是一个函数,然后 rs <- outer(1:4,-(5:7),"emulatesum")。顺便说一句:我强烈建议在 R 中使用英语,特别是对于错误信息:当你用英语时,谷歌搜索会更容易... - Nick Sabbe
@NickSabbe:谢谢Nick!我在安装R时没有太注意语言问题。既然我在中国,所以R默认选择了中文作为语言。 - Derrick Zhang

1

一个例子

func <- function(x,y) {sqrt(x^2+y^2)}
v1 <- c(1,3,5)
v2 <- c(0,-4,-12)
ret <- outer(v1,v2,"func")

然后你就有了

> ret
     [,1]     [,2]     [,3]
[1,]    1 4.123106 12.04159
[2,]    3 5.000000 12.36932
[3,]    5 6.403124 13.00000

或者如果你想要得到与你的for循环完全相同的结果

> as.vector(t(ret))
[1]  1.000000  4.123106 12.041595  3.000000  5.000000 12.369317  5.000000
[8]  6.403124 13.000000

0

使用do.callexpand.grid非常容易实现:

x <- seq(0,10, length.out=10)
> y <- seq(-1,1, length.out=5)
> d1 <- expand.grid(x=x, y=y)  
> do.call("*", d1)
 [1]   0.0000000  -1.1111111  -2.2222222  -3.3333333  -4.4444444
 [6]  -5.5555556  -6.6666667  -7.7777778  -8.8888889 -10.0000000
[11]   0.0000000  -0.5555556  -1.1111111  -1.6666667  -2.2222222
[16]  -2.7777778  -3.3333333  -3.8888889  -4.4444444  -5.0000000
[21]   0.0000000   0.0000000   0.0000000   0.0000000   0.0000000
[26]   0.0000000   0.0000000   0.0000000   0.0000000   0.0000000
[31]   0.0000000   0.5555556   1.1111111   1.6666667   2.2222222
[36]   2.7777778   3.3333333   3.8888889   4.4444444   5.0000000
[41]   0.0000000   1.1111111   2.2222222   3.3333333   4.4444444
[46]   5.5555556   6.6666667   7.7777778   8.8888889  10.0000000

很好,但请注意只有向量化函数才能在这种情况下与do.call一起使用。例如,do.call(mean, d1)会失败。 - kohske
所以也许应该是 do.call("mapply", c(fun, d1)) - kohske
有趣的想法。它似乎与 do.call(expand.grid(.)) 所做的类似于 Vectorize 所做的与 sapply - IRTFM

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