【发布时间】:2019-07-31 15:37:29
【问题描述】:
假设一个像这样的df:
df <- data.frame(end_date = as.Date("2007-10-10", format = "%Y-%m-%d"))
end_date
1 2007-10-10
我想生成从给定日期开始并返回 N 个月(在本例中为 11 个月)的每月日期序列。之后,我想为每 N 个月分配一个组 ID(在本例中为 2 个月)。我可以这样做:
library(tidyverse)
library(lubridate)
df %>%
mutate(start_date = end_date %m-% months(11),
date = list(seq.Date(start_date, end_date, by = "month"))) %>%
unnest() %>%
arrange(desc(date)) %>%
mutate(ID = gl(ceiling(n()/3), 3, length = n()))
end_date start_date date ID
1 2007-10-10 2006-11-10 2007-10-10 1
2 2007-10-10 2006-11-10 2007-09-10 1
3 2007-10-10 2006-11-10 2007-08-10 1
4 2007-10-10 2006-11-10 2007-07-10 2
5 2007-10-10 2006-11-10 2007-06-10 2
6 2007-10-10 2006-11-10 2007-05-10 2
7 2007-10-10 2006-11-10 2007-04-10 3
8 2007-10-10 2006-11-10 2007-03-10 3
9 2007-10-10 2006-11-10 2007-02-10 3
10 2007-10-10 2006-11-10 2007-01-10 4
11 2007-10-10 2006-11-10 2006-12-10 4
12 2007-10-10 2006-11-10 2006-11-10 4
这是棘手的部分。我想让后续组的“end_date”成为前一组的“start_date”,并根据这一举动调整“start_date”,这意味着ID仍然具有相同的月数。我能够创建一个半功能解决方案:
df %>%
mutate(start_date = end_date %m-% months(11),
date = list(seq.Date(start_date, end_date, by = "month"))) %>%
unnest() %>%
arrange(desc(date)) %>%
mutate(ID = gl(ceiling(n()/3), 3, length = n())) %>%
group_by(ID) %>%
summarise(start_date = min(date),
end_date = max(date)) %>%
mutate(start_date = if_else(ID != 1, start_date %m+% months(row_number() - 1), start_date),
end_date = if_else(ID != 1, end_date %m+% months(row_number() - 1), end_date))
ID start_date end_date
<fct> <date> <date>
1 1 2007-08-10 2007-10-10
2 2 2007-06-10 2007-08-10
3 3 2007-04-10 2007-06-10
4 4 2007-02-10 2007-04-10
但是,问题在于它没有按组填充整个初始阶段(12 个月)。在到达原始“start_date”之前,可能会有更多 ID,即2006-11-10。
对于这个给定的示例,有第五个 ID (这也是所需的输出):
ID start_date end_date
1 1 2007-08-10 2007-10-10
2 2 2007-06-10 2007-08-10
3 3 2007-04-10 2007-06-10
4 4 2007-02-10 2007-04-10
5 5 2006-12-10 2007-02-10
因此,我的问题是,是否有可能通过上述逻辑填充给定时间段?
【问题讨论】:
标签: r datetime dplyr lubridate