Я всегда воспринимал это как факт, что colMeans()
или colSums()
- это самый быстрый способ выполнения соответствующих операций.Как правило, я имею в виду базовые, а не dplyr
или data.table
реализации.
Обучая некоторых новых пользователей, я сам проверил эталонный тест, чтобы доказать это.Сейчас я постоянно вижу противоречивые выводы.
n = 10000
p = 100
test_matrix <- matrix(runif(n*p), n, p)
test_df <- as.data.frame(test_matrix)
benchmark <- microbenchmark(
colMeans(test_df),
colMeans(as.matrix(test_df)),
sapply(test_df, mean),
vapply(test_df, mean, 0),
colMeans(test_matrix),
apply(test_matrix, 2, mean)
)
Unit: microseconds
expr min lq mean median uq max neval
colMeans(test_df) 3099.941 3165.8290 3733.024 3241.345 3617.039 11387.090 100
colMeans(as.matrix(test_df)) 3091.634 3158.0880 3553.537 3241.345 3548.507 8531.067 100
sapply(test_df, mean) 2209.227 2267.3750 2723.176 2338.172 2602.289 10384.612 100
vapply(test_df, mean, 0) 2180.153 2228.2945 2611.982 2270.584 2514.123 7421.356 100
colMeans(test_matrix) 904.307 915.0685 1020.085 939.422 1002.667 2985.911 100
apply(test_matrix, 2, mean) 9748.388 9957.0020 12098.328 10330.429 12582.889 34873.009 100
Для матрицы colMeans()
факелы apply()
Это ожидаемо.Но для фрейма данных sapply()
и vapply()
обычно бьют colMeans()
, даже когда я увеличиваю n
и p
.Есть ли причина, по которой я хотел бы использовать colMeans()
для фрейма данных?Похоже, что разница возникает из-за издержек, связанных с преобразованием кадра данных обратно в матрицу.
![microbenchmark of means](https://i.stack.imgur.com/SbE9M.png)
Основной вопрос
Другими словами, есть ли причина, по которой (более формальная версия) следующее было бы нецелесообразным?Тесты показывают, что в основном не выпадают.Очевидно, это делает предположение о вводе, который вводит пользователь, но здесь дело не в этом.
colMeans2 <- function(myobject) {
if (typeof(myobject) == "double") {
colMeans(myobject)
} else if (typeof(myobject) == "list") {
vapply(myobject, mean, 0)
} else {
stop("what is this")
}
}
Для справки
Вот еще два поста, которые яможно найти как несколько связанные, так и упоминания о том, как colMeans()
должно быть быстрее.
Функции группировки (tapply, by, aggregate) и * apply family
Почему функции `colMeans ()` и `rowMeans ()` работают быстрее, чем использование средней функции с `lapply ()`?