【发布时间】:2011-11-01 02:16:44
【问题描述】:
我有一个包含 1008412 个观测值的大型数据集,
这些列是customer_id(整数)、visit_date(日期,格式:“2010-04-04”)、visit_spend(浮点数)。
此聚合日期函数将感兴趣的周数映射到 13-65 范围内:
weekofperiod <- function(dt) {
as.numeric(format(as.Date(dt), "%W")) + 52 * (as.numeric(format(as.Date(dt), "%Y"))-2010)
}
每个 customer_id 在 53 周内的总访问次数不定。
对于每个customer_id,我想通过weekofperiod() 获得spend_per_week 的聚合。
下面的代码在功能上是正确的,但非常慢 - cmets 让它更快?
此外,aggregate() 产生稀疏输出,其中缺少未访问的周数,我将spend_per_week 初始化为 0,然后逐行手动分配来自 aggregate() 的非零结果,以确保结果始终有 53 行。确定可以做得更好吗?
示例数据集行如下所示:
customer_id visit_date visit_spend
72 40 2011-03-15 18.38
73 40 2011-03-20 23.45
74 79 2010-04-07 150.87
75 79 2010-04-17 101.90
76 79 2010-05-02 111.90
这是针对空周的汇总调用和调整的代码:
for (cid in all_tt_cids) {
print_pnq('Getting statistics for cid', cid)
# Get row indices of the selected subset, for just this cid's records
I <- which(tt$customer_id==cid & tt$visit_date<="2011-03-31")
# (other code to compute other per-cid statistics)
# spend_per_week (mode;mean;sd)
# Aggregate spend_per_week, but beware this should be 0 for those week with no visits
spend_per_week <- data.frame(c(list('weekofperiod'=13:65), list('spendperweek'=0)) )
nonzero_spends_per_week <- aggregate(tt$visit_spend[I], list('weekofperiod'=weekofperiod(tt$visit_date[I])), FUN="sum")
for (i in 1:nrow(nonzero_spends_per_week)) {
spend_per_week[spend_per_week$weekofperiod==nonzero_spends_per_week[i,1],2] <- nonzero_spends_per_week[i,2]
}
colnames(spend_per_week)[2] <- 'spend_per_week'
# (code to compute and store per-cid statistics on spend_per_week)
}
【问题讨论】:
-
原始数据的来源是什么?一个sql数据库?对于纯粹的速度,我建议使用数据库引擎并返回准备显示结果。此查询并不过分复杂,可以在 SQL 中处理。
-
纯 .csv。我试图为每个 customer_id 计算 50 个不同的统计信息(这是被省略的代码),所以在 sqldf 中只做这个计算是没有意义的。所以我的限制是原生 R 语言。
-
@John Colby 下面的回答很好。使用
data.table中的东西可能会进一步加快速度?
标签: r dataframe aggregate sparse-matrix