使用 "apply" 将函数应用于参数特定于列的矩阵
Using "apply" to apply a function to a matrix where parameters are column-specific
我试图通过使用 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)
但这显然是不正确的,因为每一列在再次回到第一个参数之前按顺序使用所有参数。有什么建议吗?
我们可以通过 'column' (col(bar)
) split
'bar' 并且使用 mapply
我们可以将 'foo' 应用于相应的 'a'、'b'、'c' 值到 'bar'
的每一列
mapply(foo, split(bar, col(bar)), a, b, c)
或不使用 apply
ind <- col(bar)
(a[ind]*bar +b[ind])^c[ind]
您可以将参数放入向量中:
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
可以使用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
我完全不明白你为什么要为函数烦恼:
> 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
我想您可以转置矩阵并使用矢量化:
t(foo(t(bar),a,b,c))
这应该适用于每个矢量化 foo
。
我试图通过使用 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)
但这显然是不正确的,因为每一列在再次回到第一个参数之前按顺序使用所有参数。有什么建议吗?
我们可以通过 'column' (col(bar)
) split
'bar' 并且使用 mapply
我们可以将 'foo' 应用于相应的 'a'、'b'、'c' 值到 'bar'
mapply(foo, split(bar, col(bar)), a, b, c)
或不使用 apply
ind <- col(bar)
(a[ind]*bar +b[ind])^c[ind]
您可以将参数放入向量中:
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
可以使用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
我完全不明白你为什么要为函数烦恼:
> 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
我想您可以转置矩阵并使用矢量化:
t(foo(t(bar),a,b,c))
这应该适用于每个矢量化 foo
。