R中如何对HH:MM AM/PM格式的dataframe时间列排序
R中按12小时制时间列排序DataFrame的实现方法
完全可以借助dplyr/tidyverse实现该需求,以下提供两种符合要求的实现方案,均满足12:00AM为日起点的排序规则,排序后首值为03:10 AM、末值为10:10 PM。
方案1:解析为时间类型排序(推荐,容错率高)
使用tidyverse生态中专门处理时间的lubridate包直接解析12小时制时间字符串,无需拼接完整日期,代码简洁不易出错:
library(tidyverse) library(lubridate) zed_sorted <- zed %>% arrange(parse_date_time(start_time, orders = "%I:%M %p"))
参数说明:%I匹配12小时制小时,%M匹配分钟,%p匹配AM/PM时段,解析后的时间天然以12:00AM为每日起点,直接排序即可得到正确结果。
方案2:构造辅助整数列排序(无需转换时间类型)
如果不想做时间类型转换,可以通过字符串拆分把时间换算为「从0点开始累计的分钟数」作为排序依据,纯tidyverse函数即可实现。
排序核心逻辑是把12小时制时间换算为可直接比较大小的数值,规则如下:
- 拆分出时段(AM/PM)、小时、分钟三个字段
- 12AM的小时记为0,其余AM时段小时保留原值
- 12PM的小时记为12,其余PM时段小时在原值基础上加12
- 计算总累计分钟数 = 换算后小时 * 60 + 分钟,按该值升序排列即可
对应实现代码:
zed_sorted <- zed %>% mutate( # 从字符串中拆分时段、小时、分钟 period = str_sub(start_time, -2), hour_raw = as.numeric(str_sub(start_time, 1, 2)), minute = as.numeric(str_sub(start_time, 4, 5)), # 换算为24小时制小时 hour_24 = case_when( period == "AM" & hour_raw == 12 ~ 0, period == "AM" ~ hour_raw, period == "PM" & hour_raw == 12 ~ 12, period == "PM" ~ hour_raw + 12 ), # 计算当日累计分钟数作为排序键 time_rank = hour_24 * 60 + minute ) %>% arrange(time_rank) %>% # 排序完成后移除临时辅助列 select(-c(period, hour_raw, minute, hour_24, time_rank))
两种方案输出结果完全一致,可根据自己的使用习惯选择。
内容的提问来源于stack exchange,提问作者Canovice
相关产品推荐
相关产品推荐

