我试图通过使用apply
将用户定义的函数应用于矩阵来避免使用循环。我遇到的问题是我的函数使用了其他参数,它们对于矩阵的每一列都不同。以下是一个玩具示例。
说我有以下功能:
foo <- function(x, a, b, c) return( (a*x + b)^c )
我希望将其应用于矩阵bar
,为每列使用不同的a
,b
和c
值。
bar <- matrix(1:15, ncol = 3)
a <- 4:6
b <- 3:1
c <- 1:3
在这种情况下,对于bar
的第一列,然后是a=4
,b=3
和c=1
。我试过这个,
apply(bar, 2, foo, a=a, b=b, c=c)
但这显然是不正确的,因为每个列在重新包装回第一个参数之前依次使用所有参数。有什么建议吗?
答案 0 :(得分:12)
我们可以split
&#39;&#39;&#39;通过&#39;列&#39; (col(bar)
)和mapply
我们可以申请&#39; foo&#39;对应的&#39; a&#39;,&#39;&#39;&#39; c&#39;值为&#39; bar&#39;
mapply(foo, split(bar, col(bar)), a, b, c)
或者不使用apply
ind <- col(bar)
(a[ind]*bar +b[ind])^c[ind]
答案 1 :(得分:9)
我根本不明白你为什么要打扰一个功能:
> a <- matrix(4:6,nrow = 5,ncol = 3,byrow = TRUE)
> b <- matrix(3:1,nrow = 5,ncol = 3,byrow = TRUE)
> c <- matrix(1:3,nrow = 5,ncol = 3,byrow = TRUE)
> (a*bar + b)^c
[,1] [,2] [,3]
[1,] 7 1024 300763
[2,] 11 1369 389017
[3,] 15 1764 493039
[4,] 19 2209 614125
[5,] 23 2704 753571
答案 2 :(得分:3)
我猜你可以转置你的矩阵并使用矢量化:
t(foo(t(bar),a,b,c))
这适用于每个矢量化foo
。
答案 3 :(得分:2)
您可以将参数放入矢量中:
newbar <- rbind(a,b,c,bar)
newfoo <- function(z){x <- z[-(1:3)]; (z[1]*x+z[2])^z[3]}
apply(newbar,2,newfoo)
给出了
[,1] [,2] [,3]
7 1024 300763
11 1369 389017
15 1764 493039
19 2209 614125
23 2704 753571
答案 4 :(得分:2)
您可以使用sweep
;通常这是从每列中减去平均值,但是您可以传入索引来获得跨a,b和c的并行索引:
> sweep(bar, 2, seq_along(a), function(x,i) foo(x, a[i], b[i], c[i]), FALSE)
[,1] [,2] [,3]
[1,] 7 1024 300763
[2,] 11 1369 389017
[3,] 15 1764 493039
[4,] 19 2209 614125
[5,] 23 2704 753571