[R] filling an array, vectorized
Robin Hankin
r.hankin at noc.soton.ac.uk
Fri Nov 17 13:02:40 CET 2006
Hello again everyone.
I've further added to Martin and Gabor's suggestion an ellipsis to
pass additional arguments to f(). Cut-n-paste below.
BUT.....do.index() comes with a Warning: function arow() of the magic
package is much much much faster; use it if at all possible:
a <- array(0, c(2, 3, 4, 2, 3, 3, 2, 3, 2, 3))
f1 <- function(i) { arow(a, i)}
f2 <- function(x) { sum(x) }
"++" <- function(x, ...) if (nargs() == 1) x else x +
Recall(...)
> system.time(ignore1 <- do.call("++", sapply(1:4, f1,
simplify = FALSE)))
[1] 0.041 0.013 0.054 0.000 0.000
> system.time(ignore1 <- do.call("++", sapply(1:4, f1,
simplify = FALSE)))
[1] 0.029 0.009 0.040 0.000 0.000
> system.time(ignore1 <- do.call("++", sapply(1:4, f1,
simplify = FALSE)))
[1] 0.028 0.009 0.038 0.000 0.000
> system.time(ignore2 <- do.index(a, f2))
[1] 0.387 0.028 0.440 0.000 0.000
> system.time(ignore2 <- do.index(a, f2))
[1] 0.380 0.025 0.406 0.000 0.000
> system.time(ignore2 <- do.index(a, f2))
[1] 0.376 0.029 0.422 0.000 0.000
>
do.index <-
function (a, f, ...)
{
jj <- function(i) {
seq_len(dim(a)[i])
}
index <- as.matrix(expand.grid(lapply(seq_len(length(dim(a))),
jj), KEEP.OUT.ATTRS = FALSE))
a[index] <- apply(index, 1, f, ...)
return(a)
}
arow <-
function (a, i)
{
p <- 1:prod(dim(a))
n <- length(dim(a))
d <- dim(a)[i]
permute <- c(i, (1:n)[-i])
a <- aperm(a, permute)
a[] <- p
permute[permute] <- 1:n
return(force.integer(aperm(process(a, d), permute)))
}
--
Robin Hankin
Uncertainty Analyst
National Oceanography Centre, Southampton
European Way, Southampton SO14 3ZH, UK
tel 023-8059-7743
More information about the R-help
mailing list