尝试使用 dplyr 聚合时数据太大?

Data too large when trying to aggregate with dplyr?

我有一个将近 200 万行的巨大数据框。结构是这样的:

head(df)
         TimeStamp Price Contracts
1 9/29/2014 9:00:03 AM 16.05        10
2 9/29/2014 9:00:03 AM 16.04         1
3 9/29/2014 9:00:06 AM 16.05         2
4 9/29/2014 9:00:07 AM 16.05        11
5 9/29/2014 9:00:07 AM 16.05         1
6 9/29/2014 9:00:07 AM 16.05         1

如您所见,有多个具有多个条目的时间戳。我试图通过取加权平均值来按时间戳汇总此 df。我正在使用 dplyr 包,下面是我正在使用的代码,结果是:

as.data.frame(df %>% group_by(TimeStamp) %>% summarise(VWAP = weighted.mean(Price, Contracts)))
              TimeStamp     VWAP
1 9/29/2014 10:00:08 AM 16.09000
2 9/29/2014 10:00:11 AM 16.09000
3 9/29/2014 10:00:17 AM 16.10012
4 9/29/2014 10:00:18 AM 16.12500
5 9/29/2014 10:00:20 AM 16.15000
6 9/29/2014 10:00:22 AM 16.10000

说哇哇???上午 9 点的数据怎么了?!?!结果似乎跳过了数据帧的第一块!所以,我只取前千行,重新运行聚合,结果如下:

as.data.frame(head(df, 1000) %>% group_by(TimeStamp) %>% summarise(VWAP = weighted.mean(Price, Contracts)))
             TimeStamp     VWAP
1 9/29/2014 9:00:03 AM 16.04909
2 9/29/2014 9:00:06 AM 16.05000
3 9/29/2014 9:00:07 AM 16.05000
4 9/29/2014 9:00:08 AM 16.05500
5 9/29/2014 9:00:13 AM 16.06000
6 9/29/2014 9:00:20 AM 16.05000

他们来了!!怎么回事,这里?!?!所以,我一直在玩 df 的大小。我发现在大约 3000 行处,返回的 df 似乎开始覆盖自身:

as.data.frame(head(df, 3100) %>% group_by(TimeStamp) %>% summarise(VWAP = weighted.mean(Price, Contracts)))
> head(tester1)
              TimeStamp     VWAP
1 9/29/2014 10:00:08 AM 16.09000
2 9/29/2014 10:00:11 AM 16.09000
3 9/29/2014 10:00:17 AM 16.10012
4  9/29/2014 9:00:03 AM 16.04909
5  9/29/2014 9:00:06 AM 16.05000
6  9/29/2014 9:00:07 AM 16.05000

看来 dply 中存在某种内存限制?这是怎么回事?我查看了文档,没有找到任何东西......

这是一个使用 lubridate 和 data.table 包的解决方案。

library(data.table)
library(lubridate)
setDT(df)
# convert timestamp to a POSIXct object to allow for proper sorting by time
df[ , TimeStamp := mdy_hms(TimeStamp)]
# sort by time
setkey(df, TimeStamp)
# perform weighted mean by Timestamp
df[ , .(VWAP = weighted.mean(Price, Contracts)), by = key(df)]

好吧,多亏了大卫,我明白了。 df 被排序就好像它是字符(它们是)。所以,df 很好,我使用以下方法对其进行排序并按我的预期得到它。 (欢迎提出更好或更优雅的方法...)

df$TimeStamp <- strptime(df$TimeStamp, format = "%m/%d/%Y %I:%M:%S %p")
df<- df[order(df$TimeStamp),]