1

我正在寻找一种解决方案,如何使用聚合函数来总结其他列中给定几个条件的列。R 应该在一列中选择一个范围,并在考虑另一行的值的情况下在同一行中执行操作。

我试图解决的实际问题如下:我得到了一份两年内每天每 15 分钟测量一次的电力负荷清单。它看起来像这样:

日期_ __ _ __时间__ _ __ _加载
01-01-2010 00:00-00:15 1234

01-01-2010 00:15-00:30 2313

01-01-2010 ...

01-01-2010 23:30-23:45 2341

...

31-12-2011 23:30-23:45 2347

我的目标是计算所谓的“峰值负载”和“非峰值负载”峰值是从早上 8 点到晚上 8 点。非高峰期则相反。所以我想计算每天的高峰和非高峰。因此,我需要每天 8:00 到 20:00 的聚合并计算当天的剩余负载。

我也很开心

谢谢你的帮助!

最好的,F

4

1 回答 1

4

我认为你在这里的层次结构的心理模型使这种方式过于复杂。您不必按天然后按高峰/非高峰进行子集化。只是联合子集。

使用ddply

dat <- data.frame(date=rep(seq(5),5),time=runif(25),load=rnorm(25))
library(plyr)
dat$peak <- dat$time<.5
ddply(dat, .(date,peak), function(x) mean(x$load) )

> ddply(dat, .(date,peak), function(x) mean(x$load) )
   date  peak           V1
1     1 FALSE -1.064166845
2     1  TRUE  0.172868201
3     2 FALSE  0.638594830
4     2  TRUE  0.045538051
5     3 FALSE  0.201264770
6     3  TRUE  0.054019462
7     4 FALSE  0.722268759
8     4  TRUE -0.490305933
9     5 FALSE  0.003411591
10    5  TRUE  0.628566966

使用aggregate

> aggregate(dat$load, list(dat$date,dat$peak), mean )
   Group.1 Group.2            x
1        1   FALSE -1.064166845
2        2   FALSE  0.638594830
3        3   FALSE  0.201264770
4        4   FALSE  0.722268759
5        5   FALSE  0.003411591
6        1    TRUE  0.172868201
7        2    TRUE  0.045538051
8        3    TRUE  0.054019462
9        4    TRUE -0.490305933
10       5    TRUE  0.628566966

只是为了好玩,基准测试

首先,使用上面的 5x5 条目:

> microbenchmark(
+   ddply(dat, .(date,peak), function(x) mean(x$load) ),
+   aggregate(dat$load, list(dat$date,dat$peak), mean )
+   )
Unit: milliseconds
                                                 expr      min       lq   median       uq      max
1 aggregate(dat$load, list(dat$date, dat$peak), mean) 1.323438 1.376635 1.445769 1.549663 2.853348
2 ddply(dat, .(date, peak), function(x) mean(x$load)) 4.057177 4.292442 4.386289 4.534728 6.864962

5x5 基准测试

接下来使用 500x500 条目

> m
Unit: milliseconds
                                                 expr      min       lq   median       uq      max
1 aggregate(dat$load, list(dat$date, dat$peak), mean) 558.9524 570.7354 590.4633 599.4404 634.3201
2 ddply(dat, .(date, peak), function(x) mean(x$load)) 317.7781 348.1116 361.7118 413.4490 503.8540

500x500 基准

50x50 基准

n <- 50
dat <- data.frame(date=rep(seq(n),n),time=runif(n),load=rnorm(n))
dat$peak <- dat$time<.5

library(plyr)
library(microbenchmark)
library(data.table)
DT <- as.data.table(dat)
m <- microbenchmark(
  ddply(dat, .(date,peak), function(x) mean(x$load) ),
  aggregate(dat$load, list(dat$date,dat$peak), mean ),
  DT[,.Internal(mean(load)),keyby=list(date,peak)]
  )
m
plot(m)

50x50

因此,对于小问题,聚合更快(大概是因为加载所有机器的开销更少),而对于大问题(速度很重要),ddply 更快。Data.table 把一切都吹走了(像往常一样)。

于 2012-05-18T11:53:53.353 回答