2016-03-16 4 views
7

В последние дни я размышлял над следующей проблемой: я хочу рассчитать продолжительность действия в виде строки с осью y, представляющей дату, когда происходит действие, и ось x, представляющая время в часах. Когда я занимаюсь деятельностью, которая начинается и заканчивается в тот же день, это легко.Продолжительность участка в виде линий с ggplot2

Например:

df1<-structure(list(Date = structure(c(16802, 16803, 16805, 16806, 
16809, 16810, 16812, 16813, 16816, 16820, 16821, 16822, 16829 
), class = "Date"), hms1 = structure(c(1457623680, 1457620860, 
1457621160, 1457622540, 1457625600, 1457621280, 1457620380, 1457619720, 
1457623620, 1457621460, 1457620440, 1457617980, 1457621880), class =  c("POSIXct", "POSIXt"), tzone = ""), hms2 = structure(c(1457632500, 1457627640, 
1457628360, 1457629500, 1457631000, 1457625120, 1457625420, 1457624520, 
1457627640, 1457626800, 1457626800, 1457622060, 1457625540), class = c("POSIXct", 
"POSIXt"), tzone = "")), .Names = c("Date", "hms1", "hms2"), class =  "data.frame", row.names = c(103L, 105L, 108L, 110L, 114L, 117L, 120L, 122L, 127L, 135L, 136L, 138L, 145L)) 

p1<-ggplot(df1, aes(x=Date,y= hms1))+ scale_x_date(breaks = date_breaks("1 day"))+ 
geom_linerange(aes(ymin = hms1, ymax = hms2),color = "red",size = 2)+ coord_flip() 
p1+ylab("Time")+ggtitle("Activity During Day") 

дает желаемый сюжет: ggplot1

Обратите внимание, что реальная дата, на колонке Дата в то время как даты в hms1m hms2 неправильно из-за процесса, который я использовал получить время в формате H: M: S.

df1$hms1 <- format(df1$time, format = "%H:%M:%S") 
df1$hms1 <- as.POSIXct(df1$hms1, format = "%H:%M:%S") 

Вещь в том, что большая часть «видов деятельности», я пытаюсь построить пролет в течение двух дней. Единственное решение, которое я придумал до сих пор, сдвигает значения времени и времени на соответствующий период, чтобы «искусственно» поместить их в тот же день, как предлагается здесь 2. Этот процесс, естественно, приводит к тому, что ось x отображает «искусственные» временные метки.

Как я могу взять контроль над отметками в ggplot, чтобы я мог отображать правильные отметки времени? Или еще лучше может кто-то предложить более элегантное решение? Чтобы быть ясным: я хочу, чтобы ось y была только датой начала события, но ось x охватывала более 24 часов.

+0

будет легче помочь вам, если вы предоставить образец данных, который включает в себя базовые значения, которые используются для расчета HMS1 и hms2. – eipi10

+0

Df2 действительно опечатка, теперь исправленная. Прямо сейчас, я не могу включить исходный образец данных, но он будет выполнен как можно скорее. –

+0

Я не совсем понимаю, как будет выглядеть ваш желаемый результат. Вы хотите, чтобы ось y была только датой начала события, но ось x охватывает более 24 часов? Или вы хотите, чтобы строки «обертывались» с одной даты даты y до следующей даты даты y? Что-то другое? – Gregor

ответ

5

Я не уверен, как выглядит ваша реальная структура данных, поэтому я создал несколько временных периодов для иллюстрации следующим образом: Я использовал ваши значения для Date, а затем использовал runif, чтобы выбрать случайные начальные и конечные времена для каждого вида деятельности. Некоторые периоды времени происходят в течение одной даты, а некоторые промежутки - две даты.

Затем я построил данные следующим образом: горизонтальные горизонтальные линии, которые расположены вертикально на дату начала действия. Строка начинается в то время (в часах), когда началось действие (относительно полуночи на дату начала действия), а затем продолжается вправо, однако на протяжении многих часов активность продолжалась.

Горизонтальная шкала простирается до 48 часов, поэтому можно визуализировать действия, охватывающие более одной даты. Вертикальные линии обозначают границы даты, поэтому вы можете видеть, какие действия продолжались на второй день. Если у вас есть занятия продолжительностью три или более дней, просто увеличьте горизонтальную шкалу, если это необходимо для их размещения.

# Convert Date to POSIXct and set HMS to beginning of day (i.e., Midnight). 
# To do this, I added 8-hours to account for my locale being the U.S. Pacific time zone. 
df1$Date = as.POSIXct(df1$Date) + 3600*8 

## Create some times for start and end of each activity 
set.seed(20) 
df1$hms1a = df1$Date + runif(nrow(df1), 3600*5, 3600*10) 
df1$hms2a = df1$Date + runif(nrow(df1), 3600*15, 3600*40) 

library(ggplot2) 
library(scales) 
library(stringr) 

ggplot(df1, aes(x=Date)) + 
    scale_x_datetime(breaks = date_breaks("1 day")) + 
    scale_y_continuous(limits = c(0,48), breaks=seq(0,48,2), 
        labels=str_pad(seq(0,48,2) %% 24, 2, pad="0")) + 
    geom_hline(yintercept=seq(0,48,24)) + 
    geom_linerange(aes(ymin = hms1a - Date, ymax = hms2a - Date), color = "red",size = 2) + 
    coord_flip() + ylab("Time (hours)") + 
    ggtitle("Activity During Day") 

enter image description here

+0

очень умное и простое решение. Это также мой первый раз видя диаграмму Ганта в R. – PavoDive