Reputation: 2788
I would like to define the times at which a day starts and ends.
For example, lets assume that I don't want a new day to start until 10am the following day.
For sample data I have the following:
dt
1 2015-01-01 10:45:00
2 2015-01-01 11:30:00
3 2015-01-01 11:45:00
4 2015-01-01 12:00:00
5 2015-01-01 12:30:00
6 2015-01-01 13:00:00
7 2015-01-01 14:30:00
8 2015-01-01 15:00:00
9 2015-01-01 16:30:00
10 2015-01-01 16:45:00
11 2015-01-01 18:15:00
12 2015-01-01 18:45:00
13 2015-01-01 19:15:00
14 2015-01-01 21:45:00
15 2015-01-01 22:00:00
16 2015-01-01 23:00:00
17 2015-01-01 23:15:00
18 2015-01-02 00:00:00
19 2015-01-02 11:45:00
20 2015-01-02 17:00:00
21 2015-01-02 18:00:00
22 2015-01-02 19:15:00
23 2015-01-02 21:30:00
24 2015-01-02 21:45:00
25 2015-01-02 22:45:00
A dput()
of this data can be copied into R.
data <- structure(list(dt = structure(c(1420111800, 1420127100, 1420129800,
1420133400, 1420149600, 1420150500, 1420154100, 1420155900, 1420157700,
1420200000, 1420203600, 1420206300, 1420209000, 1420215300, 1420218000,
1420224300, 1420229700, 1420231500, 1420234200, 1420236900, 1420239600,
1420240500, 1420241400, 1420244100, 1420245900), class = c("POSIXct",
"POSIXt"), tzone = "UTC")), row.names = c(NA, -25L), class = "data.frame")
The only way I have calcualted the day of week in the past is with lubridate::wday
as follows
data %>%
mutate(dow = wday(dt, label = T))
dt dow
1 2015-01-01 11:30:00 Thu
2 2015-01-01 15:45:00 Thu
3 2015-01-01 16:30:00 Thu
4 2015-01-01 17:30:00 Thu
5 2015-01-01 22:00:00 Thu
6 2015-01-01 22:15:00 Thu
7 2015-01-01 23:15:00 Thu
8 2015-01-01 23:45:00 Thu
9 2015-01-02 00:15:00 Fri # make Thu
10 2015-01-02 12:00:00 Fri
11 2015-01-02 13:00:00 Fri
12 2015-01-02 13:45:00 Fri
13 2015-01-02 14:30:00 Fri
14 2015-01-02 16:15:00 Fri
15 2015-01-02 17:00:00 Fri
16 2015-01-02 18:45:00 Fri
17 2015-01-02 20:15:00 Fri
18 2015-01-02 20:45:00 Fri
19 2015-01-02 21:30:00 Fri
20 2015-01-02 22:15:00 Fri
21 2015-01-02 23:00:00 Fri
22 2015-01-02 23:15:00 Fri
23 2015-01-02 23:30:00 Fri
24 2015-01-03 00:15:00 Sat # make Fri
25 2015-01-03 00:45:00 Sat # make Fri
I marked the days that would be incorrect if assuming a new day does not start until 10am the next day.
I was curious what options are available for defining the times for which a new day starts/ends.
Upvotes: 1
Views: 121
Reputation: 669
Using base
data$dow <- with(data, ifelse(strftime(dt, "%H") < 11,
strftime(dt - as.difftime(1, units = "days"), "%a"),
strftime(dt, "%a")
)
)
Upvotes: 1
Reputation: 6769
I wonder if this will get you there:
data %>%
mutate(
dt1 = dt - hours(10),
dow = wday(dt1, label = T))
dt dt1 dow
1 2015-01-01 11:30:00 2015-01-01 01:30:00 Thu
2 2015-01-01 15:45:00 2015-01-01 05:45:00 Thu
3 2015-01-01 16:30:00 2015-01-01 06:30:00 Thu
4 2015-01-01 17:30:00 2015-01-01 07:30:00 Thu
5 2015-01-01 22:00:00 2015-01-01 12:00:00 Thu
6 2015-01-01 22:15:00 2015-01-01 12:15:00 Thu
7 2015-01-01 23:15:00 2015-01-01 13:15:00 Thu
8 2015-01-01 23:45:00 2015-01-01 13:45:00 Thu
9 2015-01-02 00:15:00 2015-01-01 14:15:00 Thu
10 2015-01-02 12:00:00 2015-01-02 02:00:00 Fri
11 2015-01-02 13:00:00 2015-01-02 03:00:00 Fri
12 2015-01-02 13:45:00 2015-01-02 03:45:00 Fri
13 2015-01-02 14:30:00 2015-01-02 04:30:00 Fri
14 2015-01-02 16:15:00 2015-01-02 06:15:00 Fri
15 2015-01-02 17:00:00 2015-01-02 07:00:00 Fri
16 2015-01-02 18:45:00 2015-01-02 08:45:00 Fri
17 2015-01-02 20:15:00 2015-01-02 10:15:00 Fri
18 2015-01-02 20:45:00 2015-01-02 10:45:00 Fri
19 2015-01-02 21:30:00 2015-01-02 11:30:00 Fri
20 2015-01-02 22:15:00 2015-01-02 12:15:00 Fri
21 2015-01-02 23:00:00 2015-01-02 13:00:00 Fri
22 2015-01-02 23:15:00 2015-01-02 13:15:00 Fri
23 2015-01-02 23:30:00 2015-01-02 13:30:00 Fri
24 2015-01-03 00:15:00 2015-01-02 14:15:00 Fri
25 2015-01-03 00:45:00 2015-01-02 14:45:00 Fri
Upvotes: 0
Reputation: 160607
Lacking timezone changes, I'd think your best bet is to if_else
off of the hour of the day, similar to what you're doing now:
library(dplyr)
library(lubridate)
data %>%
mutate(
dow = wday(dt, label = T),
dow2 = wday(dt - if_else(hour(dt) < 11, 86400, 0), label = TRUE)
)
# dt dow dow2
# 1 2015-01-01 11:30:00 Thu Thu
# 2 2015-01-01 15:45:00 Thu Thu
# 3 2015-01-01 16:30:00 Thu Thu
# 4 2015-01-01 17:30:00 Thu Thu
# 5 2015-01-01 22:00:00 Thu Thu
# 6 2015-01-01 22:15:00 Thu Thu
# 7 2015-01-01 23:15:00 Thu Thu
# 8 2015-01-01 23:45:00 Thu Thu
# 9 2015-01-02 00:15:00 Fri Thu
# 10 2015-01-02 12:00:00 Fri Fri
# 11 2015-01-02 13:00:00 Fri Fri
# 12 2015-01-02 13:45:00 Fri Fri
# 13 2015-01-02 14:30:00 Fri Fri
# 14 2015-01-02 16:15:00 Fri Fri
# 15 2015-01-02 17:00:00 Fri Fri
# 16 2015-01-02 18:45:00 Fri Fri
# 17 2015-01-02 20:15:00 Fri Fri
# 18 2015-01-02 20:45:00 Fri Fri
# 19 2015-01-02 21:30:00 Fri Fri
# 20 2015-01-02 22:15:00 Fri Fri
# 21 2015-01-02 23:00:00 Fri Fri
# 22 2015-01-02 23:15:00 Fri Fri
# 23 2015-01-02 23:30:00 Fri Fri
# 24 2015-01-03 00:15:00 Sat Fri
# 25 2015-01-03 00:45:00 Sat Fri
(This if_else
is rather trivial and can be shortened to wday(dt - 86400*(hour(dt) < 11), label = TRUE)
.)
Upvotes: 2