Using "apply" to apply a function to a matrix where the parameters are columns

I am trying to avoid using loops using apply to apply a user-defined function to the matrix. The problem is that there are additional parameters that my function uses, and they differ for each column of the matrix. Below is an example of toys.

Let's say I have the following function:

 foo <- function(x, a, b, c) return( (a*x + b)^c ) 

and I want to apply it to the bar matrix using different values ​​of a , b and c for each column.

 bar <- matrix(1:15, ncol = 3) a <- 4:6 b <- 3:1 c <- 1:3 

In this case, for the first column bar , then a=4 , b=3 and c=1 . I tried this

 apply(bar, 2, foo, a=a, b=b, c=c) 

but this is clearly not true, since each column uses all the parameters sequentially before returning to the first parameter again. Any suggestions?

+7
r apply
source share
5 answers

We could split "bar" into a "column" ( col(bar) ) and mapply we can apply "foo" to the corresponding values ​​of "a", "b", "c" for each column of 'bar'

 mapply(foo, split(bar, col(bar)), a, b, c) 

Or without using apply

 ind <- col(bar) (a[ind]*bar +b[ind])^c[ind] 
+12
source share

I don’t understand why you are worried about the function at all:

 > 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 
+9
source share

I assume that you can simply transpose your matrix and use the vector:

 t(foo(t(bar),a,b,c)) 

This should work for every vector foo .

+3
source share

You can put your parameters in a vector:

 newbar <- rbind(a,b,c,bar) newfoo <- function(z){x <- z[-(1:3)]; (z[1]*x+z[2])^z[3]} apply(newbar,2,newfoo) 

which gives

 [,1] [,2] [,3] 7 1024 300763 11 1369 389017 15 1764 493039 19 2209 614125 23 2704 753571 
+2
source share

You can use sweep ; this is usually for subtracting the average from each column, but instead you can go to the index to get parallel indexing through a, b and 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 
+2
source share

All Articles