【发布时间】:2014-07-12 02:40:47
【问题描述】:
我想获取 data.frame/matrix 的列,并在数据帧的每个单元格 ([i, j]) 之间应用一个函数,其中 i 和 j 是沿 data.frame 列的序列。基本上,我想以与cor 函数与 data.frame 一起使用的相同方式填充单个单元格的矩阵。
这是一个相关问题:Create a matrix from a function and two numeric data frames 但是,我在随机化测试中使用它并多次重复操作(制作许多矩阵)。我正在寻找执行此操作的最快方法。我使用并行处理加快了速度,但我仍然对这种速度不满意。也不能假设矩阵输出是对称的,即cor 产生对称矩阵的方式(我的示例将反映这一点)。
我今天在 data.table 网页上看到了以下内容 (http://datatable.r-forge.r-project.org/):
比
DF[i,j]<-value快500+倍
这让我想到data.table 或dplyr 或其他方式可能会加快速度。我的大脑一直专注于填充细胞,但也许有更好的方法涉及重塑、应用功能和重塑矩阵或类似的东西。我可以使用outer 或for 循环在base R 中实现这一点,如下所示。
## Arbitrary function
FUN <- function(x, y) round(sqrt(sum(x)) - sum(y), digits=1)
## outer approach
outer(
names(mtcars),
names(mtcars),
Vectorize(function(i,j) FUN(mtcars[,i],mtcars[,j]))
)
## for approach
mat <- matrix(rep(NA, ncol(mtcars)^2), ncol(mtcars))
for (i in 1:ncol(mtcars)) {
for (j in 1:ncol(mtcars)) {
mat[i, j] <- FUN(mtcars[, i], mtcars[, j])
}
}
mat
以下是microbenchmark 的时间安排,for 略有优势。
Unit: milliseconds
expr min lq median uq max neval
OUTER() 4.450410 4.691124 4.774394 4.877724 55.77333 1000
FOR() 4.309527 4.521785 4.588728 4.694156 7.04275 1000
R 中最快的方法是什么(欢迎添加软件包)?
【问题讨论】:
-
你的真实数据集的维度大约是多少?
-
变化很大,从 10 X 10 到 1000 X 1000
-
既然你说函数是任意的,那么函数本身是否可以向量化就不好说了。我的意思是,在这里,您可以计算一次
colSums(mat),一次计算sqrt(.),然后使用expand.grid(或CJ——更快,从data.table)生成组合。在不知道可能的矢量化数量的情况下,我只能建议 C 或 Rcpp。 -
@Arun 这很明智。我一直在寻找可以与任何功能一起使用的通用代码。我认为
CJ的想法可能会给我一些尝试和替补的东西。但是是的,函数上的矢量离子非常重要。 -
使用
.subset2(mtcars, i)而不是mtcars[, i],您将获得 4-5 倍的加速
标签: r performance data.table dplyr