如何按日期获得滞后变量的差异?

How to get the difference of a lagged variable by date?

考虑以下示例:

library(tidyverse)
library(lubridate)

df = tibble(client_id = rep(1:3, each=24),
            date = rep(seq(ymd("2016-01-01"), (ymd("2016-12-01") + years(1)), by='month'), 3),
            expenditure = runif(72))

df 中,您存储了过去 2 年中一群客户的每月支出信息。现在您要为每个客户计算今年与上一年之间的每月差异。

有什么方法可以保持数据集的 "long" 格式吗?在这里,我向您展示我现在的做法,这意味着要走得更远:

df2 = df %>% 
  mutate(date2 = paste0('val_',
                        year(date), 
                        formatC(month(date), width=2, flag="0"))) %>% 
  select(client_id, date2, value) %>% 
  pivot_wider(names_from = date2, 
              values_from = value)

df3 = (df2[,2:13] - df2[,14:25])

但是我发现它不必要的复杂,而且在大型数据集中,从长到宽会花费相当多的时间,所以我认为必须有更好的方法。

如果您想以长格式保存数据,一种方法是按每个 client_id 的月份和日期值分组,然后使用 diff 计算差异。

library(dplyr)

df %>% 
  group_by(client_id, month_date = format(date, "%m-%d")) %>%
  summarise(diff = -diff(expenditure))

#   client_id month_date  diff
#       <int> <chr>       <dbl>
# 1         1 01-01       0.278  
# 2         1 02-01      -0.0421 
# 3         1 03-01       0.0117 
# 4         1 04-01      -0.0440 
# 5         1 05-01       0.855  
# 6         1 06-01       0.354  
# 7         1 07-01      -0.226  
# 8         1 08-01       0.506  
# 9         1 09-01       0.119  
#10         1 10-01       0.00819
# … with 26 more rows

选项data.table

library(data.table)
library(zoo)
setDT(df)[, .(diff = -diff(expenditure)), .(client_id, month_date = as.yearmon(date))]