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,计算与前一天值的差异的主要内容,如果未能解决你的问题,请参考以下文章