使用strftime从Posixct对象中提取日期和小时

时间:2016-11-19 22:31:41

标签: r date datetime sapply strftime

我试图使用strftime从日期时间列中提取日期和小时但我不明白为什么返回的值比应返回的值早1小时。例如,对于2013-01-01 00:00:00的日期时间,返回的值应该是2013-01-01 00,而是我得到的是2012-12-31 23.我也尝试添加1小时和然后提取但是在很长的日期序列中,它再次扰乱了输出。请参阅此示例代码以供参考。

## creating the sequence of time steps for cleaned
start <- as.POSIXct('2013-01-01 00:00:00',tz='EST')
end <- as.POSIXct('2016-06-06 23:00:00',tz='EST')

timesteps = data.frame( seq.POSIXt(from = start, to =end , by = "5 min"))
colnames(timesteps) = "Time Index"

dateandhour = function (timeindex){
return(strftime(timeindex, format = "%Y-%m-%d %H"))
}

timesteps ['Date and Hour'] = sapply(timesteps$`Time Index`, dateandhour)

请让我知道我在这里失踪的是什么。非常感谢你。

2 个答案:

答案 0 :(得分:2)

那是因为您在as.POSIXct中指定了时区,但未在strptime中指定时区。

timesteps[1,1]
[1] "2013-01-01 EST"

 strftime(timesteps[1,1], format = "%Y-%m-%d %H")
[1] "2012-12-31 21"
 strftime(timesteps[1,1], format = "%Y-%m-%d %H",tz='EST')
[1] "2013-01-01 00"`

dateandhour = function (timeindex){
  return(strftime(timeindex, format = "%Y-%m-%d %H",tz='EST'))
}

timesteps ['Date and Hour'] = sapply(timesteps$`Time Index`, dateandhour)

head(timesteps)
           Time Index Date and Hour
1 2013-01-01 00:00:00 2013-01-01 00
2 2013-01-01 00:05:00 2013-01-01 00
3 2013-01-01 00:10:00 2013-01-01 00
4 2013-01-01 00:15:00 2013-01-01 00
5 2013-01-01 00:20:00 2013-01-01 00
6 2013-01-01 00:25:00 2013-01-01 00

答案 1 :(得分:1)

以下是两行答案:

创建序列

df <- data.frame(TimeIndex = 
         seq(anytime("2013-01-01 00:00:00"), 
             anytime("2016-06-06 23:00:00"), by="5 min"))

这创造了361k观测值:

R> dim(df)
[1] 360841      1
R> 

转换为日期和小时

您可以在一个操作中执行此操作,因为R是矢量化的:

df$DateAndHour <- strftime(df$TimeIndex, "%Y-%m-%d %H")

我们可以查看:

R> head(df, 10)
             TimeIndex   DateAndHour
1  2013-01-01 00:00:00 2013-01-01 00
2  2013-01-01 00:05:00 2013-01-01 00
3  2013-01-01 00:10:00 2013-01-01 00
4  2013-01-01 00:15:00 2013-01-01 00
5  2013-01-01 00:20:00 2013-01-01 00
6  2013-01-01 00:25:00 2013-01-01 00
7  2013-01-01 00:30:00 2013-01-01 00
8  2013-01-01 00:35:00 2013-01-01 00
9  2013-01-01 00:40:00 2013-01-01 00
10 2013-01-01 00:45:00 2013-01-01 00
R> 

我使用上面的anytime因为我发现它紧凑而方便 - 不需要格式。我们也可以使用as.POSIXct()strptime()

我也省略了tz参数,以便所有内容都在我当地的时区。您可以在每次调用anytime()strftime()时设置它,也可以设置TZ环境变量。

编辑:当OP询问性能时,这是一个快速比较。我需要稍微改变一下解决方案:

df <- data.frame(TimeIndex = seq(anytime("2013-01-01 00:00:00"),
                                 anytime("2016-06-06 23:00:00"), by="5 min"))

dateandhour <- function (timeindex) {
    return(strftime(timeindex, format = "%Y-%m-%d %H"))
}

f1 <- function(df) { data.frame(TimeIndex=df, DateAndHour=sapply(df, dateandhour)) }
f2 <- function(df) { data.frame(TimeIndex=df, DateAndHour=strftime(df$TimeIndex, "%Y-%m-%d %H")) }

library(rbenchmark)

benchmark(f1(df), f2(df), replications=10)[,1:4]

我得到了这个:

R> benchmark(f1(df), f2(df), replications=10)[,1:4]
    test replications elapsed relative
1 f1(df)           10   7.101     2.08
2 f2(df)           10   3.414     1.00
R> 

大约提高了两倍。