@ У Джошуа Ульриха (и Дэйсона) отличный ответ. И делать это напрямую без функции y
- лучшее решение. Но если вам действительно нужно для вызова функции, вы можете сделать это быстрее, используя vapply
. Он создает вектор без измерений (как sapply
, но быстрее), но затем вы можете добавить их обратно, используя structure
:
# Your function (optimized)
y = function(x) if (x %% 3) x+1 else NA
m <- matrix(1:1e6,1e3)
system.time( r1 <- apply(m,1:2,y) ) # 4.89 secs
system.time( r2 <- structure(sapply(m, y), dim=dim(m)) ) # 2.89 secs
system.time( r3 <- structure(vapply(m, y, numeric(1)), dim=dim(m)) ) # 1.66 secs
identical(r1, r2) # TRUE
identical(r1, r3) # TRUE
... Как вы видите, подход vapply
примерно в 3 раза быстрее, чем apply
... И причина vapply
быстрее, чем sapply
в том, что sapply
должен анализировать результат, чтобы вычислить что это может быть упрощено до числового вектора. С vapply
вы указали тип результата (numeric(1)
), поэтому не нужно угадывать ...
ОБНОВЛЕНИЕ Я нашел другой (более короткий) способ сохранения структуры матрицы:
m <- matrix(1:10, nrow=2)
m[] <- vapply(m, y, numeric(1))
Вы просто присваиваете новые значения объекту, используя m[] <-
. Затем все остальные атрибуты сохраняются (например, dim
, dimnames
, class
и т. Д.).