如何按月分类日期
Posted
技术标签:
【中文标题】如何按月分类日期【英文标题】:How to bin date by month 【发布时间】:2022-01-03 11:48:10 【问题描述】:我有以下数据:
df <- data.frame(dt1 = c("2019-05-02", "2019-01-02", "2019-06-02"),
dt2 = c("2019-08-30", "2019-04-24", "2019-12-06") )
> df
dt1 dt2
1 2019-05-02 2019-08-30
2 2019-01-02 2019-04-24
3 2019-06-02 2019-12-06
这是我想做的:
i) 我想通过分箱来创建因子,例如,对于第一个日期,日期分箱为 2019 年 7 月 31 日、2019 年 6 月 30 日、2019 年 5 月 31 日,因此基本上按 dt2 分箱。 ii) 我想计算每个 bin 中的日期总数。
预期的输出是:
dt1 dt2 val_count
1 2019-05-02 2019-08-30 3
2 2019-01-02 2019-04-24 3
3 2019-06-02 2019-12-06 6
我发现这个post 相关。
注意:我不想计算两个日期的月份之间的差异。
感谢您的建议。
【问题讨论】:
【参考方案1】:这很混乱,但如果你想计算几个月的最后日期在dt1
和dt2
之间有多少个,你可以试试
library(lubridate)
library(dplyr)
fd <- paste0(lubridate::year(min(df$dt1, df$dt2)), "-02-01") %>% as.Date()
ld <- paste0(lubridate::year(max(df$dt1, df$dt2))+1, "-01-01") %>% as.Date()
x <- seq.Date(fd, ld, by = "month") - 1
df %>%
rowwise() %>%
mutate(val_count = length(x[dt1 < x & x < dt2]))
dt1 dt2 val_count
<chr> <chr> <int>
1 2019-05-02 2019-08-30 3
2 2019-01-02 2019-04-24 3
3 2019-06-02 2019-12-06 6
<
或 <=
的选择取决于您的目的。
要获得dt1
和dt2
之间的总天数,
df %>%
rowwise() %>%
mutate(val_count = length(x[dt1 < x & x < dt2])) %>%
mutate(dd = as.Date(dt2) - as.Date(dt1))
dt1 dt2 val_count dd
<chr> <chr> <int> <drtn>
1 2019-05-02 2019-08-30 3 120 days
2 2019-01-02 2019-04-24 3 112 days
3 2019-06-02 2019-12-06 6 187 days
添加
df %>%
rowwise() %>%
mutate(val_count = length(x[dt1 < x & x < dt2]),
val_count = ifelse(val_count == 0, 1, val_count)) %>%
mutate(dd = as.Date(dt2) - as.Date(dt1))
dt1 dt2 val_count dd
<chr> <chr> <dbl> <drtn>
1 2019-05-02 2019-08-30 3 120 days
2 2019-01-02 2019-04-24 3 112 days
3 2019-06-02 2019-12-06 6 187 days
4 2019-06-01 2019-06-02 1 1 days
【讨论】:
感谢您提供好的解决方案,您的代码运行良好。我想知道是否可以为日期在2019-06-02
和2019-06-03
之间的情况添加快速修复以避免输出零?
@Vendetta 对不起。我无法理解你想要的是什么......你能解释一下吗?
例如,有了这个数据df <- data.frame(dt1 = c("2019-05-02", "2019-01-02", "2019-06-02", "2019-06-01"), dt2 = c("2019-08-30", "2019-04-24", "2019-12-06", "2019-06-02") )
,我得到最后一行 val_count 为零。我想输出 1 而不是 0。
@Vendetta 我添加了上面的代码。请检查一下。【参考方案2】:
上面的解决方案确实有点乱,只需要一个简单的oneliner就可以了
df <- data.frame(dt1 = c("2019-05-02", "2019-01-02", "2019-06-02", "2019-06-01"), dt2 = c("2019-08-30", "2019-04-24", "2019-12-06", "2019-06-02") )
df %>%
mutate(val_count = as.period(ymd(dt2) - ymd(dt1)) %/% months(1))
# dt1 dt2 val_count
# 1 2019-05-02 2019-08-30 3
# 2 2019-01-02 2019-04-24 3
# 3 2019-06-02 2019-12-06 6
# 4 2019-06-01 2019-06-02 0
【讨论】:
以上是关于如何按月分类日期的主要内容,如果未能解决你的问题,请参考以下文章
mysql 如何按月分组查询出当前年度每个月的短信数量(数据库中这个月要是为空的话就用0条怎么显示出来)