我试图从日期中减去 n 个月,如下所示:
maturity <- as.Date("2012/12/31")
m <- as.POSIXlt(maturity)
m$mon <- m$mon - 6
但结果日期为01-Jul-2012
,而不是30-Jun-2012
,正如我所料。
有没有简短的方法来获得这样的结果?
提前致谢
答案 0 :(得分:70)
1) seq.Date 。请注意,六月只有30天,所以它不能给6月31日,而是它给7月1日。
seq(as.Date("2012/12/31"), length = 2, by = "-6 months")[2]
## [1] "2012-07-01"
如果我们知道它是在月底,我们可以这样做:
seq(as.Date(cut(as.Date("2012/12/31"), "month")), length=2, by="-5 month")[2]-1
## "2012-06-30"
2) yearmon 。此外,如果我们知道它是月末,那么我们可以像这样使用动物园包的"yearmon"
类:
ibrary(zoo)
as.Date(as.yearmon(as.Date("2012/12/31")) -.5, frac = 1)
## [1] "2012-06-30"
这会将日期转换为"yearmon"
减去6个月(一年的.5),然后使用"Date"
将其转换回frac=1
,这意味着月末({{ 1}}意味着月初)。与以前的解决方案相比,它也具有自动向量化的优势,即frac=0
可能是日期的向量。
请注意,如果as.Date(...)
类仅用作表示月份的方式,那么我们可以完全摆脱它并直接使用"Date"
,因为它首先模拟了我们想要的东西:< / p>
"yearmon"
3) mondate 。第三种解决方案是mondate软件包,它的优势在于它在6个月前返回月末,而不必知道我们是月末:
as.yearmon("2012-12") - .5
## [1] "Jun 2012"
这也是矢量化的。
4) lubridate 。这个润滑的答案已根据包装中的变化而改变:
library(mondate)
mondate("2011/12/31") - 6
## mondate: timeunits="months"
## [1] 2011/06/30
lubridate也被矢量化。
5) sqldf / SQLite
library(lubridate)
as.Date("2012/12/31") %m-% months(6)
## [1] "2012-06-30"
或者如果我们知道我们在月末:
library(sqldf)
sqldf("select date('2012-12-31', '-6 months') as date")
## date
## 1 2012-07-01
答案 1 :(得分:4)
你可以使用lubridate包来实现这个
library(lubridate)
maturity <- maturity %m-% months(6)
没有理由改变日期字段。
您可以通过
将日期字段设置回该月的最后一天day(maturity) <- days_in_month(maturity)
祝你好运!!!
答案 2 :(得分:0)
从技术上讲,您不能在所有日期中添加/减去1个月(尽管您可以在所有日期中添加/减去30天,但是我想这不是您想要的)。我认为这就是您要寻找的
> lubridate::ceiling_date(as.Date("2020-01-31"), unit = "month")
[1] "2020-02-01"
> lubridate::floor_date(as.Date("2020-01-31"), unit = "month")
[1] "2020-01-01"
答案 3 :(得分:0)
lubridate
在以下计算中可以正常使用:
library(lubridate)
as.Date("2000-01-01") - days(1) # 1999-12-31
as.Date("2000-03-31") - months(1) # 2000-02-29
但有时会失败:
as.Date("2000-02-29") - years(1) # NA, should be 1999-02-28