Это идеальная работа для sweep()
.
set.seed(47)
dat <- matrix(rnorm(22239 * 200), ncol = 200)
rmeds <- apply(dat, 1, median) ## row medians
rmads <- apply(dat, 1, mad) ## row mads
dat2 <- sweep(dat, 1, rmeds, "-") ## sweep out the medians
dat2 <- sweep(dat2, 1, rmads, "/") ## sweep out the mads
. Это можно немного ускорить, если не использовать mad()
, так как он снова вычисляет медианы:
rmeds <- apply(dat, 1, median) ## row medians
dat3 <- sweep(dat, 1, rmeds, "-") ## sweep out the medians
rmads <- 1.4826 * apply(abs(dat3), 1, median) ## row mads
dat3 <- sweep(dat3, 1, rmads, "/") ## sweep out the mads
R> all.equal(dat2, dat3)
[1] TRUE
Обратите внимание, что R * mad()
умножается на константу 1,4826 для достижения асимптотически нормальной согласованности, следовательно, дополнительный бит во втором примере.
Некоторые временные параметры в моей системе:
## first version
user system elapsed
6.215 0.183 6.412
## second version
user system elapsed
4.365 0.167 4.535
Для @Ответ Ника, который я получаю:
## @Nick's Version
user system elapsed
5.900 0.032 5.955
, что последовательно быстрее, чем моя первая версия, но немного медленнее, чем вторая версия, опять же, потому что медианы вычисляются дважды.