Если ваша функция медленная и время масштабируется в зависимости от размера ее ввода, вы можете использовать combn
:
X <- 1:50
Y <- 1:50
#a slow function
myfun <- function(x, y) {
res <- x * NA
for (i in seq_along(x)) {
Sys.sleep(0.01)
res[i] <- x[i] * y[i]
}
res
}
system.time(M <- outer(X, Y, FUN = myfun))
#user system elapsed
#0.00 0.00 26.41
system.time({
inds <- combn(seq_len(length(X)), 2)
M1 <- matrix(ncol = length(X), nrow = length(Y))
M1[lower.tri(M1)] <- myfun(X[inds[1,]], Y[inds[2,]])
M1[upper.tri(M1)] <- t(M1)[upper.tri(M1)]
diag(M1) <- myfun(X, Y)
})
#user system elapsed
#0.00 0.00 13.41
all.equal(M, M1)
#[1] TRUE
Однако, возможно, лучшее решение - реализовать это в C ++ через Rcpp.