开发者

Is there some 'cross apply' function in R?

开发者 https://www.devze.com 2023-04-10 13:02 出处:网络
Is there some fu开发者_如何学Pythonnction in R of the form like: crossApply(v1, v2, func) that has the same functionality as:

Is there some fu开发者_如何学Pythonnction in R of the form like:

crossApply(v1, v2, func)

that has the same functionality as:

ret = c()
i = 1
for (e1 in v1) {
  for (e2 in v2) {
    ret[i] <- func(e1,e2)
    i <- i + 1
  }
}
return(ret)

Thanks in advance.


I think you may be looking for outer which isn't exactly what your code does, but it's close. Specifically, outer will return the matrix (i.e. the outer product) or each combination of the elements of its first two arguments.

You'd probably want to store the result and then extract the lower triangle as a vector. Something like this maybe:

rs <- outer(1:4,-(5:7),"+")
rs[lower.tri(rs,diag = TRUE)]
[1] -4 -3 -2 -1 -4 -3 -2 -4 -3


An example

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

And you then have

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

or if you want exactly what your for loops would produce

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


It's fairly easy to do with do.call and expand.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
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号