如何在数据表中按天数滞后值

时间:2014-09-22 14:35:05

标签: r data.table

说我有一个数据表:

id    dt          val1   val2
1   '2014-01-01'  100     200 
2   '2014-01-01'  100     200
3   '2014-01-01'  100     200
4   '2014-01-01'  100     200
...
9   '2014-01-14'  1000   1100
10  '2014-01-14'  1000   1100

共有100行 - 对于十天内的每一个,每天有一个val1和val2。

我需要通过id为可变天数准备一组滞后值。例如,如果我想要两天的延迟,我会看到以下内容:

id    dt          val1   val2  val1_lag  val2_lag
1   '2014-01-01'  100     200    NA         NA
2   '2014-01-01'  100     200    NA         NA
...
1   '2014-01-03'  300     400    100       200
2   '2014-01-03'  300     400    100       200
...
1   '2014-01-09'  500     600    300       400
...
9   '2014-01-14'  1000   1100    800       900

请注意,1月9日,之前的值是1月4日。两天前没有日期,因此返回最接近1月7日(1月9日减去2天)的值,而不是大于1月7日。机械地发生在每一天。例如,在1月3日,使用1月1日的值,因为它们最接近1月3日减去两天。

有一个并发症。由于周末和假日,无法保证滞后日期完全滞后值。我想要最近的值至少x天前

有没有办法使用数据表的强大功能?您可以使用以下命令构建测试表:

library(data.table)
a <- rep(c(1:10), 10)
b <- rep(c(seq(as.Date("2014-01-01"), by = 1, len = 4), seq(as.Date("2014-01-09"), by = 1, len = 6)), 10)
c <- rep(seq(100, by = 100, len = 10), 10)
d <- rep(seq(200, by = 100, len = 10), 10)
e <- data.frame(a, b, c, d)
colnames(e) <- c("id", "dt", "val1", "val2")
setDT(e)
setkeyv(e, c("id", "dt"))

我的直觉说使用类似这个公式来创建滞后值,我只是在为多列自动执行此操作:

setDT(e)[, ??][by = id]

修改 我更改了我的代码,以反映由周末,假期等引起的日期差距。

1 个答案:

答案 0 :(得分:2)

这是使用可能更容易理解的不同最小示例的解决方案(并涵盖更多案例)。

library(data.table)
lag <- 2;
dt <- data.table(id = c(1,1,1,1,2,2), 
                 dt = as.Date(c("2014-1-1", "2014-1-4", "2014-1-6", "2014-1-7", "2014-1-1", "2014-1-10")),
                 val1 = sample(10, 6),
                 val2 = sample(10, 6))
dt
   id         dt val1 val2
1:  1 2014-01-01    8    7
2:  1 2014-01-04   10    5
3:  1 2014-01-06    3    3
4:  1 2014-01-07    7    2
5:  2 2014-01-01    2    1
6:  2 2014-01-10    5    6

dt1 <- copy(dt)
dt1[, laggedDate:=dt]
setkey(dt1, "id", "laggedDate")

dt2 <- copy(dt)
dt2[, laggedDate:=dt-2]
setkey(dt2, "id", "laggedDate")

setnames(dt1, c("dt","val1", "val2"), c("dt.lagged", "val1.lagged", "val2.lagged"))
dt1[dt2, roll=TRUE]
   id laggedDate  dt.lagged val1.lagged val2.lagged         dt val1 val2
1:  1 2013-12-30       <NA>          NA          NA 2014-01-01    8    7
2:  1 2014-01-02 2014-01-01           8           7 2014-01-04   10    5
3:  1 2014-01-04 2014-01-04          10           5 2014-01-06    3    3
4:  1 2014-01-05 2014-01-04          10           5 2014-01-07    7    2
5:  2 2013-12-30       <NA>          NA          NA 2014-01-01    2    1
6:  2 2014-01-08 2014-01-01           2           1 2014-01-10    5    6

这里的关键是使用data.table的滚动连接功能。如果您对此感到不舒服,请查看this blog post