我试图在大表上进行此操作,以在数据中使用A和B的不同组合计数。Tablex。
Y <- aggregate(c ~ a+b,X,length)
这是永远花的(我在30分钟后停止),尽管RAM使用量仍在。
然后,我尝试手动循环通过b
的值并仅在a
上进行汇总(从技术上讲仍在b
上汇总,但每次都以b
为单一值):
sub_agg <- list()
unique_bs <- unique(X$b)
for (b_it in unique_bs){
sub_agg[[length(sub_agg)+1]] <- aggregate(c ~ a + b,subset(X, b == b_it),length)
}
Y <- do.call(rbind, sub_agg )
,我在3分钟内完成了。
我也可以走得更远,完全摆脱了总体,只有在子集上进行操作。
总体效率不如嵌套环和子集上的操作效率不高,或者这是一种特殊情况?
聚集通常是最花时间的代码部分,所以我现在正在考虑总是尝试循环,我想更好地理解这里发生的事情。
附加信息:
x有2000万行
B
的50个不同的值 的15 000个不同的值
是的,汇总的效率不如您在那里使用的循环,因为:
- 当数据点数量增加时,聚集体的速度降低了。您的第二个解决方案在小子集上使用
aggregate
。中的一个原因是aggregate
取决于排序,并且在O(n)时间中不进行排序。 - 汇总还在内部使用
expand.grid
,该数据框架具有变量A和B中所有唯一值的所有可能组合。您可以在aggregate.data.frame
的内部代码中看到这一点。同样,随着观察次数的增加,此功能变得越来越慢。 - 编辑:我的最后一点并没有真正有意义
也就是说,这里绝对没有理由在这里使用aggregate
。我只需使用table
即可进入数据框Y
:
thecounts <- with(X, table(a,b))
Y <- as.data.frame(thecounts)
此解决方案比使用aggregate
提出的解决方案要快得多。准确地说我的机器上有68次...
基准:
test replications elapsed relative
1 aggloop() 1 15.03 68.318
2 tableway() 1 0.22 1.000
基准测试的代码(请注意,我使所有内容都稍小一点,以免阻止我的r太长):
nrows <- 20e5
X <- data.frame(
a = factor(sample(seq_len(15e2), nrows, replace = TRUE)),
b = factor(sample(seq_len(50), nrows, replace = TRUE)),
c = 1
)
aggloop <- function(){
sub_agg <- list()
unique_bs <- unique(X$b)
for (b_it in unique_bs){
sub_agg[[length(sub_agg)+1]] <- aggregate(c ~ a + b,subset(X, b == b_it),length)
}
Y <- do.call(rbind, sub_agg )
}
tableway <- function(){
thecounts <- with(X, table(a,b))
Y <- as.data.frame(thecounts)
}
library(rbenchmark)
benchmark(aggloop(),
tableway(),
replications = 1
)
@jorismeys的建议,并说明我的评论,这是实现您所追求的一种方法的另一种方法。
data.table
语法的一般形式是, DT
是 data.table
: DT[i, j, by]
,含义"取dt,使用i的子集行,然后计算j,由" 。
分组)例如,X
中的每个a
和b
级别获得计数的代码为:X[, .N, by=c("a", "b")]
。
您可以在本软件包简介中阅读有关data.table
的更多信息。
如果我们想使用相同的示例数据X和Jorismeys中定义的函数进行其他方式基准data.table
。
library(data.table)
X2 <- copy(X) # taking a copy of X so the conversion to data.table does not impact the initial data
dtway <- function(){
setDT(X2)[, .N, by=c("a", "b")] # setDT permits to convert X2 into a data.table
}
library(rbenchmark)
benchmark(aggloop(),
tableway(),
dtway(),
replications = 1)
# test replications elapsed relative
# 1 aggloop() 1 17.29 192.111
# 3 dtway() 1 0.09 1.000
# 2 tableway() 1 0.27 3.000
注意:效率取决于数据,我尝试了几个X
(具有不同的随机种子),并发现data.table
相对于base
table
,CC_24的相对效率从1/2.5到1/3.5。