在R语言中使用month.abb转换数字月份为缩写并按时间排序的问题
解决R语言中月份缩写按时间排序的分组聚合问题
问题根源
直接在group_by中使用month.abb[month]会将月份转换为普通字符型,字符默认按字母顺序排序,导致结果不符合时间顺序要求;而arrange报错是因为你尝试用原数据集的大向量(行数5667186)去匹配聚合后小数据集的行数,长度不匹配引发错误。
解决方案
方案1:先聚合,再转换月份缩写并排序
利用聚合后保留的数字月份做排序依据,转换为缩写后再调整列顺序:
# 先执行初始聚合代码 df_summary <- df %>% group_by(member_casual, month) %>% summarise(n = n(), avg_ride = mean(ride_duration)) %>% arrange(member_casual, month) # 转换为月份缩写并按时间顺序整理 df_summary %>% ungroup() %>% # 取消分组避免操作限制 mutate(month_name = month.abb[month]) %>% # 生成月份缩写 arrange(member_casual, month) %>% # 按数字月份保证时间顺序 select(member_casual, month_name, n, avg_ride) # 可选:调整列展示顺序
方案2:聚合前将月份转为有序因子
提前把月份设置为有序因子,指定顺序为month.abb的默认时间顺序,这样分组和排序都会遵循时间逻辑:
df %>% mutate( # 将数字月份转为有序因子,levels对应Jan-Dec的顺序 month = factor(month.abb[month], levels = month.abb, ordered = TRUE) ) %>% group_by(member_casual, month) %>% summarise(n = n(), avg_ride = mean(ride_duration)) %>% arrange(member_casual, month) # 此时按因子顺序排序,即时间顺序
针对你提供的聚合后数据集的验证示例
# 你的聚合后数据集 df_agg <- structure(list(member_casual = c("casual", "casual", "casual", "casual", "casual", "casual"), month = c(1, 2, 3, 4, 5, 6), n = c(18517L, 21414L, 89874L, 126398L, 280387L, 369022L), avg_ride = c(1822.94259329265, 1602.65671990287, 1957.52169704253, 1772.21198120223, 1852.36170721182, 1926.09143357307)), class = c("grouped_df", "tbl_df", "tbl", "data.frame"), row.names = c(NA, -6L), groups = structure(list(member_casual = "casual", .rows = structure(list(1:6), ptype = integer(0), class = c("vctrs_list_of", "vctrs_vctr", "list"))), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -1L), .drop = TRUE)) # 处理后输出按时间顺序的月份缩写结果 df_agg %>% ungroup() %>% mutate(month_name = month.abb[month]) %>% arrange(member_casual, month) %>% select(member_casual, month_name, n, avg_ride)
内容的提问来源于stack exchange,提问作者kulsumbi
相关产品推荐
相关产品推荐

