我一直认为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()
?看来,差异来自与将数据帧转换回矩阵相关的开销。
主要问题
换句话说,是否有理由(以下是更正式的版本)不建议这样做?基准显示基本上没有下降。显然,这是关于用户输入的内容的一个假设,但这不是重点。
colMeans2 <- function(myobject) {
if (typeof(myobject) == "double") {
colMeans(myobject)
} else if (typeof(myobject) == "list") {
vapply(myobject, mean, 0)
} else {
stop("what is this")
}
}
供参考
在这里我可以找到另外两篇文章,两者都有些相关,并提到colMeans()
应该如何更快。
Grouping functions (tapply, by, aggregate) and the *apply family
Why are `colMeans()` and `rowMeans()` functions faster than using the mean function with `lapply()`?