从POSIXct对象中减去一年

时间:2014-12-18 15:40:18

标签: r date data.table

假设我们有这个日期" 2014-05-11 14:45:00 UTC"。我希望在此之前获得确切的POSIXct对象1年" 2013-05-11 14:45:00 UTC"。

我的第一个想法是创建一个全新的POSIXct对象,方法是从year位中减去一个并将其与字符串的其余部分一起粘贴,然后使用该字符串创建一个新的POSIXct对象:

time <- as.POSIXct("2014-05-11 14:45:00 UTC",tz="UTC",origin="1970-01-01")
newTime <- as.POSIXct(paste(as.character(as.numeric(substr(time,1,4)) - 1),substr(time,5,19),sep=""),tz="UTC",origin="1970-01-01")

这个工作正常(除了闰年!)但事情是我需要在每个行的大型data.table中执行此操作,并且最好将结果放回data.table中。 还有其他方法可以减去像这样的物体一年吗?

我还需要将其应用于data.table,如下所示:

          Time
 1: 1349206200
 2: 1349207100
 3: 1349208000
 4: 1349208900
 5: 1349209800
 6: 1349210700
 7: 1349211600
 8: 1349212500
 9: 1349213400
10: 1349214300
11: 1349215200

但是当我这样做时会发生这种情况:

SOdata[,Time:=as.numeric(as.POSIXct(paste(as.character(as.numeric(substr(Time,1,4)) - 1),substr(Time,5,19),sep=""),tz="UTC",origin="1970-01-01"))]
Error in as.POSIXlt.character(x, tz, ...) : 
  character string is not in a standard unambiguous format

我猜我需要使用类似lapply的东西,但是在使用该函数时我总是搞乱语法。那么有谁知道怎么做?

4 个答案:

答案 0 :(得分:9)

lubridate是你的朋友。

library(lubridate)
time <- as.POSIXct("2014-05-11 14:45:00 UTC",tz="UTC",origin="1970-01-01")
time-dyears(1)
#[1] "2013-05-11 14:45:00 UTC"
time+dyears(1)
#[1] "2015-05-11 14:45:00 UTC"

闰年

> x <- as.POSIXct(c("2012-02-28", "2012-02-29"), tz="UTC",origin="1970-01-01")
> x - dyears(1)
[1] "2011-02-28 UTC" "2011-03-01 UTC"

答案 1 :(得分:4)

可以使用

seq in base:

LastYr <- function(x) seq(x, length = 2, by = "-1 year")[2]
toPOSIXct <- function(x) as.POSIXct(x, origin = "1970-01-01")

# example 1

LastYr(as.POSIXct("2012-02-28"))
## [1] "2011-02-28 EST"

# example 2 - leap year

LastYr(as.POSIXct("2012-02-29"))
## [1] "2011-03-01 EST"

# example 3 - vector case

x <- as.POSIXct(c("2012-02-28", "2012-02-29")) # test data
toPOSIXct(sapply(x, LastYr))
## [1] "2011-02-28 EST" "2011-03-01 EST"

# example 4 - data.table shown in question

DT[, Time := sapply(toPOSIXct(Time), LastYr)]
使用函数LastYrtoPOSIXct简化

修订

答案 2 :(得分:4)

我还没有测试过其他答案,但无论闰年如何,以下内容都应该按要求运行:

time <- as.POSIXct("2014-05-11 14:45:00 UTC",tz="UTC",origin="1970-01-01")
time <- as.POSIXlt(time)
time$year <- time$year - 1
time <- as.POSIXct(time)
#[1] "2013-05-11 14:45:00 UTC"

以Gabor的闰年为例:

time <- as.POSIXct("2012-02-29 14:45:00 UTC",tz="UTC",origin="1970-01-01")
time <- as.POSIXlt(time)
time$year <- time$year - 1
time <- as.POSIXct(time)
#[1] "2011-03-01 14:45:00 UTC"

答案 3 :(得分:2)

或者您可以尝试,在基地R:

> time + as.difftime(52*7+1,units="days")
[1] "2015-05-11 14:45:00 UTC"

> time - as.difftime(52*7+1,units="days")
[1] "2013-05-11 14:45:00 UTC"

当然,如果单位可能多年就会更容易......