将 dplyr:lag() 与不完整的时间序列数据一起使用
Using dplyr:lag() with patchy time series data
我有一些类似于以下的时间序列数据:
df <- data.frame(id = c("001","001","001","002", "003","003","003","003",
"004","004","004","005"),
year_mon = c(2021-01, 2021-02, 2021-03, 2021-01, 2021-01, 2021-05, 2021-06,
2021-08, 2021-03, 2021-04, 2021-07, 2021-08),
value = c(15, 20, 25, 30, 19, 17, 18, 21, 39, 45, 21, 10))
id year_mon value
001 2021-01 15
001 2021-02 20
001 2021-03 25
002 2021-01 30
003 2021-01 19
003 2021-05 17
003 2021-06 18
003 2021-08 21
004 2021-03 39
004 2021-04 45
004 2021-07 21
005 2021-08 10
我想每个 id
滞后 'value' 1 个月。但是,在 year_mon
列中缺少一些日期。
我试过:
new_df <- df %>%
arrange(id, year_mon) %>%
group_by(id) %>%
mutate(lag_value = lag(value, 1L))
但这是返回上一行的值,而不是上个月的值。我该怎么做才能使数据输出为:
id year_mon value lag_value
001 2021-01 15 NA
001 2021-02 20 15
001 2021-03 25 20
002 2021-01 30 NA
003 2021-01 19 NA
003 2021-05 17 NA
003 2021-06 18 17
003 2021-08 21 NA
004 2021-03 39 NA
004 2021-04 45 39
004 2021-07 21 NA
005 2021-08 10 NA
如果 year_mon
中的月份不是 -1 月,则返回 NA
。
通过将它们转换为日期并使用 complete
临时填充所有缺失的月份
df %>%
mutate(
Date1 = as.Date(paste(year_mon,"-01",sep=""))
) %>%
arrange(id, year_mon) %>%
group_by(id) %>%
complete(Date1 = seq.Date(min(Date1), max(Date1), by='month')) %>%
mutate(lag_value = lag(value, 1L)) %>%
filter(!is.na(year_mon)) %>%
select(-Date1)
id year_mon value lag_value
<chr> <chr> <dbl> <dbl>
1 001 2021-01 15 NA
2 001 2021-02 20 15
3 001 2021-03 25 20
4 002 2021-01 30 NA
5 003 2021-01 19 NA
6 003 2021-05 17 NA
7 003 2021-06 18 17
8 003 2021-08 21 NA
9 004 2021-03 39 NA
10 004 2021-04 45 39
11 004 2021-07 21 NA
12 005 2021-08 10 NA
定义一个函数diff_mon,其中returns 当前year_mon 和之前year_mon 之间的月份差异。它将参数转换为 yearmon class,然后使用 diff 获取当前条目和先前条目之间的年份差异。将其乘以 12 并四舍五入得到当前项目和上一个项目之间的月数。如果是 1,则使用滞后,否则使用 NA。
library(dplyr)
library(zoo)
# difference in months.
# x is character vec with format yyyy-mm (or has class with as.yearmon method)
diff_mon <- function(x) round(12 * c(NA, diff(as.yearmon(x))))
df %>%
arrange(id, year_mon) %>%
group_by(id) %>%
mutate(lag = ifelse(diff_mon(year_mon) == 1, lag(value), NA)) %>%
ungroup
给予:
# A tibble: 12 x 4
id year_mon value lag
<chr> <chr> <dbl> <dbl>
1 001 2021-01 15 NA
2 001 2021-02 20 15
3 001 2021-03 25 20
4 002 2021-01 30 NA
5 003 2021-01 19 NA
6 003 2021-05 17 NA
7 003 2021-06 18 17
8 003 2021-08 21 NA
9 004 2021-03 39 NA
10 004 2021-04 45 39
11 004 2021-07 21 NA
12 005 2021-08 10 NA
备注
问题中 year_mon 值周围缺少引号,因此我们使用了这个。
df <- structure(list(id = c("001", "001", "001", "002", "003", "003",
"003", "003", "004", "004", "004", "005"), year_mon = c("2021-01",
"2021-02", "2021-03", "2021-01", "2021-01", "2021-05", "2021-06",
"2021-08", "2021-03", "2021-04", "2021-07", "2021-08"), value = c(15,
20, 25, 30, 19, 17, 18, 21, 39, 45, 21, 10)), class = "data.frame", row.names = c(NA,
-12L))
我有一些类似于以下的时间序列数据:
df <- data.frame(id = c("001","001","001","002", "003","003","003","003",
"004","004","004","005"),
year_mon = c(2021-01, 2021-02, 2021-03, 2021-01, 2021-01, 2021-05, 2021-06,
2021-08, 2021-03, 2021-04, 2021-07, 2021-08),
value = c(15, 20, 25, 30, 19, 17, 18, 21, 39, 45, 21, 10))
id year_mon value
001 2021-01 15
001 2021-02 20
001 2021-03 25
002 2021-01 30
003 2021-01 19
003 2021-05 17
003 2021-06 18
003 2021-08 21
004 2021-03 39
004 2021-04 45
004 2021-07 21
005 2021-08 10
我想每个 id
滞后 'value' 1 个月。但是,在 year_mon
列中缺少一些日期。
我试过:
new_df <- df %>%
arrange(id, year_mon) %>%
group_by(id) %>%
mutate(lag_value = lag(value, 1L))
但这是返回上一行的值,而不是上个月的值。我该怎么做才能使数据输出为:
id year_mon value lag_value
001 2021-01 15 NA
001 2021-02 20 15
001 2021-03 25 20
002 2021-01 30 NA
003 2021-01 19 NA
003 2021-05 17 NA
003 2021-06 18 17
003 2021-08 21 NA
004 2021-03 39 NA
004 2021-04 45 39
004 2021-07 21 NA
005 2021-08 10 NA
如果 year_mon
中的月份不是 -1 月,则返回 NA
。
通过将它们转换为日期并使用 complete
df %>%
mutate(
Date1 = as.Date(paste(year_mon,"-01",sep=""))
) %>%
arrange(id, year_mon) %>%
group_by(id) %>%
complete(Date1 = seq.Date(min(Date1), max(Date1), by='month')) %>%
mutate(lag_value = lag(value, 1L)) %>%
filter(!is.na(year_mon)) %>%
select(-Date1)
id year_mon value lag_value
<chr> <chr> <dbl> <dbl>
1 001 2021-01 15 NA
2 001 2021-02 20 15
3 001 2021-03 25 20
4 002 2021-01 30 NA
5 003 2021-01 19 NA
6 003 2021-05 17 NA
7 003 2021-06 18 17
8 003 2021-08 21 NA
9 004 2021-03 39 NA
10 004 2021-04 45 39
11 004 2021-07 21 NA
12 005 2021-08 10 NA
定义一个函数diff_mon,其中returns 当前year_mon 和之前year_mon 之间的月份差异。它将参数转换为 yearmon class,然后使用 diff 获取当前条目和先前条目之间的年份差异。将其乘以 12 并四舍五入得到当前项目和上一个项目之间的月数。如果是 1,则使用滞后,否则使用 NA。
library(dplyr)
library(zoo)
# difference in months.
# x is character vec with format yyyy-mm (or has class with as.yearmon method)
diff_mon <- function(x) round(12 * c(NA, diff(as.yearmon(x))))
df %>%
arrange(id, year_mon) %>%
group_by(id) %>%
mutate(lag = ifelse(diff_mon(year_mon) == 1, lag(value), NA)) %>%
ungroup
给予:
# A tibble: 12 x 4
id year_mon value lag
<chr> <chr> <dbl> <dbl>
1 001 2021-01 15 NA
2 001 2021-02 20 15
3 001 2021-03 25 20
4 002 2021-01 30 NA
5 003 2021-01 19 NA
6 003 2021-05 17 NA
7 003 2021-06 18 17
8 003 2021-08 21 NA
9 004 2021-03 39 NA
10 004 2021-04 45 39
11 004 2021-07 21 NA
12 005 2021-08 10 NA
备注
问题中 year_mon 值周围缺少引号,因此我们使用了这个。
df <- structure(list(id = c("001", "001", "001", "002", "003", "003",
"003", "003", "004", "004", "004", "005"), year_mon = c("2021-01",
"2021-02", "2021-03", "2021-01", "2021-01", "2021-05", "2021-06",
"2021-08", "2021-03", "2021-04", "2021-07", "2021-08"), value = c(15,
20, 25, 30, 19, 17, 18, 21, 39, 45, 21, 10)), class = "data.frame", row.names = c(NA,
-12L))