20

我的目标是创建一个给定开始、结束和增量(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"

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

4

6 回答 6

25

类的对象有一个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"
于 2012-01-19T10:53:00.457 回答
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数字转换为数字,您应该将您的数据视为格林威治标准时间。(这比这复杂得多,但这是一般的想法)。因此,您必须按如下方式计算偏移量:

> 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),这都有效。另请注意,时区数据的行为可能因系统而异。

于 2012-01-19T12:11:47.097 回答
8

这些时区问题总是很棘手,但我认为问题在于您的原点是在错误的时区计算的(因为字符串只指定了日期)。

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

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


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

start <- now()
seq(start, start + days(3), by = "15 min")
于 2012-01-19T10:45:50.207 回答
4

我没有你的问题的答案,但我确实有另一种创建POSIXct对象向量的方法。例如,如果您想从现在开始创建一个包含 1000 个时间戳的向量,其中 adelta_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对象添加秒向量。

于 2012-01-19T10:18:39.523 回答
4

使用seq.POSIXtis的替代方法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
于 2012-01-19T14:10:30.547 回答
1

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

于 2015-11-09T15:13:09.063 回答