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! :)
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?
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"
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)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With