如何减去年份?
Posted
技术标签:
【中文标题】如何减去年份?【英文标题】:How to subtract years? 【发布时间】:2011-03-19 18:48:44 【问题描述】:我在 R 中有一个日期,例如:
dt = as.Date('2010/03/17')
我想从这个日期减去 2 年,不用担心闰年和此类问题,得到as.Date('2010-03-17')
。
我该怎么做?
【问题讨论】:
【参考方案1】:这种方式似乎也能胜任
dt = as.Date("2010/03/17")
dt-365*2
[1] "2008-03-17"
as.Date("2008/02/29")-365*2
## [1] "2006-03-01"
【讨论】:
【参考方案2】:如果要考虑闰日,那么我建议使用此 lubridate 函数减去月份,因为其他方法将返回 3 月 1 日或 NA:
> library(lubridate)
> dt %m-% months(12*2)
[1] "2008-03-17"
# Try with leap day
> leapdt <- as.Date('2016/02/29')
> leapdt %m-% months(12*2)
[1] "2014-02-28"
【讨论】:
2 月 28 日还是 3 月 1 日是约定俗成的问题。NA
显然是不可接受的,我同意。感谢您添加信息。【参考方案3】:
与 rcs 的答案相同,但可以对向量进行操作(回答 MichaelChirico,我无法评论我没有足够的代表):
R> unlist(lapply(c("2015-12-01", "2016-12-01"),
function(x) return(as.character(seq(as.Date(x), length=2, by="-1 years")[2])) ))
[1] "2014-12-01" "2015-12-01"
【讨论】:
【参考方案4】:与lubridate
library(lubridate)
ymd("2010/03/17") - years(2)
【讨论】:
这对于闰年不起作用:ymd("2016/02/29") - years(2)
返回 NA。使用%m-% months(24)
返回"2014-02-28"
。为了更加确定,%m-% months(48)
返回"2012-02-29"
。
这是来自 lubridate 的预期行为。润滑的文档明确指出:考虑一个简单的操作,1 月 31 日 + 一个月。答案应该是:* 2 月 31 日(不存在)* 3 月 4 日(1 月 31 日之后的 31 天),或 * 2 月 28 日(假设它不是闰年)算术的基本属性是 a + b - b =一个。只有解决方案 1 遵守此属性,但它是无效日期...如果添加或减去一个月或一年会创建无效日期,lubridate 将返回一个 NA。【参考方案5】:
你可以使用seq
:
R> dt = as.Date('2010/03/17')
R> seq(dt, length=2, by="-2 years")[2]
[1] "2008-03-17"
【讨论】:
没有办法将其应用于日期列表,除非我缺少一个简单的扩展 seq.Date 也是可能的。 seq.Date(as.Date('2010/03/17'),length.out=2,by='-1 年')[2] @JerryTseq.Date
是使用seq
时调度的S3方法
如果您不介意,我发现选择“2”会混淆它查看此解决方案的条款。对于像我这样“挣扎”的其他人,我认为以下内容要清楚得多:x <- 2
seq(Sys.Date(), length=2, by=paste0("-", x, " years"))[2]
。您可以将 x 更改为其他间隔(3、4 等),这就是变量 - 其他“2”是“固定的......我相信按照@MichaelChirico 的要求应用这个列表会很容易跨度>
【参考方案6】:
最简单的做法是将其转换为 POSIXlt 并从年份槽中减去 2。
> d <- as.POSIXlt(as.Date('2010/03/17'))
> d$year <- d$year-2
> as.Date(d)
[1] "2008-03-17"
请参阅此相关问题:How to subtract days in R?。
【讨论】:
rcs 下面的答案更可取——我们确实有difftime
运算符。
使用 difftime,我不认为你可以做几年,几天或几周。
在 2 月 29 日的情况下要小心,因为生成的对象可能有 wday/mon/mday 插槽不正确!尝试:d=as.POSIXlt('2016-02-29',tz='GMT');d$year=d$year - 1
并检查 d$wday,d$mon,d$mday
的值以上是关于如何减去年份?的主要内容,如果未能解决你的问题,请参考以下文章
如何从 Java 8 Date API 中的回历日期中减去回历年份