【问题标题】:Plotting time intervals by day in R在R中按天绘制时间间隔
【发布时间】:2015-07-18 13:38:44
【问题描述】:

我有一个nx2 数据框,其中每一行都包含某个时间间隔的开始和结束。

              start                 end
3  2015-04-21 20:57:23 2015-04-21 23:55:23
5  2015-04-22 00:16:26 2015-04-22 00:28:23
8  2015-04-22 01:20:14 2015-04-22 02:34:51
12 2015-04-22 03:31:27 2015-04-22 04:31:03
14 2015-04-22 04:35:56 2015-04-22 05:54:10
16 2015-04-22 06:01:35 2015-04-22 07:14:35

我想在 R 中绘制这些间隔,x 轴为 24 小时,y 轴为天。所以它应该看起来像这样:

执行此操作的适当方法是什么?

这是前 20 行的 dput:

nx2 <- structure(list(start = structure(c(1429642643.153, 1429654586.936, 
1429658414.048, 1429666287.926, 1429670156.358, 1429675295.181, 
1429680010.595, 1429691755.137, 1429700624.139, 1429708239.758, 
1429712967.668, 1429716686.314, 1429725292.357, 1429735963.053, 
1429741262.112, 1429751626.278, 1429755842.324, 1429774600.104, 
1429787329.274, 1429791813.291), class = c("POSIXct", "POSIXt"
), tzone = ""), end = structure(c(1429653323.153, 1429655303.968, 
1429662891.218, 1429669863.373, 1429674850.654, 1429679675.181, 
1429686495.759, 1429695163.947, 1429707547.129, 1429711839.758, 
1429715565.467, 1429722206.314, 1429734763.081, 1429740231.567, 
1429749242.112, 1429752556.557, 1429767902.324, 1429783522.586, 
1429790609.476, 1429795064.659), class = c("POSIXct", "POSIXt"
), tzone = "")), .Names = c("start", "end"), row.names = c(3L, 
5L, 8L, 12L, 14L, 16L, 18L, 24L, 28L, 30L, 33L, 35L, 38L, 42L, 
44L, 48L, 52L, 59L, 65L, 68L), class = "data.frame")

【问题讨论】:

  • 您可以将dput(nx2) 的输出添加到您的帖子中吗?
  • 从前 20 行添加了 dput 的输出
  • 我想看看这些间隔每天是如何变化的。所以我想有一套例如白色水平线(或条纹),其中每条线对应于从 0:00:00 到 23:59:59 的某个日历日,每条线的某些部分应涂成蓝色以显示表格中的间隔。

标签: r time plot


【解决方案1】:

这是使用 ggplot 和 dplyr 的一种方法。该图表显示的是莫斯科时间

library(ggplot2)
library(dplyr)

tz <- "Europe/Moscow"

df <- nx2 %>%
  mutate( hour_start = floor(as.numeric(start)/3600),
          hour_end_est = ceiling(as.numeric(end)/3600),
          hour_end = ifelse(hour_end_est >= hour_start, 
                            hour_end_est,
                            hour_start)
  ) %>%
  rowwise() %>%
  do( {
    hourstamp <- 3600 * seq( .$hour_start, .$hour_end, by=1) 
    day_hour <- sapply(hourstamp, function(x) 
                as.POSIXlt(x, tz=tz, origin="1970-01-01")$hour)
    day_id <- sapply(hourstamp, function(x)
                as.POSIXlt(x, tz=tz, origin="1970-01-01")$mday)
    data.frame(hour = day_hour, day = day_id)    
  } ) 


ggplot(df,aes(x=hour, y=day))  +
  geom_tile(col="black",fill="blue",alpha=0.3) +
  scale_x_continuous(breaks=0:24,limits=c(-1,24)) +
  scale_y_continuous(breaks=0:31,limits=c(-1,31)) +
  xlab("Hours") +
  ylab("Days")

我明白了:

如果需要微小的分辨率,那么只需对上面的代码进行简单的修改:

library(ggplot2)
library(dplyr)

tz <- "Europe/Moscow"

df <- nx2 %>%
  mutate( minute_start = floor(as.numeric(start)/60),
          minute_end_est = ceiling(as.numeric(end)/60),
          minute_end = ifelse(minute_end_est >= minute_start, 
                            minute_end_est,
                            minute_start)
  ) %>%
  rowwise() %>%
  do( {
    minutestamp <- 60 * seq( .$minute_start, .$minute_end, by=1) 
    day_minute <- sapply(minutestamp, function(x) 
      {
        psx_time <- as.POSIXlt(x, tz=tz, origin="1970-01-01")
        psx_time$hour*60 + psx_time$min
      })
    day_id <- sapply(minutestamp, function(x)
      {
        psx_time <- as.POSIXlt(x, tz=tz, origin="1970-01-01")
        psx_time$mday
      })
    data.frame(minute = day_minute, day = day_id)    
  } ) 


ggplot(df,aes(x=minute, y=day))  +
  geom_tile(fill="blue",alpha=0.3) +
  scale_x_continuous(breaks=seq(0,24*60,by=60),
                     limits=c(-60,24*60)) +
  scale_y_continuous(breaks=0:31,limits=c(-1,31)) +
  xlab("Minutes") +
  ylab("Days")

我明白了:

【讨论】:

  • seq.default(.$hour_start, .$hour_end, by = 1) 中的错误:'by' 参数中的错误登录
  • 糟糕.. 忘记添加库:library(ggplot2)library(dplyr)
  • 对了,start总是比end小吗?
  • 我猜,这个错误发生在某个时间间隔的开始在一天结束并且结束在第二天开始时。
  • 这不太可能,因为它已被考虑在内。当开始时间戳>结束时间戳时,看起来完整的数据集包含数据点。我为此添加了一张支票。如果可行,请尝试!
【解决方案2】:

试试这个:

library(lubridate)
library(ggplot2)

#data prep for plotting
nx2$DD <- day(nx2$start)
nx2$startHH <- hour(nx2$start)
nx2$endHH <- hour(nx2$end)

#plot    
ggplot(nx2,aes(xmin = startHH, xmax = endHH + 1,
               ymin = DD-0.5, ymax = DD + 0.5)) +
  geom_rect(col="black",fill="blue",alpha=0.3) +
  scale_x_continuous(breaks=0:24,limits=c(0,24)) +
  scale_y_continuous(breaks=0:31,limits=c(0,31)) +
  xlab("Hours") +
  ylab("Days") +
  theme_bw()

【讨论】:

  • 这个其实很好,非常感谢!但是,如果我想要分钟精度怎么办?似乎如果我为整个小时间隔着色,我几乎所有东西都被着色了。
  • 看起来有问题。该图显示 23 日午夜之后的两个小时内没有任何活动,但数据表明这不是真的。 (行名 35、38、42、44、48)
  • 非常好。如果一个时期跨越一天以上,这种方法将如何运作?”例如,从一天晚上 10:07 开始,到第二天早上 6 点结束?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多