如何按日期获得滞后变量的差异?
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))]
考虑以下示例:
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))]