【问题标题】:Plot time on x axis in R for Sleep Data在 R 中的 x 轴上绘制睡眠数据的时间
【发布时间】:2021-12-29 10:24:22
【问题描述】:

我正在尝试使用 ggplot 绘制夜间睡眠开始时间以及平均睡眠开始时间。我基本上有一堆列,其中感兴趣的列包含 POSIXct 日期时间对象。睡眠开始时间跨度几个月,所以他们都有不同的日期。我已经尝试过以下代码:

# change all the datetimes to a single date + time
sleep$StartHMS <- format(sleep$StartDateTime, "%H:%M:%S")
sleep$StartHMS <- as.POSIXct(strptime(sleep$StartHMS, "%H:%M:%S"))
sleep %>% ggplot(aes(x=StartHMS)) + geom_histogram(position = "identity") + scale_x_datetime(labels = date_format("%I %p)) 

问题在于,直方图中每边都有两个峰值,因为它默认从下午 4 点开始到下午 4 点左右结束。我想根据可用时间的最小和最大限制以及从晚上 8 点左右开始到早上 8 点之前结束的数据来开始直方图。

如果有更好的方法来处理这些数据并绘制这个“时间序列”,请告诉我,因为直方图在表示下午 4 点左右有很多人睡觉时看起来有点不对劲,但事实并非如此,因为运行以下 sn-p 表示大多数人的睡眠时间发生在晚上 11 点(或 23 小时)和凌晨 12 点(0 小时)之间。

library(lubdridate)
sleep$SleepHour <- hour(sleep$StartDateTime)
sleep %>% ggplot(aes(x = SleepHour)) + geom_bar(position = "identity")

我想最终将人们睡眠的平均时间也绘制成 geom_vline,并且 x 轴需要采用 12 小时时间格式 (AM/PM)。

提前致谢!

编辑:在此处包含一些用于 StartDateTime 的示例虚拟数据:

1  2021-03-20 23:47:30
2  2021-06-15 23:17:00
3  2021-06-21 22:35:00
4  2021-05-03 22:49:00
5  2021-06-23 00:51:00
6  2021-05-05 05:56:00
7  2021-05-22 22:34:00
8  2021-07-07 23:50:30
9  2021-04-14 22:29:30
10 2021-07-08 00:48:21

【问题讨论】:

标签: r ggplot2 lubridate


【解决方案1】:

我认为最终可视化在一定程度上取决于您要选择的统计数据。如果您认为可能存在自相关,我认为您可能真的想研究时间序列分析,然后简单地取平均每小时并绘制它,如果不是明显错误的话,可能会非常误导。

对于您的问题,我认为使用小时信息(通过使用 lubridate)对我来说似乎是合理的。您只需将其转换为具有正确因子水平的因子,并告诉 ggplot 不要丢弃未使用的水平。

关于 12h 表示法,您只需为因子添加标签即可。可能有一些聪明的功能已经包含了,但我不知道。

library(tidyverse)
library(lubridate)
sleep <- read.table(text = "1  2021-03-20 23:47:30
2  2021-06-15 23:17:00
3  2021-06-21 22:35:00
4  2021-05-03 22:49:00
5  2021-06-23 00:51:00
6  2021-05-05 05:56:00
7  2021-05-22 22:34:00
8  2021-07-07 23:50:30
9  2021-04-14 22:29:30
10 2021-07-08 00:48:21")
names(sleep) <- c("rn", "date", "StartDateTime")

## I think it is a perfectly reasonable approach to just use the hour information, as you have done
sleep$StartHMS <- hour(hms(sleep$StartDateTime))
sleep %>% 
## change factor order, add the labels for 12h notation
  mutate(StartHMS = factor(StartHMS, levels = c(8:23, 0:7), labels = c(paste0(8:11, "am"), paste0(c(12,1:11), "pm"), paste0(c(12, 1:7), "am")))) %>%
  ggplot(aes(x=StartHMS)) + 
## because we're now dealing with a factor, we need geom_bar
  geom_bar() +
## don't drop unused factor levels
  scale_x_discrete(drop = FALSE) +
  theme(axis.text.x = element_text(angle = 45))

【讨论】:

  • 嗨@tjebo 无论如何可以轻松地以 12 小时格式表示小时而不是使用数字?这就是我不想使用 lubridate 的函数来绘制它而是想要一个直方图的原因。我还想要一种方法在同一个图上绘制中位数/平均就寝时间,x 轴仅显示从晚上 8 点到早上 8 点的就寝时间范围(或任何最大值和最小值)
  • @Janet,你可能在我更新之前写了评论?当前的标签是您想象中的吗?
  • @janet 关于限制 - 我认为从我的回答中您应该能够自己找到解决方案?关于 geom_vline - 您需要手动计算平均计数(返回数据框),然后将其添加为 geom_vline 层
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多