根据时间间隔的小时创建一天中的时间列类别

Posted

技术标签:

【中文标题】根据时间间隔的小时创建一天中的时间列类别【英文标题】:Create time of day column categories based on hour of time interval 【发布时间】:2022-01-22 23:58:38 【问题描述】:

我正在尝试创建一个“一天中的时间”列,在该列中我根据小时将一天中的时间分类为多个部分。例如,从 20:00 到 21:59 的任何时间都属于“20-22”类别。我计划在不同的时间间隔内多次执行此操作(例如,两小时间隔、3 小时间隔等)。但是,间隔并不总是从零开始。例如,3 小时间隔将为:“02-05”、“05-08”、“08-11”等。这使得很难定义如何切割数据以进行分类。

这是我的数据示例:

library(lubridate)
library(chron)

table <- "ID        date time
1 1 2016-04-30 21:00:00
2 2 2016-04-30 23:15:00
3 3 2016-04-30 19:30:00
4 4 2016-04-30 17:45:00
5 5 2016-04-30 14:00:00
6 6 2016-04-30 13:15:00
7 7 2016-04-30 05:30:00
8 8 2016-04-30 07:45:00
9 9 2016-04-30 09:00:00
10 10 2016-04-30 13:15:00
11 11 2016-04-30 10:30:00
12 12 2016-04-30 11:45:00
13 13 2016-05-01 12:00:00
14 14 2016-05-01 00:15:00
15 15 2016-05-01 01:30:00
16 16 2016-05-01 03:45:00
17 17 2016-05-01 04:00:00
18 18 2016-05-01 06:15:00
19 19 2016-05-01 19:30:00
20 20 2016-05-01 20:00:00"

# Create dataframe
df <- read.table(text=table, header = TRUE)

# Change time format
df$time <- times(df$time) 

# Add hour
df$hour <- hour(hms(df$time))
str(df)

我尝试了该站点的各种资源,但结果数据总是存在一些问题。以下是我尝试过的细分:

    下面的代码不起作用,因为任何属于小时的时间(例如,在这种情况下为 20:00:00)进入它之前的类别 (18-20) 而不是它应该在的类别 (20- 22)。此代码也不适用于 3 小时间隔。
breaks <- c(0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24) / 24
labels <- c("00-02", "02-04", "04-06", "06-08", "08-10", "10-12", "12-14", "14-16",
             "16-18", "18-20", "20-22", "22-00")
df$tod <- cut(df$time, breaks, labels, include.lowest = TRUE)

    此代码不起作用,因为它会导致某个类别的时间出现一些 NA 值(例如 23:15:00)。
breaks2 <- hour(hm("02:00", "04:00", "06:00", "08:00", "10:00", "12:00", "14:00", "16:00",
                   "18:00", "20:00", "22:00", "00:00", "01:59"))
labels2 <- c("22-00", "00-02", "02-04", "04-06", "06-08", "08-10", "10-12", "12-14", "14-16",
             "16-18", "18-20", "20-22")
df$tod2 <- cut(x=df$hour, breaks=breaks2, labels=labels2, include.lowest=TRUE)

任何帮助将不胜感激!

【问题讨论】:

@G.Grothendieck 我已将我在本次会议中使用的所有库添加到帖子中。 根据链接r,示例应该是最少的。省略发布代码中未使用的包的库语句。 【参考方案1】:

您的第一次尝试失败,因为您正在寻找right = FALSE 设置,而不是include.lowest,它只影响最低的bin。除以 24 时可能会遇到浮点精度问题,所以我认为直接剪切 hour 列是最简单的:

df$hour <- hour(hms(df$time))
hr_breaks = seq(0, 24, by = 2)
hr_labels <- c("00-02", "02-04", "04-06", "06-08", "08-10", "10-12", "12-14", "14-16",
             "16-18", "18-20", "20-22", "22-00")
df$tod = cut(df$hour, breaks = hr_breaks, 
             labels = hr_labels,
             include.lowest = T, right = F)
df
#    ID       date     time hour   tod
# 1   1 2016-04-30 21:00:00   21 20-22
# 2   2 2016-04-30 23:15:00   23 22-00
# 3   3 2016-04-30 19:30:00   19 18-20
# 4   4 2016-04-30 17:45:00   17 16-18
# 5   5 2016-04-30 14:00:00   14 12-14
# 6   6 2016-04-30 13:15:00   13 12-14
# 7   7 2016-04-30 05:30:00    5 04-06
# 8   8 2016-04-30 07:45:00    7 06-08
# 9   9 2016-04-30 09:00:00    9 08-10
# 10 10 2016-04-30 13:15:00   13 12-14
# 11 11 2016-04-30 10:30:00   10 08-10
# 12 12 2016-04-30 11:45:00   11 10-12
# 13 13 2016-05-01 12:00:00   12 10-12
# 14 14 2016-05-01 00:15:00    0 00-02
# 15 15 2016-05-01 01:30:00    1 00-02
# 16 16 2016-05-01 03:45:00    3 02-04
# 17 17 2016-05-01 04:00:00    4 02-04
# 18 18 2016-05-01 06:15:00    6 04-06
# 19 19 2016-05-01 19:30:00   19 18-20
# 20 20 2016-05-01 20:00:00   20 18-20

【讨论】:

根据我的定义,这确实适用于 2 小时的间隔,但我希望能够决定我将其分成的间隔。例如,对于 3 小时间隔,我不希望它从零开始:“02-05”、“05-08”、“08-11”、“11-14”、“14-17”、 “17-20”、“20-23”、“23-02”。有没有办法让我适应这个选择开始?我已编辑我的问题以包含此内容。 当然,3 小时的休息时间如评论中所述,您将使用 breaks_3 = c(-Inf, seq(2, 23, by = 3), Inf)labs_3 = c("02-05", "05-08", "08-11", "11-14", "14-17", "17-20", "20-23", "23-02", "02-05")。您可以对第一个和最后一个垃圾箱重复使用相同的标签,让它在午夜前后环绕。 不幸的是,这也不起作用,它将“00:00:00”时间归类为“02-05” 我能够将您的代码编辑为:(有效):c("23-02", "02-05", "05-08", "08-11", " 11-14"、"14-17"、"17-20"、"20-23"、"23-02") 太好了,就是这个主意!

以上是关于根据时间间隔的小时创建一天中的时间列类别的主要内容,如果未能解决你的问题,请参考以下文章

R:根据一天中的时间有效地对数据框进行子集化

有没有办法将 24 小时时间格式转换为一天的四个类别或四个象限?

DateTimePicker - 如何将时间间隔设置为 20 分钟、一周中允许的特定日期和一天中的时间?

python pandas 按一天中的小时求和

颤动本地通知“一天中的小时,以 24 小时制 [0..23] 表示。”

Crontab 在一天中的两个小时运行,但其中一个小时不包括一周中的某些天