如何在日期上使用剪切功能
Posted
技术标签:
【中文标题】如何在日期上使用剪切功能【英文标题】:How to use cut function on dates 【发布时间】:2022-01-03 17:35:03 【问题描述】:我有以下两个日期:
dates <- c("2019-02-01", "2019-06-30")
我想从以上两个日期创建以下垃圾箱:
2019-05-30, 2019-04-30, 2019-03-31, 2019-02-28
我使用了cut函数和seq,
dt <- as.Date(dates)
cut(seq(dt[1], dt[2], by = "month"), "month")
但这不会产生正确的结果。
您能否介绍一下在日期上使用 cut 功能?
【问题讨论】:
?cut.Date
会有所帮助。
lubridate 有一个功能回滚,它将日期转换为上个月的最后一个日期。 rollback(seq(dt[1], dt[2], by = "month"))[-1]
这将产生以下输出 [1] "2019-02-28" "2019-03-31" "2019-04-30" "2019-05-31"
您也可以使用 sort
函数按降序获取输出
【参考方案1】:
我们假设需要的是介于但不包括 dates
中的两个日期之间的所有月末。在问题中 dates[1] 是月初, dates[2] 是月底,但我们不假设如果我们这样做可能会简化。我们在下面生成了降序系列,但通常在 R 中使用升序。
下面的第一种方法使用每月序列和切割,下面的第二种方法使用每日序列。
没有使用任何包。
1) 我们定义了第一个月份的函数,fom,它给定一个日期或字符日期,使用 cut 给出月份的第一个日期。然后我们计算两个日期的第一个月份之间的每月日期,将其转换为月末,然后删除不严格位于日期中的日期之间的任何日期。
fom <- function(x) as.Date(cut(as.Date(x), "month"))
s <- seq(fom(dates[2]), fom(dates[1]), "-1 month")
ss <- fom(fom(s) + 32) - 1
ss[ss > dates[1] & ss < dates[2]]
## [1] "2019-05-31" "2019-04-30" "2019-03-31" "2019-02-28"
2) 另一种方法是在转换为 Date 类后计算两个日期元素之间的每日序列,然后仅保留第二天具有不同月份且在日期之间的那些在日期。这不使用剪切。
dt <- as.Date(dates)
s <- seq(dt[2], dt[1], "-1 day")
s[as.POSIXlt(s)$mon != as.POSIXlt(s+1)$mon & s > dt[1] & s < dt[2]]
## [1] "2019-05-31" "2019-04-30" "2019-03-31" "2019-02-28"
【讨论】:
这就是我想要的,谢谢你的精彩解释。请解释为什么在此代码fom(fom(s) + 32) - 1
中添加+32?
fom(s) 给出月初,加上 32 给出下个月的日期,然后 fom of that 给出该月的第一天。最后减去 1 得到 s 的最后一天。
如果加上 32 给出一个 2 个月后的日期会发生什么,例如如果你从 1 月 31 日开始?
这就是为什么我们在添加 32 之前取月初的原因。【参考方案2】:
这里不需要删减:
library(lubridate)
dates <- c("2019-02-01", "2019-06-30")
seq(min(ymd(dates)), max(ymd(dates)), by = "months") - 1
#> [1] "2019-01-31" "2019-02-28" "2019-03-31" "2019-04-30" "2019-05-31"
由reprex package (v2.0.1) 于 2021 年 11 月 25 日创建
【讨论】:
以上是关于如何在日期上使用剪切功能的主要内容,如果未能解决你的问题,请参考以下文章
devexpress gridview 中选择多行 剪切,粘帖功能怎么做?