Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Efficiently create a matrix from function values

Tags:

function

r

matrix

What would experienced R developers consider the most efficient (yet still readable) way to construct a matrix with a given number of rows and columns from a given function, such that e.g. A_ij = someFun(i,j) with 1 <= i <= rows, 1 <= j <= cols?

Since I couldn't find something in the documentation I came up with

initMatrix <- function(rows, cols, fn) {
    A <- matrix(nrow=rows, ncol=cols)
    for (i in 1:rows)
        for (j in 1:cols)
            A[i,j] <- fn(i,j)
    return(A)
}

which seems silly and slow to me. Any improvements (particularly one-liners) welcome! :)

like image 927
fotNelton Avatar asked Oct 28 '11 13:10

fotNelton


3 Answers

I think you're looking for outer(seq(rows),seq(cols),fn) (or as suggested below, outer(seq_len(rows),seq_len(cols),fn): would need some examples to see how much difference that made).

You can gain a lot in readability (at least if you don't have to go look up ?outer to find out what's going on) this way, but I don't actually think you save much time. Something cleverer and more efficient might be possible if your fn is vectorized to begin with: is it?

like image 138
Ben Bolker Avatar answered Nov 15 '22 17:11

Ben Bolker


have a look at outer:

> outer (LETTERS [1:3], letters [4:7], paste)
     [,1]  [,2]  [,3]  [,4] 
[1,] "A d" "A e" "A f" "A g"
[2,] "B d" "B e" "B f" "B g"
[3,] "C d" "C e" "C f" "C g"
like image 31
cbeleites unhappy with SX Avatar answered Nov 15 '22 16:11

cbeleites unhappy with SX


If you just write any function, you might get errors calling 'outer', so Vectorize it first.

fn <- function(i,j){ ... }

A <- outer(1:rows, 1:cols, Vectorize(fn))

Example where it won't work without Vectorizing:

fn <- function(i,j){
  return(prop.test(c(tables[i,1], tables[j,1]), c(sum(tables[i,]), sum(tables[j,])))$p.value)
  }
like image 33
Spine Feast Avatar answered Nov 15 '22 16:11

Spine Feast