data.table,计算与前一天值的差异

Posted

技术标签:

【中文标题】data.table,计算与前一天值的差异【英文标题】:data.table, calculate difference to last day value 【发布时间】:2022-01-16 11:49:15 【问题描述】:

我有一个 data.table:

library(data.table)

dt = structure(list(date = c("01.01.2020", "01.01.2020", "02.01.2020", 
                             "02.01.2020", "03.01.2020", "03.01.2020", "04.01.2020", "04.01.2020"
), name = c("10AFC25D", "FA1A310C", "10AFC25D", "FA1A310C", "10AFC25D", 
            "FA1A310C", "10AFC25D", "FA1A310C"), value = c(100L, 50L, 80L, 
                                                           60L, 70L, 60L, 50L, 80L)), row.names = c(NA, -8L), class = c("data.table", "data.frame"))
dt[, date:=as.Date(date, format="%d.%m.%Y")]

看起来像:

> dt
         date     name value
1: 01.01.2020 10AFC25D   100
2: 01.01.2020 FA1A310C    50
3: 02.01.2020 10AFC25D    80
4: 02.01.2020 FA1A310C    60
5: 03.01.2020 10AFC25D    70
6: 03.01.2020 FA1A310C    60
7: 04.01.2020 10AFC25D    50
8: 04.01.2020 FA1A310C    80

目标: 我想计算两个新列,它们给出了最后一天值的差异。一列显示绝对差异,另一列显示相对差异。公式应该是我可以将延迟从 1 天更改为 7 天(如果我想比较相同的工作日)或任何其他值的灵活性。

预期输出应如下所示:

         date     name value diff_absolut diff_relative
1: 01.01.2020 10AFC25D   100           NA            NA
2: 01.01.2020 FA1A310C    50           NA            NA
3: 02.01.2020 10AFC25D    80          -20    -0.2000000
4: 02.01.2020 FA1A310C    60           10     0.2000000
5: 03.01.2020 10AFC25D    70          -10    -0.1250000
6: 03.01.2020 FA1A310C    60            0     0.0000000
7: 04.01.2020 10AFC25D    50          -20    -0.2857143
8: 04.01.2020 FA1A310C    80           20     0.3333333

我可以这样解决:

dt2 = copy(dt)
dt2[, date:=date+days(1)]

dt_final = merge(dt, dt2, by=c("date", "name"), all.x=TRUE, suffixes=c("", "_2"))
dt_final[, `:=`(diff_absolute=value-value_2, diff_relative=(value-value_2)/value_2, value_2=NULL)]
dt_final

         date     name value diff_absolute diff_relative
1: 2020-01-01 10AFC25D   100            NA            NA
2: 2020-01-01 FA1A310C    50            NA            NA
3: 2020-01-02 10AFC25D    80           -20    -0.2000000
4: 2020-01-02 FA1A310C    60            10     0.2000000
5: 2020-01-03 10AFC25D    70           -10    -0.1250000
6: 2020-01-03 FA1A310C    60             0     0.0000000
7: 2020-01-04 10AFC25D    50           -20    -0.2857143
8: 2020-01-04 FA1A310C    80            20     0.3333333

这可以正常工作,但看起来并不优雅和高效。由于原始数据有 1 到 24 行 Mio 行,我想我最好问问是否有人有更平滑的解决方案?请仅 data.table。非常感谢。

【问题讨论】:

【参考方案1】:

如果您从行的角度考虑这一点,应该这样做:

lag = 2L
dt[, diff_absolut := shift(value, n = lag) - value]
dt[, diff_relative := diff_absolut / shift(value, n = lag)]

【讨论】:

【参考方案2】:

喜欢这样吗?

对于更长的延迟,在shift-functions 中设置 n 参数

dt[, `:=`(diff_absolute = value - shift(value),
          diff_relative = (value - shift(value)) / shift(value)), 
   by = .(name)][]

【讨论】:

以上是关于data.table,计算与前一天值的差异的主要内容,如果未能解决你的问题,请参考以下文章

与组或外部变量中的早期实例的差异

Oracle - 两个表中两行之间的差异或变化

你如何将 POSIX 日期转换为一年中的某一天?

如何计算不同时区的两个 NSDate 对象之间的天数差异?

在R中按组计算日期之间的差异

Excel VBA中的时间计算