【问题标题】:Formatting 24-hour time variable to capture observations in different ranges格式化 24 小时时间变量以捕获不同范围内的观察结果
【发布时间】:2026-01-05 12:15:02
【问题描述】:

我目前有一个包含 Start.Time 列的数据框(从 *.csv 文件导入),格式为 24 小时格式(例如,20:00:00 等于晚上 8 点)。我的目标是在不同的时间间隔(例如,在 9:00:00 到 10:00:00 之间)捕获具有开始时间的观察结果,这也符合其他标准。然而,似乎 R 对这个“字符”变量进行排序的方式与我们一天的生活方式不一致(例如,14:00:00 被认为是低于 9:00:00 的值)。

例如,下面是一行按预期工作的代码,我在其中捕获了两个不同路径段的观察结果,它们的开始时间在 8:00:00 和 9:00:00 之间。

RLLtoMist8.9<-sum((dataset1$Trail.Segment==52|dataset1$Trail.Segment==55) & 
                     (dataset1$Start.Time>="8:00" & dataset1$Start.Time < "9:00"),
                  na.rm=TRUE)
RLLtoMist8.9

但是,下面的代码不能按预期工作,因为 R 将 9:00:00 '评估'为大于 10:00:00。

RLLtoMist9.10 <-
       sum((dataset1$Trail.Segment==52|dataset1$Trail.Segment==55) & 
           (dataset1$Start.Time>="9:00:00 AM" & dataset1$Start.Time < "10:00:00 AM"),
            na.rm=TRUE)

【问题讨论】:

标签: r dataframe datetime


【解决方案1】:

当然,字符类型是按“14:00”小于“9:00”的方式排序的。然而,R 有一个 datetime 类,一旦字符表示被解析,它就会正确地对时间进行排序。

a <- as.POSIXct("14:00", format="%H:%M")
b <- as.POSIXct("8:00", format="%H:%M")
# test
> a < b
[1] FALSE

您可以使用以下方法转换整个列:

dataset1$Start.Time <- as.POSIXct(dataset1$Start.Time,  format="%H:%M")

a 和 b 的日期是转换时的系统日期,因此如果您打印它们,您会看到默认格式的日期和时间。有一些包,比如chron,可以让你只使用时间,但是 POSIXt 对象必须有日期和时间。见?DateTimeClasseslubridate 包也有一个“间隔”类,并且在 base-R 中存在一个 difftime 函数。

还有seq.POSIXtcut.POSIXt 函数,它们中的任何一个都可用于为日期时间的分类转换创建多个时间或日期边界。

【讨论】:

    【解决方案2】:

    使用 data.table 库:

    # convert to data table 
    dataset1<-data.table(dataset1)
    
    # format to a date format rather that character
    dataset1[, Start.Time := as.POSIXct(Start.Time, format="%H:%M:%S")]
    
    #now do your filtering
    dataset1[between(Start.Time, as.POSIXct("09:00:00", format="%H:%M:%S"), as.POSIXct("10:00:00", format="%H:%M:%S")) & (Trail.Segment==52 | Trail.Segment==55)]
    

    【讨论】:

      最近更新 更多