在R中按天绘制时间间隔

时间:2015-05-07 19:41:54

标签: r time plot

我有一个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行的输入:

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")

2 个答案:

答案 0 :(得分: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()

enter image description here

答案 1 :(得分:2)

以下是使用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")

我明白了: enter image description here

如果需要微小的分辨率,那么它只是对上述代码的简单修改:

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")

我明白了:

enter image description here