2017-07-29 108 views
2

我有一个定期的5分钟日期时间数据集(约50)。 POSIXt/ lubridate函数很好地将我的日期时间转换为24小时格式。但我想在我的一天的定义中添加另一列,从早上6点到早上6点(现在是午夜到午夜)。我试图在12AM活动之后捕获,作为当前日期的一部分,而不是下一个日期。R日期/日期操作

我目前正在尝试每288行创建一个组(每天有288个5分钟的时间间隔)。但是它造成了一个问题,因为我的数据集不一定在独特的时间开始。

我不想创建偏移量,因为它会篡改对应于时间的值。

解决此问题的任何有效方法?谢谢。

+0

不确定你的意思是“我不想创建偏移量”。这是否适合您的需求? '库(tidyverse); seq(as.POSIXct(Sys.time()),by =“5 min”,length.out = 50 * 288)%>%as_data_frame()%>% mutate(my_day = as.Date(value-as。 difftime(6,units =“hours”)))' – dmi3kno

回答

1

可以有效地通过首先产生一个seq uence的日期/时间,然后用cut在其中找到每个值落在垃圾桶做到这一点:

set.seed(2) 
dat <- Sys.time() + sort(runif(10, min=0, max=5*24*60*60)) 
dat 
# [1] "2017-07-29 15:43:10 PDT" "2017-07-29 20:23:12 PDT" "2017-07-29 22:24:22 PDT" "2017-07-31 08:22:57 PDT" 
# [5] "2017-07-31 18:13:06 PDT" "2017-07-31 21:01:10 PDT" "2017-08-01 12:30:19 PDT" "2017-08-02 04:14:03 PDT" 
# [9] "2017-08-02 17:26:14 PDT" "2017-08-02 17:28:52 PDT" 
sixs <- seq(as.POSIXct("2017-07-29 06:00:00", tz = "UTC"), as.POSIXct("2017-08-03 06:00:00", tz = "UTC"), by = "day") 
sixs 
# [1] "2017-07-29 06:00:00 UTC" "2017-07-30 06:00:00 UTC" "2017-07-31 06:00:00 UTC" "2017-08-01 06:00:00 UTC" 
# [5] "2017-08-02 06:00:00 UTC" "2017-08-03 06:00:00 UTC" 
cut(dat, sixs, label = FALSE) 
# [1] 1 1 1 3 3 3 4 5 5 5 

根据帮助页面(?seq.POSIXt),你可以选择by="DSTday"

1

由于我不能评论(声誉问题,这里新的joinee),我发布这个答案。
结算这个问题和相应的答案:How to manipulate the time part of a date column?

它说明了一个更强大的解决方案,因为它是独立于您的数据结构(如重复)。

继@meenaparam的解决方案:

转换所有日期列dmy_hms格式从lubridate包。请根据您的具体需求,探索其他选项,如dmy_hmymd_hms等。

mutate(DATE = dmy_hms(DATE)) 

现在创建一个列来标识需要以不同方式修改的数据点。就像你的数据点00:00:00至05:59:59(hms)需要成为上一个日期的一部分。

DAY_PAST = case_when(hour(DATE) < 6 ~ "yup", TRUE ~ "nope")) 

现在这些"yup"日期的day值转换为day(DATE)-1

NEW_DATE = case_when(DAY_PAST == "yup" 
     ~ make_datetime(year(DATE-86400), month(DATE-86400), day = day(DATE-86400), hour = hour(DATE)), 
     TRUE ~ DATE) 

希望这能解决你的问题。

+0

谢谢,令人惊叹! –

+0

它会为月份开始输入创建“NA”结果,我更新了代码。如果它适合你,请接受我的答案。这将是我第一个接受的答案。 :) – Arani