如果日期时间是午夜00:00:00,请更改为第二天

时间:2019-07-30 13:00:20

标签: r time time-series

我正在建立一个大型数据集以进行时间序列分析。数据具有日期开始时间和日期结束时间。

数据在结束时间输入为24:00:00,我现在将其转换为00:00:00。我想将所有在00:00:00完成的结束数据向前移动一天。

#Current database
id<-c("m1","m1","m1","m2","m2","m2","m3","m4","m4")
x<-c("2020-01-03 10:00:00","2020-01-03 16:00:00","2020-01-03 
19:20:00","2020-01-05 10:00:00","2020-01-05 15:20:00","2020-01-05 
20:50:00","2020-01-06 06:30:00","2020-01-08 06:30:00","2020-01-08 
07:50:00")
start<-strptime(x,"%Y-%m-%d %H:%M:%S")
y<-c("2020-01-03 16:00:00","2020-01-03 19:20:00","2020-01-03 
00:00:00","2020-01-05 15:20:00","2020-01-05 20:50:00","2020-01-05 
00:00:00","2020-01-06 07:40:00","2020-01-08 07:50:00","2020-01-08 
08:55:00")
end<-strptime(y,"%Y-%m-%d %H:%M:%S")
mydata<-data.frame(id,start,end)

#Output
id2<-c("m1","m1","m1","m2","m2","m2","m3","m4","m4")
x2<-c("2020-01-03 10:00:00","2020-01-03 16:00:00","2020-01-03 
19:20:00","2020-01-05 10:00:00","2020-01-05 15:20:00","2020-01-05 
20:50:00","2020-01-06 06:30:00","2020-01-08 06:30:00","2020-01-08 
07:50:00")
start2<-strptime(x2,"%Y-%m-%d %H:%M:%S")
y2<-c("2020-01-03 16:00:00","2020-01-03 19:20:00","2020-01-04 
00:00:00","2020-01-05 15:20:00","2020-01-05 20:50:00","2020-01-06 
00:00:00","2020-01-06 07:40:00","2020-01-08 07:50:00","2020-01-08 
08:55:00")
end2<-strptime(y2,"%Y-%m-%d %H:%M:%S")
mydata2<-data.frame(id2,start2,end2)

我希望第3行和第6行的输出将日期提前一天。是“ if”功能还是有更简单的方法?

3 个答案:

答案 0 :(得分:3)

if似乎很简单。 ifelse已向量化:

library(lubridate)
mydata$end2 = as_datetime(ifelse(format(mydata$end, "%H:%M:%S") == "00:00:00", mydata$end + days(1), mydata$end), tz = Sys.timezone())
mydata
#   id               start                 end                end2
# 1 m1 2020-01-03 10:00:00 2020-01-03 16:00:00 2020-01-03 16:00:00
# 2 m1 2020-01-03 16:00:00 2020-01-03 19:20:00 2020-01-03 19:20:00
# 3 m1 2020-01-03 19:20:00 2020-01-03 00:00:00 2020-01-04 00:00:00
# 4 m2 2020-01-05 10:00:00 2020-01-05 15:20:00 2020-01-05 15:20:00
# 5 m2 2020-01-05 15:20:00 2020-01-05 20:50:00 2020-01-05 20:50:00
# 6 m2 2020-01-05 20:50:00 2020-01-05 00:00:00 2020-01-06 00:00:00
# 7 m3 2020-01-06 06:30:00 2020-01-06 07:40:00 2020-01-06 07:40:00
# 8 m4 2020-01-08 06:30:00 2020-01-08 07:50:00 2020-01-08 07:50:00
# 9 m4 2020-01-08 07:50:00 2020-01-08 08:55:00 2020-01-08 08:55:00

答案 1 :(得分:2)

当您要求“更简单的方法”:lubridate软件包会自动为您执行此操作(即使在24:00:00时也是如此)。如果您不熟悉它,请在RStudio网站上查看此cheatsheet

以00:00:00结尾的日期时间将保留在同一天,以24:00:00结尾的日期时间将向前偏移一天。一些例子:

library(lubridate)

ymd_hms("2019-07-30 00:00:00")
[1] "2019-07-30 UTC"

ymd_hms("2019-07-30 24:00:00")
[1] "2019-07-31 UTC"

ymd_hms("2019-07-30 24:01:05")
[1] "2019-07-31 00:01:05 UTC"

我真的建议使用此程序包,因为它可以减少麻烦的日期时间。在性能一致性与性能之间有一个小的取舍,但我认为在大多数情况下这不是问题。

答案 2 :(得分:1)

如果数据在POSIXct中,则添加86400相当于添加一天。除了使用if语句,还可以将其向量化。

library(lubridate)
my_hours <- rep(0, nrow(mydata))
my_hours[which(hour(mydata$end)==0)] <- 86400
my_hours <- which(hour(mydata$end) == 0)
mydata$end <- mydata$end + my_hours

mydata$end == mydata2$end2
[1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
相关问题