如何减去年份?

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] @JerryT seq.Date 是使用seq时调度的S3方法 如果您不介意,我发现选择“2”会混淆它查看此解决方案的条款。对于像我这样“挣扎”的其他人,我认为以下内容要清楚得多:x &lt;- 2seq(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 中的回历日期中减去回历年份

显示日期 - 长格式的三天减去 Freemarker 中的年份

arcgis如何把value值减去同样的数

从日期时间减去 1 年

C# - 获取两个日期然后只减去年份[重复]

excel如何通过身份证计算性别和年龄