Кажется, использование цикла for с set()
быстрее (лучше?). Вот эталонный тест:
Редактировать : добавлено предложение Фрэнка, и оно, кажется, превосходит все, что мыдо сих пор пробовал:
Изменить 2 : изменено times = 1
для более справедливого сравнения - оригинальное решение кажется довольно хорошим сейчас.
Редактировать 3 :Добавлено предложение Хью, и, похоже, это улучшение:
dt <- as.data.table(replicate(c, rnorm(r)))
dt2 <- copy(dt)
dt3 <- copy(dt)
dt4 <- copy(dt)
microbenchmark::microbenchmark(
set = {for (col in names(dt)) {set(dt, j = col, value = sort(dt[[col]]))}},
original = as.data.table(sapply(dt2,sort)),
matrixapply = apply(as.matrix(dt2), 2, sort),
frank = dt3[, names(dt) := lapply(.SD, sort)],
hugh = for (j in seq_along(dt4)) { v <- .subset2(dt4, j); set(dt4, j = j, value = v[order(v)]) },
times = 1
)
Результаты
Unit: seconds
expr min lq mean median uq max neval
set 6.223533 6.223533 6.223533 6.223533 6.223533 6.223533 1
original 5.598481 5.598481 5.598481 5.598481 5.598481 5.598481 1
matrixapply 6.039590 6.039590 6.039590 6.039590 6.039590 6.039590 1
frank 5.255841 5.255841 5.255841 5.255841 5.255841 5.255841 1
hugh 5.084420 5.084420 5.084420 5.084420 5.084420 5.084420 1