Сравнение решений, предложенных @Ronak Shah и @ThomasIsCoding с microbenchmark
для большего matrix
, дает следующий результат:
# Generate matrix
set.seed(1)
ex <- matrix(data = round(runif(100000), 1), nrow = 1000, ncol = 100)
ex
colMeans(ex)
# for-loop solution
ex2 <- ex
for(i in 1:ncol(ex2)){
ex2[, i][ex2[, i] < colMeans(ex2)[i]] <- NA
}
ex2
# Solution with sweep
ex3 <- ex
ex3[sweep(ex3, 2, colMeans(ex3), "<")] <- NA
ex3
# Solution with replace
ex4 <- ex
ex4 <- replace(ex4, ex4 < t(replicate(nrow(ex4), colMeans(ex4))), NA)
ex4
# Transposing solution
ex5 <- ex
ex5[t(t(ex5) < colMeans(ex5))] <- NA
ex5
# Apply solution
ex6 <- ex
apply(ex6, 2, function(x) replace(x, x < mean(x), NA))
ex6
# Identical
all.equal(ex2, ex3, ex4, ex5, ex6)
# Microbenchmark
library(microbenchmark)
comp <- microbenchmark(
for_loop = {
ex2 <- ex
for(i in 1:ncol(ex2)){
ex2[, i][ex2[, i] < colMeans(ex2)[i]] <- NA
}},
sweep = {
ex3 <- ex
ex3[sweep(ex3, 2, colMeans(ex3), "<")] <- NA
},
replace = {
ex4 <- ex
ex4 <- replace(ex4, ex4 < t(replicate(nrow(ex4), colMeans(ex4))), NA)
},
transpose = {
ex5 <- ex
ex5[t(t(ex5) < colMeans(ex5))] <- NA
},
apply = {
ex6 <- ex
apply(ex6, 2, function(x) replace(x, x < mean(x), NA))
}
)
library(ggplot2)
autoplot(comp)
Они дают идентичные результаты, но sweep
подход кажется самым быстрым.