如何使用data.table

时间:2017-11-25 09:52:11

标签: r data.table quantile rollapply

我想使用数据表计算滚动分位数,数据表包含多个组的数据,对于每组我有多天,每天我有多个观察。我不想计算表格中每个观察点的滚动分位数,但总是记录最后一天的数据,比如3天,计算分位数并继续前进。

我有这样的数据:

test2 <- data.table(group = rep(c("a", "b"), each = 100),
                    date = rep(rep(seq(from = as.Date('2017-01-01'),
                                    as.Date('2017-01-10'),
                                    by = "day"), each = 10), 2),
                    time = rep(rep(seq(from = 1, 10, by = 1), times = 10), 2),
                    some_data = rnorm(200) + c(1:20, 20:1, 30:1, 1:30, 30:1, 1:20, 20:1, 1:30))

上表有2个不同的组,每组有10天的数据,每天有10个观察值。接下来,我想计算每个组的滚动分位数。

理论上,我可以像这样计算:

tests_result <- test2[, list(date = date,
                         q_30 = rollapply(some_data,
                                          30, quantile,
                                          probs = 0.3,
                                          fill = NA, align = "right")),
                  by = "group"][seq(from = 10, to = 200, by = 10)]

但即使我使用基于c ++的代码计算分位数,这也会非常缓慢!所以我真正想要的是仅将结果返回到当天的最后一次观察。

问题2)我每天都有不同数量的观测值,但仍希望能够计算特定天数的滚动分位数(而不是设置评估分位数的窗口的固定宽度)

示例方案中的输出应如下所示:

    group       date      q_30
 1:     a 2017-01-01        NA
 2:     a 2017-01-02        NA
 3:     a 2017-01-03 10.284081
 4:     a 2017-01-04  8.281827
 5:     a 2017-01-05  8.281827
 6:     a 2017-01-06  8.281827
 7:     a 2017-01-07 10.274793
 8:     a 2017-01-08  4.749455
 9:     a 2017-01-09  4.749455
10:     a 2017-01-10  9.246267
11:     b 2017-01-01        NA
12:     b 2017-01-02        NA
13:     b 2017-01-03 10.145996
14:     b 2017-01-04  5.423782
15:     b 2017-01-05  5.423782
16:     b 2017-01-06  9.741683
17:     b 2017-01-07 10.123940
18:     b 2017-01-08  4.347293
19:     b 2017-01-09  4.347293
20:     b 2017-01-10  9.177718

总结挑战:

  1. 每天只计算一次分位数,而不是10 次
  2. 执行给定天数的分位数计算 即使每天都有不同数量的观察结果。 即,如果我想根据2天,第一天计算分位数 会有10个值,第2天20个值,我会得到一个结果 在这两天的30个值和最终结果 计算将分配到第二天的日期。
  3. 修改

    我想办法如何处理我拥有的数据集。但我认为它仍然有很大的改进,所以,如果你有任何建议,我想听听它们。

    我对样本数据集的处理方式如下:

    首先计算每个后续3天的观测总数,同时计算给定日期最后一次观测的原始数据集中的行数。这些新变量将被称为in_3orig_row

    test3 <- test2[, list(.N, orig_row = .I[.N]), by = c("group", "date")][, list(date,in_3 = rollapply(N, 3, sum, fill = NA, align = "right"),
                                                      orig_row),
                                               by = "group"]
    

    然后使用foreach包迭代原始数据帧的相关子集并计算每个子集的分位数。

    library(foreach)
    quantiles <- foreach(i = 1:nrow(test3),.combine = 'c') %do% 
      ifelse(!is.na(test3[i]$V3 - test3[i]$in_3 + 1),
      test2[(test3[i]$orig_row - 3[i]$in_3 + 1):test3[i]$orig_row][,quantile(some_data, probs = 0.3)],
      NA)
    

    最后,分配到聚合数据集

    test3[, `:=`(q03 = quantiles)]
    

    我也尝试并行运行它,但是我的笔记本电脑耗尽了物理内存并且开始写入磁盘太多了,这使得进程减慢得更多,然后只用一个核心进行运算。

0 个答案:

没有答案