eold - 6 months ago 38

R Question

I am wondering if there is a built-in function in R which applies a function to each element of the matrix (of course, the function should be computed based on matrix indices). The equivalent would be something like this:

`matrix_apply <- function(m, f) {`

m2 <- m

for (r in seq(nrow(m2)))

for (c in seq(ncol(m2)))

m2[[r, c]] <- f(r, c)

return(m2)

}

If there is no such built-in function, what is the best way to initialize a matrix to contain values obtained by computing an arbitrary function which has matrix indices as parameters?

Answer

I suspect you want `outer`

:

```
> mat <- matrix(NA, nrow=5, ncol=3)
> outer(1:nrow(mat), 1:ncol(mat) , FUN="*")
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 2 4 6
[3,] 3 6 9
[4,] 4 8 12
[5,] 5 10 15
> outer(1:nrow(mat), 1:ncol(mat) , FUN=function(r,c) log(r+c) )
[,1] [,2] [,3]
[1,] 0.6931472 1.098612 1.386294
[2,] 1.0986123 1.386294 1.609438
[3,] 1.3862944 1.609438 1.791759
[4,] 1.6094379 1.791759 1.945910
[5,] 1.7917595 1.945910 2.079442
```

That yields a nice compact output. but it's possible that `mapply`

would be useful in other situations. It is helpful to think of `mapply`

as just another way to do the same operation that others on this page are using `Vectorize`

for. `mapply`

is more general because of the inability `Vectorize`

to use "primitive" functions.

```
data.frame(mrow=c(row(mat)), # straightens out the arguments
mcol=c(col(mat)),
m.f.res= mapply(function(r,c) log(r+c), row(mat), col(mat) ) )
# mrow mcol m.f.res
1 1 1 0.6931472
2 2 1 1.0986123
3 3 1 1.3862944
4 4 1 1.6094379
5 5 1 1.7917595
6 1 2 1.0986123
7 2 2 1.3862944
8 3 2 1.6094379
9 4 2 1.7917595
10 5 2 1.9459101
11 1 3 1.3862944
12 2 3 1.6094379
13 3 3 1.7917595
14 4 3 1.9459101
15 5 3 2.0794415
```

You probably didn't really mean to supply to the function what the row() and col() functions would have returned: This produces an array of 15 (somewhat redundant) 3 x 5 matrices:

```
> outer(row(mat), col(mat) , FUN=function(r,c) log(r+c) )
```