【问题标题】:R: Aggregating Large Data Frame under a Grouping ConditionR:在分组条件下聚合大数据框
【发布时间】:2014-03-12 18:47:47
【问题描述】:

我正在尝试找出聚合大型数据框(约 50M 行)的最快方法,该数据框类似于:

>sample_frame = data.frame("id" = rep(sample(1:100,2,replace=F),3),
+ "date" = sample(seq(as.Date("2014-01-01"),as.Date("2014-02-13"),by=1),6),
+ "value" = runif(6))
> sample_frame
  id       date      value
1 73 2014-02-11 0.84197491
2  7 2014-01-14 0.08057893
3 73 2014-01-16 0.78521616
4  7 2014-01-24 0.61889286
5 73 2014-02-06 0.54792356
6  7 2014-01-06 0.66484848

这里我们有 2 个具有 3 个日期的唯一 ID,并为每个 ID 分配了一个值。我知道我可以使用 ddply 或 data.table,或者只是一个 lapply 来聚合并找到每个 ID 的平均值。

我真正想要的是一种快速找到最近两个日期的每个 ID 的平均值的方法。例如,使用 sapply:

> sapply(split(sample_frame,sample_frame$id),function(x){
+   mean(x$value[x$date%in%x$date[order(x$date,decreasing=T)][1:2]])
+ })
        7        73 
0.3497359 0.6949492

我不知道如何获取 data.table 来执行此操作。想法?提示?

【问题讨论】:

  • 好问题,抱歉不清楚。是的,每个 ID 的日期应该是唯一的。如果有只有 1 行的组,则应该只返回该行的值。
  • 没有 NA 值,数据是干净的。

标签: r dataframe grouping aggregate data.table


【解决方案1】:

为什么不在“data.table”聚合步骤中使用tail

set.seed(1)
sample_frame = data.frame("id" = rep(sample(1:100,2,replace=F),3),
                          "date" = sample(seq(as.Date("2014-01-01"),
                                              as.Date("2014-02-13"),by=1),6),
                          "value" = runif(6))

DT <- data.table(sample_frame, key = "id,date")
DT
#    id       date      value
# 1: 27 2014-01-09 0.20597457
# 2: 27 2014-01-26 0.62911404
# 3: 27 2014-02-07 0.68702285
# 4: 37 2014-02-06 0.17655675
# 5: 37 2014-02-09 0.06178627
# 6: 37 2014-02-13 0.38410372
DT[, mean(tail(value, 2)), by = id]
#    id        V1
# 1: 27 0.6580684
# 2: 37 0.2229450

由于您只需要两个值的平均值,因此您可以直接进行(不使用mean)。您可以使用内部变量 .N 而不是 tail 来获得更多的加速。您只需要处理只有 1 个日期的情况。基本上,这应该快得多。

DT[, (value[.N]+value[max(1L, .N-1)])/2, by=id]

【讨论】:

    猜你喜欢
    • 2017-02-22
    • 2022-12-06
    • 1970-01-01
    • 2016-01-13
    • 2020-01-19
    • 2014-11-07
    • 1970-01-01
    • 2021-08-18
    • 2020-03-01
    相关资源
    最近更新 更多