【问题标题】:R: Using several criteria for the Aggregate functionR:对聚合函数使用多个标准
【发布时间】:2012-05-18 11:45:28
【问题描述】:

我正在寻找一种解决方案,如何使用聚合函数来总结其他列中给定几个条件的列。 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

【问题讨论】:

    标签: r aggregate plyr data.table


    【解决方案1】:

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

    使用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
    

    接下来使用 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
    

    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)
    

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

    【讨论】:

    • 通过在 25 行 data.frame 上重复相同的调用 100 次(microbenchmark 的默认值为 times=100L)来比较这两种方法。不知道你在说什么。
    • 酷。既然是星期五,为了好玩,想把这个加入到组合中吗? DT[,.Internal(mean(load)),keyby=list(date,peak)],其中DT=as.data.table(dat) 首先在计时之外完成。我已经在 1.8.1 中自动设置了 .Internal 位(尚未提交),但是对于 CRAN 上的 1.8.0,您必须手动编写它(根据 wiki 第 3 项)。
    • 周五的乐趣终于可以正常使用了。
    • 感谢您的提示!我们发现使用聚合函数也可以处理多个条件... >>aggregate(tab$number, by = list (tab$criteria1, tab$criteria2, sum))
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-29
    • 2020-01-07
    • 1970-01-01
    • 2014-01-21
    • 1970-01-01
    • 2016-05-02
    • 2019-07-03
    相关资源
    最近更新 更多