You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在R的ggplot2中按日期对训练日志图表X轴排序?

解决R中训练日志可视化的日期排序问题

训练日志CSV包含Date、Activity、Duration三列,用ggplot绘制柱状图时,X轴日期无法按正确时间顺序排列(比如2/6、2/9排在2月其他日期之后),当前代码如下:

log <- read_csv("Training Log.csv")

ggplot(log, aes(Date,Duration))+
  geom_col(aes(fill=Activity))+
  ylab("Duration (min)")

通过dput(log)查看的数据结构显示,Date列是字符型向量:

structure(list(Date = c("2/6", "2/9", "2/11", "2/13", "2/15", 
"2/16", "2/17", "2/18", "2/19", "2/19", "2/21", "2/24", "2/25", 
"2/26", "2/27", "2/28", "3/1", "3/2", "3/3", "3/3"), Activity = c("BJJ (Gi)", 
"BJJ (Nogi)", "Lifting", "BJJ (Gi)", "BJJ (Gi)", "Lifting", "Lifting", 
"BJJ (Gi)", "Tennis", "Lifting", "BJJ (Gi)", "BJJ (Gi)", "BJJ (Gi)", 
"Lifting", "BJJ (Gi)", "BJJ (Gi)", "BJJ (Gi)", "BJJ (Nogi)", 
"BJJ (Gi)", "Lifting"), Duration = c(90, 90, 40, 60, 60, 40, 
40, 120, 30, 30, 75, 90, 90, 45, 140, 70, 120, 60, 60, 30)), row.names = c(NA, 
-20L), class = c("tbl_df", "tbl", "data.frame"))

核心问题:日期是字符型而非日期类型

Date列是字符向量,ggplot会按字符字典序排序(比如"2/11"比"2/6"靠前,因为字符"1"<"6"),必须转换成日期类型才能按时间顺序排列。

步骤1:转换日期格式

方法1:使用lubridate包(推荐)

先安装并加载包,将字符型日期转换为日期格式,可手动指定年份:

install.packages("lubridate")
library(lubridate)
library(dplyr)

log <- read_csv("Training Log.csv") %>%
  mutate(Date = mdy(paste0(Date, "/2024"))) # 拼接年份,比如2024

方法2:使用base R

log <- read_csv("Training Log.csv")
# 转换为日期类型,默认使用当前年份
log$Date <- as.Date(log$Date, format = "%m/%d")
# 若需指定年份,可拼接:
log$Date <- as.Date(paste(log$Date, "2024"), format = "%m/%d %Y")

步骤2:重新绘制图表

转换日期后,ggplot会自动按时间顺序排列X轴,还可自定义日期显示格式:

ggplot(log, aes(Date, Duration)) +
  geom_col(aes(fill = Activity)) +
  ylab("Duration (min)") +
  scale_x_date(date_labels = "%m/%d") # 显示为月/日格式

可选:显示未训练的日期(补0)

如果需要展示所有日期(包括无训练的日子),可以生成完整日期序列后左连接原数据:

# 生成从最早到最晚的连续日期序列
full_dates <- tibble(Date = seq(min(log$Date), max(log$Date), by = "day"))

# 左连接补全数据,无训练的时长设为0,活动标记为"No Training"
log_full <- full_dates %>%
  left_join(log, by = "Date") %>%
  mutate(
    Duration = ifelse(is.na(Duration), 0, Duration),
    Activity = ifelse(is.na(Activity), "No Training", Activity)
  )

# 绘制补全后的图表
ggplot(log_full, aes(Date, Duration)) +
  geom_col(aes(fill = Activity)) +
  ylab("Duration (min)") +
  scale_x_date(date_labels = "%m/%d")

内容的提问来源于stack exchange,提问作者Rsika

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 01:52:49