如何减去年?

How to subtract years?

提问人:gt6989b 提问时间:7/23/2010 最后编辑:gt6989b 更新时间:8/19/2022 访问量:69127

问:

我在 R 中有一个日期,例如:

dt = as.Date('2010/03/17')

我想从这个日期减去 2 年,而不用担心闰年之类的问题,得到.as.Date('2008-03-17')

我该怎么做?

日期 date-arithmetic r-faq

评论


答:

58赞 Shane 7/23/2010 #1

最简单的方法是将其转换为 POSIXlt 并从年隙中减去 2。

> d <- as.POSIXlt(as.Date('2010/03/17'))
> d$year <- d$year-2
> as.Date(d)
[1] "2008-03-17"

请参阅此相关问题:如何在 R 中减去天数?

评论

1赞 Dirk is no longer here 7/24/2010
RCS 下面的答案更可取——我们确实有运营商。difftime
3赞 gt6989b 9/1/2010
有了difftime,我认为你不能做几年,只有几天或几周。
3赞 digEmAll 2/20/2018
在 2 月 29 日的情况下要小心,因为生成的对象可能会有 wday/mon/mday 插槽不正确!尝试 : 并检查d=as.POSIXlt('2016-02-29',tz='GMT');d$year=d$year - 1d$wday,d$mon,d$mday
31赞 rcs 7/23/2010 #2

您可以使用:seq

R> dt = as.Date('2010/03/17')
R> seq(dt, length=2, by="-2 years")[2]
[1] "2008-03-17"

评论

4赞 MichaelChirico 2/2/2015
但是,除非我缺少一个简单的扩展名,否则无法将其应用于日期列表
0赞 Jerry T 12/23/2019
序列。日期也是可能的。序列。日期(as.Date('2010/03/17'),length.out=2,by='-1 year')[2]
0赞 rcs 12/23/2019
@JerryT 是使用seq.Dateseq
0赞 tchevrier 11/17/2020
如果您不介意,我发现选择“2”会混淆查看此解决方案的术语。对于像我这样“挣扎”的人来说,我认为以下内容要清楚得多:。您可以更改其他间隔(3、4 等)的 x,这是变量 - 其他“2”是“固定的......我相信,按照@MichaelChirico的要求,应用这个清单就很容易了x <- 2seq(Sys.Date(), length=2, by=paste0("-", x, " years"))[2]
103赞 hadley 7/23/2010 #3

lubridate

library(lubridate)
ymd("2010/03/17") - years(2)

评论

5赞 user2105469 2/9/2018
对于闰年,这不会按预期工作:返回 NA。使用 returns。而且要更加确定,返回.ymd("2016/02/29") - years(2)%m-% months(24)"2014-02-28"%m-% months(48)"2012-02-29"
3赞 Patrick Conwell 5/1/2018
这是润滑剂的预期行为。润滑文档明确指出:考虑一个简单的操作,1 月 31 日 + 一个月。答案应该是: * 2 月 31 日(不存在)* 3 月 4 日(1 月 31 日之后的 31 天),或 * 2 月 28 日(假设它不是闰年) 算术的一个基本性质是 a + b - b = a。只有解决方案 1 遵循此属性,但它是无效的日期...如果添加或减去月份或年份导致日期无效,则 lubridate 将返回 NA。
3赞 Jean-Xavier Raynaud 1/4/2016 #4

与 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"
12赞 Hugo Silva 9/26/2016 #5

如果要考虑闰日,那么我建议使用此润滑函数来减去月份,因为其他方法将返回 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"

评论

1赞 gt6989b 9/27/2016
2 月 28 日还是 3 月 1 日是惯例问题。 显然是不可接受的,我同意。感谢您添加信息。NA
2赞 DJJ 11/22/2019 #6

这种方式似乎也可以完成这项工作

dt = as.Date("2010/03/17")
dt-365*2
[1] "2008-03-17"

as.Date("2008/02/29")-365*2
## [1] "2006-03-01"

评论

1赞 tommmm 3/9/2022
我担心由于闰年,这不会提供正确的日期
1赞 tommmm 3/9/2022 #7
cur_date <- str_split(as.character(Sys.Date()), pattern = "-")
cur_yr <- cur_date[[1]][1]
cur_month <- cur_date[[1]][2]
cur_day <- cur_date[[1]][3]
new_year <- as.integer(year) - 2
new_date <- paste(new_year, cur_month, cur_day, sep="-")
1赞 Luis Carmona Martinez 8/18/2022 #8

使用 Base R,您可以简单地使用以下内容,而无需安装任何软件包。

1) 将字符串转换为日期格式,在第二个参数中指定输入格式,以便 R 可以正确解释日期格式。

dt = as.Date('2010/03/17',"%Y/%m/%d")

注意:如果您现在查看您的环境选项卡,您会看到 dt 作为变量,其值为“2010-03-17”(年-月-日由“-”分隔,而不是由“/”分隔)

2)指定要减去多少年

years_substract=2

3) 将 paste() 与格式 () 结合使用,只保留月和日,只需从原始日期中减去 2 年。Format() 函数将使用格式第二个参数相应地保留日期的特定部分。

dt_substract_2years<-
as.Date(paste(as.numeric(format(dt,"%Y"))-years_substract,format(dt,"%m"),format(dt,"%d"),sep = "-"))

注1:我们使用paste()函数连接日期组件,并将分隔符指定为“-”(sep = “-”),默认为日期的R分隔符。

注2:我们还使用as.numeric()函数将年份从字符转换为数字

评论

0赞 gt6989b 8/19/2022
谢谢你的回答。这与@tommmm的答案有何本质区别?(同意有更多评论来解释发生了什么,+1)