POSIXct的seq()

时间:2012-01-19 10:03:39

标签: r date posixct

我的目标是在给定开始,结束和增量(15分钟,1小时,1天)的情况下创建POSIXct时间戳的向量。我希望我可以使用seq,但我在数字和POSIXct表示之间转换时遇到问题:

now <- Sys.time()
now
# [1] "2012-01-19 10:30:39 CET"
as.POSIXct(as.double(now), origin="1970-01-01", tz="CET")
# [1] "2012-01-19 09:30:39 CET"
as.POSIXct(as.double(now), origin=as.POSIXct("1970-01-01", tz="CET"), tz="CET")
# [1] "2012-01-19 09:30:39 CET"

转换过程中会丢失一小时。我做错了什么?

6 个答案:

答案 0 :(得分:22)

seq()的对象有"POSIXt"方法,它是"POSIXlt""POSIXct"类的超类。因此,您无需进行任何转换。

> now <- Sys.time()
> tseq <- seq(from = now, length.out = 100, by = "mins")
> length(tseq)
[1] 100
> head(tseq)
[1] "2012-01-19 10:52:38 GMT" "2012-01-19 10:53:38 GMT"
[3] "2012-01-19 10:54:38 GMT" "2012-01-19 10:55:38 GMT"
[5] "2012-01-19 10:56:38 GMT" "2012-01-19 10:57:38 GMT"

答案 1 :(得分:10)

你必须要知道,当从POSIXct转换为数字时,R会考虑时区,但总是从GMT原点开始计算:

> xgmt <- as.POSIXct('2011-01-01 14:00:00',tz='GMT')
> xest <- as.POSIXct('2011-01-01 14:00:00',tz='EST')
> (as.numeric(xgmt) - as.numeric(xest)) / 3600
[1] -5

如您所见,EST中的时间比GMT时间提前了五个小时,这是两个时区之间的时差。这是内部保存的值。

as.POSIXCT()函数只添加一个包含时区的属性。它不会改变值,所以你得到的时间是GMT时间,但是有一个属性告诉它是EST。这也意味着,一旦您从POSIXct转到数字,您应该将您的数据视为GMT时间。 (这比这复杂得多,但这是一般的想法)。所以你必须按如下方式计算偏移量:

> nest <- as.numeric(xest)
> origin <- as.POSIXct('1970-01-01 00:00:00',tz='EST')
> offset <- as.numeric(origin)
> as.POSIXct(nest-offset,origin=origin)
[1] "2011-01-01 14:00:00 EST"

无论您的语言环境中的时区是什么(在我的情况下,实际上都是CET)。另请注意,时区数据的行为可能因系统而异。

答案 2 :(得分:8)

这些时区问题总是很繁琐,但我认为问题是您的来源是在错误的时区计算的(因为字符串只指定了日期)。

尝试使用origin <- now - as.numeric(now)

或者,使用lubridate::origin,即字符串"1970-01-01 UTC"


完整的解决方案,再次使用lubridate

start <- now()
seq(start, start + days(3), by = "15 min")

答案 3 :(得分:4)

使用seq.POSIXt的替代方法是xts::timeBasedSeq,它允许您将序列指定为字符串:

library(xts)
now <- Sys.time()
timeBasedSeq(paste("2012-01-01/",format(now),"/H",sep=""))  # Hourly steps
timeBasedSeq(paste("2012-01-01/",format(now),"/d",sep=""))  # Daily steps

答案 4 :(得分:3)

我对你的问题没有答案,但我确实有另一种方法来创建POSIXct个对象的向量。例如,如果您想从现在开始创建一个1000个时间戳的向量,其中delta_t为15分钟:

now = Sys.time()
dt = 15 * 60 # in seconds
timestamps = now + seq(0, 1000) * dt
> head(timestamps)
[1] "2012-01-19 11:17:46 CET" "2012-01-19 11:32:46 CET"
[3] "2012-01-19 11:47:46 CET" "2012-01-19 12:02:46 CET"
[5] "2012-01-19 12:17:46 CET" "2012-01-19 12:32:46 CET"

技巧是你可以向POSIXct对象添加秒向量。

答案 5 :(得分:1)

您需要使用seq(from = start,to = end,by = step)。请注意,在步骤中,您可以使用“days”或一个整数来定义从一个项目到另一个项目的秒数。