在下面的代码中,我试图完成一个日期序列。我的开始日期是 5 月 31 日,结束日期是 8 月 31 日。当我seq()
按下面的月份排序时,您会看到跳过了 2023 年 6 月,但 2023 年 7 月出现了两次(该月的第一天和最后一天)。我想按月份排序,这样每个月都会出现在两个日期之间的序列中。我该如何实现呢?
library(tidyverse)
df1 <- data.frame(id = "1",
startdate = as.Date( "2023-05-31"),
enddate = as.Date("2024-08-31")) %>%
mutate(date_duration = startdate,
enddate = ceiling_date(enddate, "month") -1 ) %>%
complete(date_duration = seq(startdate, enddate, by = "month"))
编辑第二个例子
使用下面 Jon 发布的代码,它适用于我的第一个示例。但是,如果开始日期从每月的第一天开始,我会再次得到重复的月份。可以解决这个问题吗?
df1 <- data.frame(id = c("1","2"),
startdate = as.Date( c("2023-05-31", "2023-01-01")),
enddate = as.Date(c("2024-08-31", "2023-03-15")),
date_duration = as.Date( c("2023-05-31", "2023-01-01"))
) %>%
group_by(id) %>%
complete(date_duration = seq(ceiling_date(startdate, "month"),
ceiling_date(enddate, "month"),
by = "month") - 1)
这是基本函数的不足之处
seq.Date
,它无法像您预期的那样在月份的最后几天工作。(我认为这是因为月份的长度不同,因此用户想要什么以及如何简单地实现这一点并不明确。实际上,它假定您正在寻找 31 日所在的日期(如果存在的话),因此下面显示 2024-07-01,而您预期的是 2024-06-30。)不过,它会按照您预期的方式在每月的第一天工作,因此您可以像这样进行修改:
您可以考虑使用下面这样的代码,四舍五入到下个月(按您预期的顺序排列),然后您可以回溯一天。这解决了您可能提供 2024-02-28 的情况,虽然它不是该月的最后一天,但可能是用户期望它提供的情况。
我还添加了
id
、startdate
和 ,enddate
因为它们存在于您的数据中。不确定您是否想要这样做,但我觉得这很有用。结果
编辑:
或者,如果我们只想要“每月一行”,我们可以先 floor_date 定义列,如下所示:(不太准确,因为我不知道需要保留哪些行的原始形式)